1. 程式人生 > >Delphi中的窗體創建與銷毀

Delphi中的窗體創建與銷毀

tab nil 切換 什麽 RoCE code 需要 bject lpad

  Delphi中的窗體,有模式窗體與非模式窗體兩種。兩種窗體的調用方式不同,模式窗體使用ShowModal顯示,非模式窗體使用Show顯示。當顯示模式窗體的時候你是不能操作本程序的其他窗體的,你不能把焦點從模式窗體轉到其他窗體上。而非模式窗體則沒有這種限制,你可以從一個非模式窗體切換到另外一個非模式窗體上。兩種窗體的區別僅僅在調用的方式上有區別。

窗體的創建:

當使用Delphi的IDE New一個窗體後,在Project1.dpr文件中,會出現一句

1 Application.CreateForm(TForm2, Form2);

意思是當程序啟動的時候會創建TForm2類的Form2實例,也就是窗體2。這一過程是自動的,不管你是否調用顯示Form2,
Form2已經存在了,其OnCreate事件也已經觸發了。這時候,如果你想顯示Form2,那麽可以顯式調用Form2的Show或ShowModal方法,以非模式或模式顯示窗體。

如果你不想隨程序啟動而創建窗體,而是動態的創建窗體,那麽,你可以刪除上面的那句代碼,然後在程序中你想動態創建窗體的地方加上以下代碼:

1 2 //需要在頭部引用TForm2所在的單元文件,並聲明Form2變量。 Application.CreateForm(TForm2, Form2);

或者使用

1 2 //和上面一樣,需要引用並聲明。註意,一定不要直接這樣寫Form2.Create Form2 := TForm2.Create(Application);

兩者沒有特別大的區別,一般情況下是通用的。兩者的主要區別在於,觸發OnCreate事件的時候,第一種方法Form2變量已經指向了新生成的實例,外部代碼可以直接調用Form2這個變量了,而第二種方法先調用TForm2的Create方法,再給Form2這個變量賦值,在OnCreate時Form2變量還是未定義的。這點區別比較小,基本上不會遇到,但是如果不明白其中的道理,又遇到這個問題的話會浪費你很多時間來調試的。

窗體銷毀:

有創建,就必須有銷毀,不然的話會產生內存泄漏。

當我們調用Form的Close或者點擊窗體右上角的X時,窗體真的已經釋放了麽?答案是否定的,如果你想驗證的話……你可以去看源碼。對於程序自動生成的窗體,在程序結束的時候會自己釋放,對於這種窗體,我不建議進行手動釋放,除非你確定釋放後絕對不會再用到這個窗體了,不然就會產生內存訪問錯誤。

對於動態生成的窗體,一旦不再使用,一定要手動釋放資源,不然你會看到程序占有內存瘋狂上漲,然後就被任務管理器幹掉了~手動釋放主要有兩種方式,第一種是顯示調用Form.Free這個方法。對於上面用的例子Form2來說:

1 2 Form2.Free; Form2 := nil;

至於為什麽要將變量Form2賦值為nil,是為了防止此後的代碼通過Form2變量訪問已經被釋放的TForm2實例。
另一種方法是在窗體的OnClose事件中將變量Action設置為caFree。

1 2 3 4 5 procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; // TCloseAction = (caNone, caHide, caFree, caMinimize); Form2 := nil; end;

這兩種方法沒有什麽本質區別,可以根據實際情況來使用,但是一定不要忘記在釋放資源後將變量指向空,不然很容易出現非法訪問的情況。實際上在TForm2的FormClose中寫Form2 := nil 是無用的,應該寫在創建Form2的單元中,因為這兩個Form2變量是不同的,TForm2所在單元的Form2變量是一個私有變量,別人是訪問不到的,別人可以訪問到的,也就是可能觸發非法訪問的是在TForm2所在單元外的Form2變量(有點繞口令了,不知道大家看懂沒有……)。

Delphi中的窗體創建與銷毀