我在删除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;
}
当我点击创建的按钮时,在模块' rtl60.bpl'中的地址40005905处发生错误"访问冲突,读取地址00000018"出现
我知道将一个方法分配给删除它的按钮是错误的,但我真的需要通过按下来删除按钮
答案 0 :(得分:1)
您的代码中有两个错误。
调用Form1
构造函数时尚未分配全局TForm1
变量,因此您的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;
}
或者使用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));
}