全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2045
推到 Plurk!
推到 Facebook!

如何動態釋放form

尚未結案
kimochi
一般會員


發表:6
回覆:6
積分:2
註冊:2002-11-02

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-02-10 23:51:28 IP:211.23.xxx.xxx 未訂閱
請問一下各位, 以下情況該怎樣解決呢? 我有一MDI FORM的表單,menu會依照一template form動態create child form,template form中有一按鈕『關閉』我要如何在template form中寫程式,動態釋放(要nil) child form呢?也就是說我要如何動態取得該form,並nil該form呢?謝謝大家。 發表人 - kimochi 於 2004/02/11 00:01:58
ringox
一般會員


發表:7
回覆:14
積分:4
註冊:2003-04-09

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-02-11 00:45:11 IP:61.30.xxx.xxx 未訂閱
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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-02-11 00:59:28 IP:211.23.xxx.xxx 未訂閱
謝謝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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-02-11 01:06:24 IP:61.64.xxx.xxx 未訂閱
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=43193
Chance36
版主


發表:31
回覆:1033
積分:792
註冊:2002-12-31

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-02-11 01:55:41 IP:203.204.xxx.xxx 未訂閱
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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-02-11 13:56:18 IP:211.23.xxx.xxx 未訂閱
Chance36您好, 請問一下,我一您所提供的方法實做,會出現錯誤耶? 不知是不是我設定錯誤? 錯誤發生在 FReadyFreeForm : TBaseForm ; //接收要釋放的BaseForm案例 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 會出現 Undeclared identifier:'TBaseForm'? 請問一下,是不是我哪裡有漏掉呢?謝謝。
Chance36
版主


發表:31
回覆:1033
積分:792
註冊:2002-12-31

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-02-11 15:36:24 IP:211.20.xxx.xxx 未訂閱
引言: FReadyFreeForm : TBaseForm ; //接收要釋放的BaseForm案例
TBaseForm 只是代表,你必須把它改成你自已定義的BaseForm類別名稱
kimochi
一般會員


發表:6
回覆:6
積分:2
註冊:2002-11-02

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-02-11 21:58:55 IP:211.23.xxx.xxx 未訂閱
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

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-02-11 22:28:25 IP:211.20.xxx.xxx 未訂閱
引言: 可以用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

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-07-04 00:54:07 IP:211.76.xxx.xxx 未訂閱
所有的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
系統時間:2024-05-18 6:04:57
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!