I am writing my custom visual component and find it convenient to publish some of its properties as array:
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);
...
};
Component is built and installed without problems. But after I try to insert component on form, access violation message box shows. When debugging source of error I found, that method GetArrowStyle is called with index value of -1 which causes reading out of array bounds. I understand that user of TVctDiag2 class (=integrated development environment) cannot know what is the array size. The size of array is constant and its quite a small number (6), so alternative solution would be:
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);
...
};
But I prefer more general solution. How can this be accomplished, if possible with option to change property values through Object inspector.
Declare array properties as public
instead. __published
is used for design-time editing and RTTI generation, which do not support array properties:
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);
...
};
Your second example is buggy. You need to remove the index
parameters from the getter/setter methods since the properties does not use indexes (by using non-array properties, you can declare them as __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();
...
};
If you want to use separate properties for the individual array values, I would suggest going back to using indexes with a single set of getter/setter methods by using the index
specifier on the property declarations (I would even go as far as declaring a public
array property again for good measure, in case you ever need to loop through the values in code):
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);
...
};
If you want design-time editing of an array, you either need to write a custom component editor and register it with the IDE, or re-write the array property into a TCollection
(which is fully supported in RTTI and design-time editing).