c++ - 动态创建的复选框的事件处理程序
问题描述
我使用 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
解决方案
CBoxClick()
不是您的 Form 类的成员。
在您的 cpp 文件中,编译器将其视为独立函数。这就是OnClick
事件分配失败时错误消息所抱怨的内容(非静态类方法具有__closure
属性,非成员没有)。
确保在头文件的 Form 类中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
,这显然是行不通的。您需要分配 to 的地址,这仅适用于非静态类方法,不适用于独立函数(好吧,它可以完成,但它需要涉及使用结构的类型转换黑客的不同代码)。CBoxClick()
OnClick
TMethod
此外,您不应该使用dynamic_cast
. 由于您知道Sender
将始终是 a TCheckBox
,请static_cast
改用:
void __fastcall TForm1::CBoxClick(TObject *Sender){
TCheckBox *cb = static_cast<TCheckBox*>(Sender);
//Do stuff with cb...
}
更新:现在,话虽如此,更好的选择是完全摆脱ChkBoxInit()
并在表单自己的构造函数中进行数组初始化:
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...
}
推荐阅读
- mysql - 错误的服务器时区 MySql。为什么 MySql-shell 中的命令不正确?
- python - 字段布尔值不随时间更新
- xml - 为什么 COBOL 生成的 XML 中缺少编码属性?
- django-rest-framework - 提供的 appsecret_proof 无效(django Rest 框架)
- java - PageFactory.initElements 给出错误 java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
- java - 日志文件不工作 - 无法找到或加载主类
- python - TypeError: 只有 size-1 的数组可以用函数和数组转换为 Python 标量
- controller - 如何通过 RS485 与 Watlow 控制器通信?
- google-sheets - 谷歌表格 - 批量写入条件格式?
- python - 在 install_requires 中使用 git repo 编写 setup.py 以检测是否已安装