Обработчик событий для динамически создаваемого CheckBox
Я написал программу на C++ с использованием Borland C++ Builder 5. Программа динамически создает массив 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
2 ответа
CBoxClick()
не является членом вашего класса Form.
В вашем файле cpp компилятор видит его как отдельную функцию. Вот на что жалуется сообщение об ошибке при назначении OnClick
событие не выполняется (нестатические методы класса имеют __closure
атрибут, нечленов нет).
Удостовериться CBoxClick()
объявлен внутри вашего класса Form в заголовочном файле:
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()
в целом и вместо этого выполните инициализацию массива внутри собственного конструктора формы:
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...
}
Реми - У меня все еще проблемы с использованием редактора. Вот рабочий код, основанный на вашем первом ответе с одним небольшим изменением. Спасибо за помощь.
`//.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";
}
}