Self destruction

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
LVL 1
Edo082297Asked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
EpsylonConnect With a Mentor Commented:
>LOCK<
0
 
EpsylonCommented:
An object can't destroy itself...
0
 
rwilson032697Commented:
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
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

 
sunsetyangCommented:
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
 
yk030299Commented:
don't destroy when construction
0
 
EpsylonCommented:
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
 
Edo082297Author Commented:
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
 
SlavakCommented:
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
 
MadshiCommented:
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
 
EpsylonCommented:
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
 
EpsylonCommented:
Edo, does this solve your problem?
0
 
EpsylonCommented:
Edo?
0
 
Edo082297Author Commented:
Thankyou, this is good.

Cheers

Edo
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.