C++ Builder的XE - 出版数组属性
问题描述:
我写我的自定义可视化组件,并发现它方便公布它的一些属性为数组:C++ Builder的XE - 出版数组属性
class PACKAGE TVctDiag2 : public TCustomControl
{
__published:
__property int ArrowStyle[int index] = {read=GetArrowStyle,write=SetArrowStyle};
protected:
void __fastcall SetArrowStyle(int index, int value);
int __fastcall GetArrowStyle(int index);
...
};
组件的建造和安装没有问题。但是当我尝试在窗体上插入组件后,访问冲突消息框显示。在调试我发现的错误源时,该方法GetArrowStyle被调用索引值-1导致读出数组边界。我知道的用户TVctDiag2 class(=集成开发环境)无法知道数组的大小。阵列的大小是恒定的并且它的相当少量的(6),因此可替代的解决方案是:
class PACKAGE TVctDiag2 : public TCustomControl
{
__published:
__property int ArrowStyle1 = {read=GetArrowStyle1,write=SetArrowStyle1};
__property int ArrowStyle2 = {read=GetArrowStyle2,write=SetArrowStyle2};
__property int ArrowStyle3 = {read=GetArrowStyle3,write=SetArrowStyle3};
__property int ArrowStyle4 = {read=GetArrowStyle4,write=SetArrowStyle4};
__property int ArrowStyle5 = {read=GetArrowStyle5,write=SetArrowStyle5};
__property int ArrowStyle6 = {read=GetArrowStyle6,write=SetArrowStyle6};
protected:
void __fastcall SetArrowStyle1(int index, int value);
int __fastcall GetArrowStyle1(int index);
void __fastcall SetArrowStyle2(int index, int value);
int __fastcall GetArrowStyle2(int index);
void __fastcall SetArrowStyle3(int index, int value);
int __fastcall GetArrowStyle3(int index);
void __fastcall SetArrowStyle4(int index, int value);
int __fastcall GetArrowStyle4(int index);
void __fastcall SetArrowStyle5(int index, int value);
int __fastcall GetArrowStyle5(int index);
void __fastcall SetArrowStyle6(int index, int value);
int __fastcall GetArrowStyle6(int index);
...
};
但我更喜欢更通用的解决方案。如果可能,可以通过对象检查器更改属性值,如何完成此操作。
答
改为声明数组属性为public
。 __published
用于设计时编辑和RTTI代,不支持阵列属性:
class PACKAGE TVctDiag2 : public TCustomControl
{
public:
__property int ArrowStyle[int index] = {read=GetArrowStyle,write=SetArrowStyle};
protected:
void __fastcall SetArrowStyle(int index, int value);
int __fastcall GetArrowStyle(int index);
...
};
你的第二个例子是越野车。你需要从getter/setter方法去除index
参数,因为属性不使用索引(通过使用非数组属性,你可以声明为__published
):
class PACKAGE TVctDiag2 : public TCustomControl
{
__published:
__property int ArrowStyle1 = {read=GetArrowStyle1,write=SetArrowStyle1};
__property int ArrowStyle2 = {read=GetArrowStyle2,write=SetArrowStyle2};
__property int ArrowStyle3 = {read=GetArrowStyle3,write=SetArrowStyle3};
__property int ArrowStyle4 = {read=GetArrowStyle4,write=SetArrowStyle4};
__property int ArrowStyle5 = {read=GetArrowStyle5,write=SetArrowStyle5};
__property int ArrowStyle6 = {read=GetArrowStyle6,write=SetArrowStyle6};
protected:
void __fastcall SetArrowStyle1(int value);
int __fastcall GetArrowStyle1();
void __fastcall SetArrowStyle2(int value);
int __fastcall GetArrowStyle2();
void __fastcall SetArrowStyle3(int value);
int __fastcall GetArrowStyle3();
void __fastcall SetArrowStyle4(int value);
int __fastcall GetArrowStyle4();
void __fastcall SetArrowStyle5(int value);
int __fastcall GetArrowStyle5();
void __fastcall SetArrowStyle6(int value);
int __fastcall GetArrowStyle6();
...
};
如果要使用单独的属性对于单个数组值,我建议回到使用索引与一组getter/setter方法通过在属性声明中使用index
说明符(我甚至会尽可能声明public
数组属性以获得更好的度量,如果您需要遍历代码中的值):
class PACKAGE TVctDiag2 : public TCustomControl
{
__published:
__property int ArrowStyle1 = {read=GetArrowStyle,write=SetArrowStyle,index=0};
__property int ArrowStyle2 = {read=GetArrowStyle,write=SetArrowStyle,index=1};
__property int ArrowStyle3 = {read=GetArrowStyle,write=SetArrowStyle,index=2};
__property int ArrowStyle4 = {read=GetArrowStyle,write=SetArrowStyle,index=3};
__property int ArrowStyle5 = {read=GetArrowStyle,write=SetArrowStyle,index=4};
__property int ArrowStyle6 = {read=GetArrowStyle,write=SetArrowStyle,index=5};
public:
__property int ArrowStyle[int index] = {read=GetArrowStyle,write=SetArrowStyle};
protected:
void __fastcall SetArrowStyle(int index, int value);
int __fastcall GetArrowStyle(int index);
...
};
如果您想要对数组进行设计时编辑,您需要编写自定义组件编辑器并将其注册到IDE中,或者将数组属性重新写入TCollection
(RTTI和design-时间编辑)。