views:

178

answers:

2

I have a TListBox on a form, and items are added with

listbox1.ItemIndex := listbox1.Items.AddObject('msg', TObject(grp));

grp is an integer,

The listbox is set to lbOwnerDrawFixed

In the onDrawItem event i get the Exception EStringListError raise on the marked line

msg := (control as Tlistbox).Items.Strings[index]; <-- this line works
grp := integer((control as Tlistbox).Items.Objects[index]); <--- Exception here

msg and grp are local string and integer variables

Project ### raised exception class EStringListError with message 'List index out of bounds (1)'

A: 

You just want to store an integer, so you should change your code to

listbox1.ItemIndex := listbox1.Items.Add(IntToStr(grp));
[...]
grp := StrToInt((control as TListBox).Items[index]);

No need for storing objects here and this makes the whole thing much easier and more readable.

The exception you get now is because you can't retrieve objects using the index, but have to use the string you associated them with (the first parameter of AddObject). The correct way would be something like this:

msg := (control as Tlistbox).Items.Strings[index];
grp := integer((control as Tlistbox).Items.Objects[(control as Tlistbox).Items.IndexOf(msg)]);

Also see this tutorial about AddObject.

schnaader
thanks you the answer, the msg string is needed too,
Christopher Chase
+1  A: 

Silly Mistake,
i was using grp := -1 as the default group,
which AddObject or Objects[index] must not like

Christopher Chase
+1 Interesting.. You've got yourself an OS bug I think. LB_GETITEMDATA returns -1 (LB_ERR) when there's an error. So there's no way to tell if the api successfully returns -1 or an error. It should not let to set item data to -1 in the first place. Well, the VCL does not check the return of LB_SETITEMDATA anyway, but that's not the problem in this case.
Sertac Akyuz
It's not an OS bug. It's clearly documented that it returns `LB_ERR` on error, so if you want to be able to distinguish between errors and valid values, you need to make sure you don't store `LB_ERR` in the first place. Besides, Delphi expects to be storing `TObject` values, and -1 is never a valid value of that type. In a way, this is an application bug for type-casting where it's not appropriate.
Rob Kennedy
@Rob - What Delphi does with item data is quite irrelevant, the OS sets an Integer. I understand the view that it's not a bug, but if I were to design it I would return a LB_ERR if somebody tries to store LB_ERR to item data.
Sertac Akyuz