Why does my program crash when I destroy a button in its own OnClick handler?

旧时模样 提交于 2019-12-18 08:32:20

问题


I tried a script from a web site I run http://www.delphi-central.com/runtime.aspx and succeed.


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;

But if I change the OnClick,

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

it will generate an error message. How could this happen ...???


回答1:


An event handler is called by a function on the control's object, and it could have more code to execute once the event handler finishes. If you delete the control, then any code that references that object is likely to raise an access violation.

What you need to do is get your program to delete the control after it's done with all the code it's currently running. For that, you need to post a message. If you don't know about messages, this is a good opportunity to learn.

You need to create a new message type ID. WM_USER + 1 should work. One of the params will be the address of the control to be deleted. Set up a message handler on your form that handles that message type and frees the control referenced in the message param. And then in the event handler, have it PostMessage that message to your form. That should work without causing access violations.




回答2:


Of course it goes boom--that's what's liable to happen when you cut off the branch you're sitting on.

You can't kill a control inside an event handler spawned by that control.

Note that the sample you're working from did NOT point the CustomButtonClick at the delete routine!




回答3:


It is easy think see the reason, when you consider that the system must somehow redraw the button after you release the mouse button / key. Since you're deleting the button object already during the click, this will fail.

Hence you need to find a way to somehow delete the button after the processing of the onClick event has occurred and successfully finished.



来源:https://stackoverflow.com/questions/3359552/why-does-my-program-crash-when-i-destroy-a-button-in-its-own-onclick-handler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!