Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I free a dynamically created object by clicking an object on it?

Graphical User Interface

How do I free a dynamically created object by clicking an object on it?

by  BobbaFet  Posted    (Edited  )
Say you have a dynamically created TPanel and on that panel you have a button that the user can use to close (TPanel.Free;) that panel.

Let's call the Panel myPanel. You cannot close myPanel by simply putting myPanel.Free; in the onClick event. This is because the button's event is executing and it will result in an EAccessViolation or an EAbstractError.

So how do you do this then? Well, that requires using a different procedure than the TButton.OnClick event.

You can do this by using PostMessage:
First you declare a constant that allows you to identify the message that will cause the procedure to trigger
Code:
// Declare your message that your app will respond to
[b]const CW_FREEPANEL = WM_USER + WM_APP + 123;[/b]
type
  TForm1 = class(TForm)

Here you tell your app that when a message with CW_FREEPANEL as the constant arrives, that it will need to execute this procedure
Code:
{ private declarations }
    // Declare the procedure that will respond to CW_FREEPANEL
    procedure FreeThisPanel(var msg: TMessage); message CW_FREEPANEL;

Here you define what happens once the message is received. In this case you free the panel.
Code:
procedure TForm1.FreeThisPanel(var Msg: TMessage);
begin
// Reads out WParam to know which panel to free
TTabSheet(msg.WParam).Free;
end;

With PostMessage you can set this message in the windows message queu so your app can respond to it. The user clicks on the button and the button onclick event will then post a message that your application can use to free it. By using
(Sender as TButton).Parent you get the parent object which you pass on to the procedure that will free it.
Code:
procedure TForm1.thisButton(Sender: TObject);
begin
// Posts the message with the offending panel in WParam
PostMessage(Self.Handle, CW_FREEPANEL, integer((Sender as TButton).Parent), 0);
end;

This gave me a lot of headaches so I thought I would post it here and hopefully prevent others from suffering from this as well.
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top