When a ListBox control is created, its ItemHeight is zero.
Based on ListBox.Style:
lbStandard: ItemHeight value is calculated and is *not* related to
FItemHeight making it a read only property:
//\lcl\include\customlistbox.inc
function TCustomListBox.GetItemHeight: Integer;
begin
if HandleAllocated and (Style = lbStandard) then
begin
with ItemRect(TopIndex) do
Result := Bottom - Top;
lbOwnerDrawFixed: The system requests the height by sending WM_MeasureItem message once. If FItemHeight is zero, the value passed by the system is used. The problem this value is not identical to the value used in lbStandard as the system does not know about the font and its height, yet:
The system sends the WM_MEASUREITEM message to the owner window of combo boxes and list boxes created with the OWNERDRAWFIXED style before sending the WM_INITDIALOG message. As a result, when the owner receives this message, the system has not yet determined the height and width of the font used in the control; function calls and calculations requiring these values should occur in the main function of the application or library.
This is the code involved:
procedure TCustomListBox.LMMeasureItem(var TheMessage: TLMMeasureItem);
var
AHeight: Integer;
begin
with TheMessage.MeasureItemStruct^ do
begin
if Self.ItemHeight <> 0 then
AHeight := Self.ItemHeight
else
AHeight := ItemHeight; //<--- ItemHeight of MeasureItemStruct^ where the wrong value is
MeasureItem(Integer(ItemId), AHeight);
if AHeight > 0 then
ItemHeight := AHeight; //<--- ItemHeight of MeasureItemStruct^
end;
end;
ItemHeight passed in MeasureItemStruct^ has the value 20 on my system.