delphi – 当我在自己的OnClick处理程序中销毁一个按钮时,为什么我的程序会崩溃?

我从我运行的网站上尝试了一个脚本
http://www.delphi-central.com/runtime.aspx并取得成功.
private
  { Private declarations }
  procedure CustomButtonClick(Sender: TObject);
procedure TForm1.AddNewButtonClick(Sender: TObject);
var
  NewButton : TButton;
begin 
  NewButton := TButton.create(self);

  with NewButton do
  begin
    Top    := 30;
    Width  := 60;
    Left   := Width * (self.ControlCount-2);
    Parent := self;
    OnClick := CustomButtonClick;
    Caption := 'Button '+ inttostr (self.ControlCount-2);
  end;  //With
end;

procedure TForm1.DeleteLastButtonClick(Sender: TObject);
begin
  if Self.ControlCount>2 then
    TButton (Controls[ControlCount-1]).destroy;
end;

procedure TForm1.CustomButtonClick(Sender: TObject); 
begin    
    ShowMessage(TButton(Sender).caption + ' Pressed'); 
end;

但如果我更改OnClick,

OnClick := CustomButtonClick; ==> OnClick := DeleteLastButtonClick;

它会生成一条错误消息.
怎么会发生这种情况…… ???

解决方法

事件处理程序由控件对象上的函数调用,一旦事件处理程序完成,它可能有更多代码要执行.如果删除该控件,则引用该对象的任何代码都可能引发访问冲突.

您需要做的是让程序在完成当前运行的所有代码后删除控件.为此,您需要发布消息.如果您不了解消息,这是一个学习的好机会.

您需要创建新的消息类型ID. WM_USER 1应该可以工作.其中一个参数将是要删除的控件的地址.在表单上设置一个处理该消息类型的消息处理程序,并释放消息参数中引用的控件.然后在事件处理程序中,将PostMessage消息发送给您的表单.这应该工作而不会导致访问冲突.

相关文章

 从网上看到《Delphi API HOOK完全说明》这篇文章,基本上都...
  从网上看到《Delphi API HOOK完全说明》这篇文章,基本上...
ffmpeg 是一套强大的开源的多媒体库 一般都是用 c/c+&#x...
32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和ED...
1 mov dst, src dst是目的操作数,src是源操作数,指令实现的...