c++ - 动态创建的复选框的事件处理程序

标签 c++ c++builder c++builder-5 tcheckbox

我使用 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 属性,非成员没有)。

确保 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()address 分配给 OnClick,这仅适用于非静态类方法,不适用于独立函数(好吧,它可以完成,但它需要不同的代码,涉及使用 TMethod 结构的类型转换 hack)。

此外,您不应该使用 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...
}

关于c++ - 动态创建的复选框的事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51976382/

相关文章:

c++ - 禁用没有宏的 C++ 代码

c++ - 对这 n^2 个数字进行排序的最快方法是什么?

c++builder - 如何在运行时在 C++ Builder XE7 中添加组件

delphi - TMainMenu 中的单选项目不使用点,而是使用复选标记

c++ - Borland 字符串::查找错误

c++ - C++:我在一种方法中得到一个迭代器,如何在另一种方法中通过迭代器修改原始列表?

c++ - 诺基亚N95可以编译运行C/C++程序吗?

C++ UnixTimestamp 和可读时间格式

c++ - 无法访问打印机 Borland C++ 5