删除动态创建的控件 borland 6 c++ builder
Deleting dynamically created control borland 6 c++ builder
我在 Borland C++Builder 6 中删除动态创建的按钮时遇到问题。
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner) {
TButton *but = new TButton(this);
but->Left = 100;
but->Top = 100;
but->OnClick = click;
Form1->InsertControl(but);
}
void __fastcall TForm1::click(TObject *Sender) {
delete Sender;
}
当我点击创建的按钮时,出现错误 "Access violation at address 40005905 in module 'rtl60.bpl', read of address 00000018"
我知道为按钮分配一个删除它的方法是错误的,但我确实需要通过按下按钮来删除它
您的代码中有两个错误。
调用TForm1
构造函数时,全局Form1
变量还没有赋值,所以你的Form1->InsertControl(but)
语句是无效的,很可能会崩溃。使用 this->
而不是 Form1->
。但是,您不应该直接调用 InsertControl()
,而是设置按钮的 Parent
属性:
but->Parent = this;
当事件处理程序为 运行 时 delete
事件的 Sender
是不安全的。在处理程序退出后,RTL 仍然需要访问对象(正如您的 AccessViolation 错误所证明的那样)。您将不得不延迟 delete
,例如使用较短的计时器:
void __fastcall TForm1::DeleteButtonTimerElapsed(TObject *Sender)
{
TObject *obj = reinterpret_cast<TObject*>(DeleteButtonTimer->Tag);
DeleteButtonTimer->Tag = 0;
DeleteButtonTimer->Enabled = false;
delete obj;
}
void __fastcall TForm1::click(TObject *Sender)
{
DeleteButtonTimer->Tag = reinterpret_cast<int>(Sender);
DeleteButtonTimer->Enabled = true;
}
或 post 使用 PostMessage()
给自己的自定义消息(我更喜欢这种方法):
#define WM_DELETE_OBJECT (WM_USER + 1)
void __fastcall TForm1::WndProc(TMessage &Message)
{
if (Message.Msg == WM_DELETE_OBJECT)
delete reinterpret_cast<TObject*>(Message.LParam);
else
TForm::WndProc(Message);
}
void __fastcall TForm1::click(TObject *Sender)
{
TButton *btn = static_cast<TButton*>(Sender);
btn->OnClick = NULL;
PostMessage(Handle, WM_DELETE_OBJECT, 0, reinterpret_cast<LPARAM>(Sender));
}
我在 Borland C++Builder 6 中删除动态创建的按钮时遇到问题。
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner) {
TButton *but = new TButton(this);
but->Left = 100;
but->Top = 100;
but->OnClick = click;
Form1->InsertControl(but);
}
void __fastcall TForm1::click(TObject *Sender) {
delete Sender;
}
当我点击创建的按钮时,出现错误 "Access violation at address 40005905 in module 'rtl60.bpl', read of address 00000018"
我知道为按钮分配一个删除它的方法是错误的,但我确实需要通过按下按钮来删除它
您的代码中有两个错误。
调用
TForm1
构造函数时,全局Form1
变量还没有赋值,所以你的Form1->InsertControl(but)
语句是无效的,很可能会崩溃。使用this->
而不是Form1->
。但是,您不应该直接调用InsertControl()
,而是设置按钮的Parent
属性:but->Parent = this;
当事件处理程序为 运行 时
delete
事件的Sender
是不安全的。在处理程序退出后,RTL 仍然需要访问对象(正如您的 AccessViolation 错误所证明的那样)。您将不得不延迟delete
,例如使用较短的计时器:void __fastcall TForm1::DeleteButtonTimerElapsed(TObject *Sender) { TObject *obj = reinterpret_cast<TObject*>(DeleteButtonTimer->Tag); DeleteButtonTimer->Tag = 0; DeleteButtonTimer->Enabled = false; delete obj; } void __fastcall TForm1::click(TObject *Sender) { DeleteButtonTimer->Tag = reinterpret_cast<int>(Sender); DeleteButtonTimer->Enabled = true; }
或 post 使用
PostMessage()
给自己的自定义消息(我更喜欢这种方法):#define WM_DELETE_OBJECT (WM_USER + 1) void __fastcall TForm1::WndProc(TMessage &Message) { if (Message.Msg == WM_DELETE_OBJECT) delete reinterpret_cast<TObject*>(Message.LParam); else TForm::WndProc(Message); } void __fastcall TForm1::click(TObject *Sender) { TButton *btn = static_cast<TButton*>(Sender); btn->OnClick = NULL; PostMessage(Handle, WM_DELETE_OBJECT, 0, reinterpret_cast<LPARAM>(Sender)); }