Solved

Self destruction

Posted on 2000-03-26
13
419 Views
Last Modified: 2010-08-05
Hi

Suppose I have a frame in a panel on a form. It displays properties of a given object. Now I want to put a button in that frame that will create another frame in the same place (i.e. Parent) which subsequently causes it's own destruction.

How can I do this without causing random access violations?

Have fun,

Edo
0
Comment
Question by:Edo082297
13 Comments
 
LVL 13

Expert Comment

by:Epsylon
ID: 2658760
An object can't destroy itself...
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2658970
Actually, an object can destroy itself. You just need to make sure that the object that does free itself never references a data member of the class after freeing itself.

eg:

  procedure TSomeObject.DoSomething;
  begin
    FFred := 0; // FFred is data member: OK
    Free; // Destroy this instance
    ShowMessage('I''m dead');
    FFred := 0; // Bad, this will AV.
  end;

Cheers,

Raymond.
0
 

Expert Comment

by:sunsetyang
ID: 2659335
You can either use a global variable to be sure of its in life when want to access.When it is freed,you should set the variable to mark this class has been destructed.If you are sure of your code,You can remove the flag and test for the proper result.
0
 
LVL 1

Expert Comment

by:yk030299
ID: 2659417
don't destroy when construction
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 2659865
From Delphi help:

Warning: Never explicitly free a component within one of its own event handlers or free a component from the event handler of a component it owns or contains. For example, don’t free a button in its OnClick event handler or free the form that owns the button from the button's OnClick event.


So what I said is, more or less, right...
0
 
LVL 1

Author Comment

by:Edo082297
ID: 2659994
Fine: it can't be done.

Post an answer, Epslyon, I suppose.

Raymond, I asked specifically about the button case, but thanks anyway.

I was really hoping someone knew an elegant way to unwind the stack or clear the message queue  such that control wouldn't return to the handler: but I believe this is not possible, as the button handler's address has been pushed into a register as the control return.

Cheers

Edo
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 3

Expert Comment

by:Slavak
ID: 2660063
If you call Close method of the form from button onClick event you actually destroy ( free ) the form. Difference is that close method use PostMessage function to be sure that all data member use over.
From my view Raymond answer should gain the points.

Cheers.

0
 
LVL 20

Expert Comment

by:Madshi
ID: 2660208
Look in the VCL sources at the implementation of the TForm.Release method. You can use the same logic for a button, too. Then the button *CAN* destroy itself without danger.

Regards, Madshi.
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 2660215
There is a solution. Instead of 'Free' send a user defined message to the main form:


PostMessage(Application.MainForm.Handle, WM_USER+1, 0, 0);

The main unit will receive the message and calls 'Free' and creates the new frame.


type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure WMUSER(var Message: TWMDestroy); message WM_USER+1;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  F1, F2: TFrame;

implementation

uses Unit2, Unit3;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
  F1 := TFrame2.Create(Self);
  F1.Align := alClient;
  F1.Parent := Panel1;
end;

procedure TForm1.WMUSER(var Message: TWMDestroy);
begin
  F1.Free;
  F2 := TFrame3.Create(Self);
  F2.Align := alClient;
  F2.Parent := Panel1;
end;
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 2669265
Edo, does this solve your problem?
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 2677085
Edo?
0
 
LVL 13

Accepted Solution

by:
Epsylon earned 100 total points
ID: 2688178
>LOCK<
0
 
LVL 1

Author Comment

by:Edo082297
ID: 2698212
Thankyou, this is good.

Cheers

Edo
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now