I have an owner drawn combo box that displays the strings in columns. The drawing routine can be shared across combos if I can somehow pass the column specifications to the OnDrawItem event. A natural way to do so, would be to pass the array of column widths in the ComboBox.Tag property and then cast it back to an array.
When I define the column array as:
const arrWidth :array[1..4] of integer = (100,100,100,70);
and set the Tag property to:
ComboBox.Tag := integer(@arrWidth);
and then in the OnDrawItem event, cast it back to an array:
Widths :array of integer;
Widths := pointer(ComboBox.Tag);
I can see the array elements fine, but the array does not know it's length. It appears to be much longer with all sorts of random values.
I have tried using a dynamic array, but then I don't even get the proper column values.
Casts are dangerous because you go outside the type checking system. That has caught you out here. The issue is that array[1..4] of integer
and array of integer
are not the same type.
You need to declare your array as a distinct type like this
TWidthArray = array [1..4] of Integer;
PWidthArray = ^TWidthArray;
Then do your constant like this:
const
arrWidth: TWidthArray = (100,100,100,70);
When you need to extract the array from the combo box do it like this:
Widths: TWidthArray;
...
Widths := PWidthArray(ComboBox.Tag)^;
If you need to support using dynamic array lengths then you would need to change your common type to reflect that. However, beware that casting to an Integer
to put in Tag
will bypass the reference counting of the dynamic array. So you need to really understand what you are doing if you go down that route.
One final point. If ever you wish to compile this code for 64 bit it will fail because of this line:
ComboBox.Tag := integer(@arrWidth);
since integer
is a 32 bit data type. Instead you should use NativeInt
which is is an integer the same width as a pointer.
ComboBox.Tag := NativeInt(@arrWidth);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With