我使用Borland C ++ Builder 5编写了一个C ++程序。该程序动态创建TCheckBox
对象的数组。我试图编写一个OnClick
事件处理程序,该事件处理程序将确定单击了哪个复选框,并根据该事件执行一些指令。我的事件处理程序基于与该网站类似的帖子,但是我似乎无法使其正常工作。
这是(缩写)代码
// Header declaration
void __fastcall CBoxClick(TObject *Sender);
// End Header
// CBoxClick function (the event handler)
void __fastcall CBoxClick(TObject *Sender){
if (dynamic_cast<TCheckBox*>(Sender)!=NULL){
//Do stuff
}
else{
Form1 -> Debug -> Text = "Object is not a TCheckBox";
}
}
void ChkBoxInit(void){
int i; //Loop counter index
TCheckBox* ChkBx[NCARDS]; //Define array of type checkboxes
for(i = 0; i < NCARDS; i++){ //Initalize each checkbox
ChkBx[i] = new TCheckBox(Form1); //Create a new checkbox
ChkBx[i] -> Parent = Form1; //Define parent of checkbox
ChkBx[i] -> Tag = i; //Set value of Tag to index
// Other CheckBox parameters here such as Height, Width, Top, Left, Name are here
// Next, call event handler. I've tried the following 2 statements with the comment results
ChkBx[i] -> OnClick = CBoxClick(ChkBx[i]); // Results in E2109: Not an allowed type
ChkBx[i] -> OnClick = CBoxClick; /* Alternate try - Results in E2034: Cannot convert
'void (_fastcall *)(TObject *)' to
'void (_fastcall * (_closure )(TObject *))(TObject *)' */
} //End of for loop
} //End of function
答案 0 :(得分:0)
CBoxClick()
不是您的Form类的成员。在您的cpp文件中,编译器将其视为独立功能。这就是错误消息在OnClick
事件分配失败时所抱怨的(非静态类方法具有__closure
属性,非成员类则没有)。
确保在头文件中的CBoxClick()
被声明为在内部:
class TForm1 : public TForm
{
...
public:
...
void __fastcall CBoxClick(TObject *Sender); // <-- add this
...
};
然后在cpp文件中更改此行:
void __fastcall CBoxClick(TObject *Sender){
为此:
void __fastcall TForm1::CBoxClick(TObject *Sender){
然后从以下更改您对OnClick
事件的分配:
ChkBx[i]->OnClick = CBoxClick;
为此(因为ChkBoxInit()
本身也不是Form类的成员)
ChkBx[i]->OnClick = Form1->CBoxClick;
您尝试的第一个语法(OnClick = CBoxClick(ChkBx[i]);
)完全是错误的,因为您实际上是在调用 CBoxClick()
,然后尝试分配其void
返回值到OnClick
,显然是行不通的。您需要将CBoxClick()
的地址分配给OnClick
,这仅适用于非静态类方法,不适用于独立函数(嗯,可以做到,但它需要使用TMethod
结构进行类型转换黑客攻击的不同代码。
此外,您不应该使用dynamic_cast
。由于您知道Sender
将始终是TCheckBox
,因此请使用static_cast
:
void __fastcall TForm1::CBoxClick(TObject *Sender){
TCheckBox *cb = static_cast<TCheckBox*>(Sender);
//Do stuff with cb...
}
更新:话虽如此,更好的选择是完全放弃ChkBoxInit()
并在Form自己的构造函数中进行数组初始化:
class TForm1 : public TForm
{
...
private:
...
void __fastcall CBoxClick(TObject *Sender); // <-- moved here
...
public:
__fastcall TForm1(TComponent *Owner); // <-- constructor
...
};
__fastcall TForm1::TForm1(TComponent *Owner)
: TForm(Owner)
{
TCheckBox* ChkBx[NCARDS]; //Define array of type checkboxes
for(int i = 0; i < NCARDS; i++){ //Initalize each checkbox
ChkBx[i] = new TCheckBox(this); //Create a new checkbox
ChkBx[i] -> Parent = this; //Define parent of checkbox
ChkBx[i] -> Tag = i; //Set value of Tag to index
// Other CheckBox parameters here such as Height, Width, Top, Left, Name are here
// Next, setup event handler
ChkBx[i]->OnClick = CBoxClick;
} //End of for loop
}
void __fastcall TForm1::CBoxClick(TObject *Sender)
{
TCheckBox *cb = static_cast<TCheckBox*>(Sender);
// Do stuff with cb...
}
答案 1 :(得分:0)
Remy-我在使用编辑器时仍然遇到麻烦。这是工作代码,该代码基于您的第一反应,但有一点点变化。谢谢您的帮助。
`// .h文件----------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Deal;
TButton *Reset;
TButton *Help;
TButton *Quit;
TEdit *Debug;
void __fastcall QuitClick(TObject *Sender);
void __fastcall ResetClick(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
void __fastcall CBoxClick(TObject *Sender); //CheckBox Event Handler prototype
};
// .cpp文件----------------
void ChkBoxInit(void){
int i; //Loop counter index
TCheckBox* ChkBx[NCARDS]; //Define array of type checkbox
for(i = 0; i < NCARDS; i++){ //Initalize each checkbox
ChkBx[i] = new TCheckBox(Form1); //Create a new checkbox
ChkBx[i] -> Parent = Form1; //Define parent of checkbox
// ..... Various parameters of ChkBx[i] go here (height, Width, Top, Left, etc.)
ChkBx[i] -> Tag = i; //Use index value as tag
` ChkBx[i] -> OnClick = Form1 -> CBoxClick; //Assign OnClick event to CBoxClick
} //End of for loop
} //End of function
// Event Handler ------------------
void __fastcall TForm1::CBoxClick(TObject *Sender){
if (static_cast<TCheckBox*>(Sender)!=NULL){
Form1 -> Debug -> Text = (static_cast<TCheckBox*>(Sender) -> Name);
}
else{
Form1 -> Debug -> Text = "Object is not a TCheckBox";
}
}