2011-12-14 68 views
10

我有一个所有者绘制组合框,显示列中的字符串。如果我能以某种方式将列规格传递给OnDrawItem事件,则可以在组合中共享绘图例程。一种自然的方法是,将ComboBox.Tag属性中的列宽度数组传递给数组,然后将其转换回数组。如何将数组转换为指针并返回到Delphi?

当我定义列阵列为:

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); 

我可以看到数组元素罚款,但数组不知道它的长度。随着各种随机值的出现似乎要长得多。

我一直在使用动态数组试过,但后来我甚至不得到适当的列值。

+4

替代不涉及存储在标签阵列的指针包括写入存储在专用于任务属性的值的后代,并存储在一个关联阵列(像TDictionary)列宽映射combo-框实例转换为宽度数组。 – 2011-12-14 17:41:20

回答

19

转换非常危险的,因为你去的类型检查系统之外。这已经引起你的注意。问题是array[1..4] of integerarray of integer不是相同的类型。

您需要声明您的数组作为一个独特的类型像这样

TWidthArray = array [1..4] of Integer; 
PWidthArray = ^TWidthArray; 

然后做你常数是这样的:

const 
    arrWidth: TWidthArray = (100,100,100,70); 

当你需要数组从组合框中提取做像这样:

Widths: TWidthArray; 
... 
Widths := PWidthArray(ComboBox.Tag)^; 

如果你需要支持使用动态数组长度,那么你woul d需要改变你的常见类型以反映这一点。然而,提防转换成一Integer把在Tag将绕过动态数组的引用计数。所以你需要真正理解你在做什么,如果你沿着这条路线走。

最后一点。要是你想编译此代码为64位,将失败,因为这行:

ComboBox.Tag := integer(@arrWidth); 

因为integer是一个32位的数据类型。相反,你应该使用NativeInt这是一个与指针相同宽度的整数。

ComboBox.Tag := NativeInt(@arrWidth); 
相关问题