1. 程式人生 > >Delphi中的窗體建立與銷燬

Delphi中的窗體建立與銷燬

  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變數(有點繞口令了,不知道大家看懂沒有……)。