Solved

Self destruction

Posted on 2000-03-26
13
428 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How to define IfThen functions in one common unit? 4 79
Performance of SQL statement 37 148
Delphi: making a BW image transparent 10 138
Using MMsystem To change audio input 1 40
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…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…
This video shows how to use Hyena, from SystemTools Software, to update 100 user accounts from an external text file. View in 1080p for best video quality.

759 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