Tuesday, February 27, 2007

TListBox bug

Another one of those bugs that make our life difficult. I have been trying to make a list box with variable item height. I wanted the height of each item to vary, depending on the item, so I thought I would associate a dummy object with each string of the list box, using code like this:

MyListBox.AddItem(aStr, Pointer(theHeight));

Then I would use an OnMeasureItem event to set the height:

procedure MyForm.MyListBoxMeasureItem(Control: TWinControl; Index: Integer; var Height: Integer);
begin
Height := integer(MyListBox.Items.Objects[Index]);
end;

However, this does not work. The reason is rather interesting. When the AddItem procedure is called, the string is first added to the list box, then Delphi triggers the OnMeasureItem event, BEFORE the object has been added, so the event finds no object in the Items.Objects collection.
My workaround was to add the height as the first character of the string:

MyListBox.Items.Add(Char(theHeight) + aStr);

Then, in the OnMeasureItem procedure, I strip the character and convert it to an integer value:

Height := byte(MyListBox.Items[Index][1]);

Note that this will only work if the variable stored in the first character of the string is not zero, otherwise it will be mistaken as a string termination character and a null string will be added to the list box.