Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
How to free a parent form when its child gets closed or freed Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
19-May-03
Category
Win API
Language
Delphi 2.x
Views
106
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			Author: Tomas Rutkauskas 

I am using a TPageControl and show some forms on its pages. So, whenever I want to 
show a form I create a new page on the TPageControl for that form and then displat 
the form in that page. Now I want free that page when the user closes the form 
sitting on it. I tried using the form's OnClose or OnDestroy events to free the 
parent tabsheet of the form but I get an access violation.

Answer:

Solve 1:

It is difficult enough to destroy a control from an event handler of that control, 
trying to destroy its parent adds even more problems to that. The best way to 
handle this is to leave the destruction of the tabsheet to a neutral 3rd party, in 
this case the form holding the pagecontrol. In the embedded forms OnClose you post 
(via postmessage) a custom message to the form holding the pagecontrol and then 
hide the embedded form. The host form then destroys the tabsheet and that also 
destroys the embedded form. Posting the message delays the action long enough to 
allow any code in the embedded form to complete safely. Example:

1   {Unit for the embedded form}
2   
3   unit Unit2;
4   
5   interface
6   
7   uses
8     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
9   Dialogs,
10      StdCtrls;
11  
12  const
13    UM_KILLCONTROL = WM_USER + 666;
14  type
15    TUMKillControl = record
16      msg: Cardinal;
17      control: TControl;
18      unused: LPARAM;
19      result: LRESULT;
20    end;
21  type
22    TForm2 = class(TForm)
23      Button1: TButton;
24      procedure Button1Click(Sender: TObject);
25      procedure FormClose(Sender: TObject; var Action: TCloseAction);
26    private
27    public
28    end;
29  
30  implementation
31  
32  {$R *.dfm}
33  
34  procedure TForm2.Button1Click(Sender: TObject);
35  begin
36    close
37  end;
38  
39  procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
40  begin
41    action := caHide;
42    PostMessage(GetParentForm(self).Handle, UM_KILLCONTROL, Integer(parent), 0);
43  end;
44  
45  end.
46  
47  {Unit for the host form}
48  
49  unit Unit1;
50  
51  interface
52  
53  uses
54    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
55    ComCtrls, StdCtrls, unit2;
56  
57  type
58    TForm1 = class(TForm)
59      StatusBar: TStatusBar;
60      Button1: TButton;
61      PageControl1: TPageControl;
62      procedure Button1Click(Sender: TObject);
63    private
64      { Private declarations }
65      procedure UMKillControl(var msg: TUMKillControl); message UM_KILLCONTROL;
66    public
67      { Public declarations }
68    end;
69  
70  var
71    Form1: TForm1;
72  
73  implementation
74  
75  {$R *.DFM}
76  
77  procedure TForm1.Button1Click(Sender: TObject);
78  var
79    tab: TTabSheet;
80  begin
81    tab := TTabSheet.Create(self);
82    tab.PageControl := pagecontrol1;
83    with TForm2.create(self) do
84    begin
85      borderstyle := bsNone;
86      parent := tab;
87      tab.caption := caption;
88      align := alclient;
89      show;
90    end;
91  end;
92  
93  procedure TForm1.UMKillControl(var msg: TUMKillControl);
94  begin
95    msg.control.Free;
96  end;
97  
98  end.



Solve 2:

As long as the child form is not "owned" by the tabsheet on which it is parented 
(being owned by the form which owns the PageControl is OK), you can do this:

99  { ... }
100 type
101   TfNastyChild = class(TForm)
102     procedure FormClose(Sender: TObject; var Action: TCloseAction);
103   private
104     { Private declarations }
105     fKillParent: TWinControl;
106   public
107     { Public declarations }
108     destructor Destroy; override;
109   end;
110 
111 implementation
112 
113 {$R *.dfm}
114 
115 procedure TfNastyChild.FormClose(Sender: TObject; var Action: TCloseAction);
116 begin
117   if (Parent is TTabsheet) and (Owner <> Parent) then
118   begin
119     Hide;
120     fKillParent := Parent;
121     Parent := nil;
122   end;
123   action := caFree;
124 end;
125 
126 destructor TfNastyChild.Destroy;
127 begin
128   if assigned(fKillParent) and not (csDestroying in fKillParent.ComponentState) then
129     fKillParent.Free;
130   inherited;
131 end;


			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC