如何動態釋放form |
尚未結案
|
kimochi
一般會員 發表:6 回覆:6 積分:2 註冊:2002-11-02 發送簡訊給我 |
|
ringox
一般會員 發表:7 回覆:14 積分:4 註冊:2003-04-09 發送簡訊給我 |
procedure TForm1._BClick(Sender: TObject);
begin
if FormClin=nil then
begin
Form2 := TForm2.Create(self);
Form2.Show;
end;
end; procedure TForm2._FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFREE;
Form2:=nil;
end; 要互相uses unit
|
kimochi
一般會員 發表:6 回覆:6 積分:2 註冊:2002-11-02 發送簡訊給我 |
謝謝ringox這麼快就幫我回答。
不過這樣不是我所要的,我現在就是這麼寫的。
我的情形
Main=Form1
MDI Child=Form2
Template=FormBase
我現在的作法也是直接在Form2上 key
procedure TForm2._FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFREE;
Form2:=nil;
end; 但是我希望能直接在FormBase上的關閉鈕寫程式,
在我動態create form2後, form2 上的關閉鈕,
能動態抓取 form2這個component,把 form2設定nil
之所以要這麼做是因為有太多form,一個一個寫滿累的,
目前遇到的困難是動態取得該Tform,如form2, fomr3.....
不知有無方法,可在Baseform中就寫好Close後的動作
謝謝。
|
conundrum
尊榮會員 發表:893 回覆:1272 積分:643 註冊:2004-01-06 發送簡訊給我 |
|
Chance36
版主 發表:31 回覆:1033 積分:792 註冊:2002-12-31 發送簡訊給我 |
kimochi 你好 個人覺得這種狀況,應該適合使用Windows的訊息處理機制實作如下 1.在主Form
Const WM_FREEFORM = WM_USER+100 ; .. TMainForm = Class (TForm) .. Private ... procedure FreeForm(var Message); message WM_FREEFORM ; ..... Public ... FReadyFreeForm : TBaseForm ; //接收要釋放的BaseForm案例 ... End; ... procedure TMainForm.FormCreate(Sender: TObject); Begin FReadyFreeForm := nil; End; procedure TMainForm.FreeForm(var Message); Begin If FReadyFreeForm <> nil Then Begin FReadyFreeForm.Free; FReadyFreeForm := nil; End; End; .... End. 2.在BaseForm uses MainForm; procedure TBaseForm.bCloseClick(Sender: TObject); Begin Do Something ; .. Close; MainForm.FReadyFreeForm := Self; //告訴主Form 把我釋放掉 sendMessage(Self.Parent.Handle,WM_FREEFORM,0,0); End;訊息處理機制,其實我也不熟,只是做過一些,應該還有改進的空間或是更好的方法,大家參考看看 發表人 - chance36 於 2004/02/11 01:57:26 發表人 - chance36 於 2004/02/11 12:57:47 |
kimochi
一般會員 發表:6 回覆:6 積分:2 註冊:2002-11-02 發送簡訊給我 |
|
Chance36
版主 發表:31 回覆:1033 積分:792 註冊:2002-12-31 發送簡訊給我 |
|
kimochi
一般會員 發表:6 回覆:6 積分:2 註冊:2002-11-02 發送簡訊給我 |
Chance36您好,
您所提到的問題,我有注意到,貼上我的原始碼,希望您能指教。 unit Main; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus; Const
WM_FREEFORM = WM_USER 100 ; type
TfmMain = class(TForm)
MainMenu1: TMainMenu;
test1: TMenuItem;
procedure test1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure FreeForm(var Message); message WM_FREEFORM ;
public
{ Public declarations } end; var
fmMain: TfmMain;
FReadyFreeForm : TfmBase ; implementation uses Base, Child; {$R *.dfm} procedure TfmMain.test1Click(Sender: TObject);
begin
if fmChild = nil then
begin
fmChild := TfmChild.Create(Self);
fmChild.show;
end
end; procedure TfmMain.FormCreate(Sender: TObject);
begin
FReadyFreeForm := nil; end;
procedure TMainForm.FreeForm(var Message);
Begin
If FReadyFreeForm <> nil Then Begin
FReadyFreeForm.Free;
FReadyFreeForm := nil;
End;
End; end. ***************************************************** unit Base; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls; type
TfmBase = class(TForm)
btnClose: TButton;
procedure btnCloseClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; var
fmBase: TfmBase; implementation uses Main;
{$R *.dfm} procedure TfmBase.btnCloseClick(Sender: TObject);
begin
self.Close;
Main.FReadyFreeForm := Self;
sendMessage(Self.Parent.Handle,WM_FREEFORM,0,0);
end; end. *****************************************************
Child則完全繼承Base,只有一按鈕。 另外,想問一個觀念問題。
可以用Self的觀念去釋放CHILD form嗎?
當動態開啟child form後, Self即等於 child form,
為何不能設定self:=nil去釋放 child form呢?謝謝。
|
Chance36
版主 發表:31 回覆:1033 積分:792 註冊:2002-12-31 發送簡訊給我 |
引言: 可以用Self的觀念去釋放CHILD form嗎? 當動態開啟child form後, Self即等於 child form, 為何不能設定self:=nil去釋放 child form呢?謝謝。請參考下列連結裏面有說明到 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=44564 void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action) { Action = caFree; Form2 = NULL; }這一段程式碼會不會有問題?? 雖然執行起來,系統不會當機, 但 因為 Form2 = NULL 這一行是寫在 Form2 的函數內,當 Form2 真的被釋放了,怎麼可能還可以繼續跑後續的程式碼?? 如果BCB的架構是把整段程式碼全部跑完,最後才來釋放記憶體, 那這一段程式碼更是千錯萬錯,因為你已經把Form2 的指標改到 NULL 這個位置了,也就是說,Form2根本不會被銷毀,還是在某 個不知位置的記憶體內,你釋放的是 NULL 這個位置的記憶體, 意思也就是說什麼動作根本都沒做,所以你也不會當機。 【截錄自以上連結】 MDIForm的程式,我未曾寫過,原則上主Form應該要有一個串列(TList或其後代類別,如TStringList)來管理ChildForm,子Form的建立及釋放皆須透過主Form來做,並同時管理好ChildForm的串列 , 子Form要釋放時只要通知主Form曰:[我要走了],其他的事皆交給主Form 。 或許MainForm已經有這個串列,我不知道,要請有經驗的人賜教了。當主 Form要結束時,需先檢查此串列是否還有子Form尚未結束的,通知子Form說[是時候,該走了] , 然後一一釋放子Form,最後清理現場,才能功成身退。 |
pwipwi
版主 發表:68 回覆:629 積分:349 註冊:2004-04-08 發送簡訊給我 |
所有的TComponent元件都有一個特性,在Destory的時候會把所有的Child Components都釋放掉。所以MDIChild會在他的Owner(也就是MDI Form)釋放時一起釋放。 但是如果Owner還在,MDIChild關閉不代表馬上被destroy。想要直接釋放的做法是直接使用FreeAndNil即可。MDIChild在釋放的時候,會呼叫Owner.RemoveComponent(Self)。因此不用怕MDIForm還會多事再把被釋放的Child再釋放一次。 附注一點,只要是動態產生的Component(繼承自TComponent),如果有指定Owner就不必再加上程式碼去釋放他。因為那是Owner的責任。 發表人 - pwipwi 於 2004/07/04 00:55:22
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |