Я написал программу на 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
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";
}
}