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 ...???
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!
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With