我有一个所有者绘制的组合框,用于在列中显示字符串。如果我可以以某种方式将列规范传递给OnDrawItem事件,则可以跨组合共享绘图例程。这样做的一种自然方法是传递ComboBox.Tag属性中的列宽数组,然后将其强制转换为数组。
当我将列数组定义为:
时const arrWidth :array[1..4] of integer = (100,100,100,70);
并将Tag属性设置为:
ComboBox.Tag := integer(@arrWidth);
然后在OnDrawItem事件中,将其强制转换为数组:
Widths :array of integer;
Widths := pointer(ComboBox.Tag);
我可以看到数组元素很好,但数组不知道它的长度。各种随机值似乎要长得多。
我尝试过使用动态数组,但后来我甚至没有得到正确的列值。
答案 0 :(得分:19)
施放是危险的,因为你走出了类型检查系统。那抓住了你。问题是array[1..4] of integer
和array of integer
的类型不同。
您需要将数组声明为类似
的不同类型TWidthArray = array [1..4] of Integer;
PWidthArray = ^TWidthArray;
然后像这样做你的常数:
const
arrWidth: TWidthArray = (100,100,100,70);
当您需要从组合框中提取数组时,请执行以下操作:
Widths: TWidthArray;
...
Widths := PWidthArray(ComboBox.Tag)^;
如果您需要支持使用动态数组长度,那么您需要更改常用类型以反映这一点。但是,请注意,转换为Integer
以放入Tag
将绕过动态数组的引用计数。因此,如果沿着这条路走下去,你需要真正了解自己在做什么。
最后一点。如果您希望将此代码编译为64位,则由于以下行而失败:
ComboBox.Tag := integer(@arrWidth);
因为integer
是32位数据类型。相反,你应该使用NativeInt
,它是一个与指针宽度相同的整数。
ComboBox.Tag := NativeInt(@arrWidth);