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

时间:2010-07-29 04:51:30

标签: delphi delphi-2010 delphi-7

我在我运行的网站上尝试过一个脚本 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;

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

3 个答案:

答案 0 :(得分:6)

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

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

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

答案 1 :(得分:5)

当然它会热潮 - 这就是当你切断你所坐的树枝时可能发生的事情。

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

请注意,您正在使用的示例 NOT 指向删除例程中的CustomButtonClick!

答案 2 :(得分:1)

很容易想到看原因,当你考虑系统必须以某种方式重新绘制按钮后释放鼠标按键/键。由于您在点击期间已经删除了按钮对象,因此会失败。

因此,您需要找到一种方法,以便在onClick事件处理完成并成功完成后以某种方式删除按钮。