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

Jos*_*f J 5 delphi delphi-7 delphi-2010

我从一个运行http://www.delphi-central.com/runtime.aspx的网站上尝试了一个脚本, 然后成功了.


private
  { Private declarations }
  procedure CustomButtonClick(Sender: TObject);
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)

但如果我更改OnClick,

OnClick := CustomButtonClick; ==> OnClick := DeleteLastButtonClick;
Run Code Online (Sandbox Code Playgroud)

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

Mas*_*ler 6

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

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

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

  • 现在我知道你的意思了,我得到一篇关于你的意思的文章"http://www.cryer.co.uk/brian/delphi/ howto_send_custom_window_message.htm"我学到了更多的感谢... (3认同)
  • @josef:这是一篇非常好的文章.但是有一个错误.SendMessage不会将消息发布到消息队列的末尾; 它将其直接发送给收件人以立即执行.但除了这个错误,它看起来像一篇好文章.在这种情况下你想要的是PostMessage,它将等到所有其他消息(其中一些可能需要使用按钮)在处理新消息之前完成. (3认同)

Lor*_*tel 5

当然它会热潮 - 这就是当你切断你所坐的树枝时容易发生的事情.

您无法杀死由该控件生成的事件处理程序中的控件.

请注意,您是从工作的样品也不要在删除程序点CustomButtonClick!