大多數(shù) Delphi 7 的應(yīng)用程序至少有一個(gè) TForm的實(shí)例。Delphi 7 VCL 應(yīng)用程序也只能有一個(gè) TApplication 的實(shí)例和一個(gè) TScreen 的實(shí)例凭语。TForm、TApplication拾因、TScreen 3 個(gè)類在 Delphi 7 中起著舉足輕重的作用∪糇ǎ可根據(jù)需要修改它們的默認(rèn)功能脖含。
1.? TForm類
TForm 類(即窗體類)是Delphi 7 應(yīng)用程序的焦點(diǎn)。
大多數(shù)情況下角骤,整個(gè)應(yīng)用程序都是圍繞窗體操作的隅忿。從主窗體中可以打開其他窗體,通常要通過菜單命令或按鈕邦尊”惩可以自動(dòng)創(chuàng)建窗體,也可以選擇在運(yùn)行期間動(dòng)態(tài)創(chuàng)建窗體蝉揍。
注意:Delphi 可以創(chuàng)建不使用窗體的程序(例如控制臺(tái)程序链峭、服務(wù)和COM服務(wù)器),在這種情況下又沾,TForm 就不再是應(yīng)用程序的焦點(diǎn)弊仪。
顯示給用戶的窗體有兩種:有模式的和無模式的。具體使用哪一種窗體杖刷,取決于用戶是否希望能夠同時(shí)用這個(gè)窗體和其他窗體交互励饵。
1.1?顯示一個(gè)模式窗體
當(dāng)打開一個(gè)模式窗體后,用戶無法與應(yīng)用程序的其他部分交互滑燃,直到用戶關(guān)閉了這個(gè)窗體役听。模式窗體通常是對話框,就像Delphi 7 本身自帶的對話框一樣表窘。事實(shí)上典予,大多數(shù)情況下應(yīng)當(dāng)使用模式窗體。
要顯示一個(gè)模式窗體蚊丐,只要調(diào)用 ShowModal 就可以了熙参。下面的代碼演示了如何創(chuàng)建 TModalForm,并把它作為模式窗體打開麦备。
var
ModalForm:TModalForm;
begin ? //創(chuàng)建 TModalForm 的實(shí)例 ??
ModalForm:=TModalForm.Create(Application); ??
try ????
if ModalForm.ShowModal=mrOk then???? //顯示這個(gè)窗體 ?????
?{執(zhí)行一些代碼} ??
finally ????
ModalForm.Free; ????
ModalForm:=nil; ?
end; end;
上面的代碼演示了如何動(dòng)態(tài)地創(chuàng)建TModalForm 以及把實(shí)例賦值給ModalForm 變量孽椰。
注意:如果需要?jiǎng)討B(tài)創(chuàng)建一個(gè)窗體的實(shí)例,就要把這個(gè)窗體從“Project Options”對話框中的“Auto-Create forms”框中去掉凛篙。
如果窗體的實(shí)例已經(jīng)存在黍匾,可以調(diào)用ShowModal 函數(shù)打開它,其他代碼可以刪掉呛梆,縮減代碼如下:
begin ?
if ModalForm.ShowModal = mrOk then???? //如果 ModalForm 已經(jīng)存在 ???
{執(zhí)行一些代碼}
end;
ShowModal函數(shù)的返回值是ModalForm 的ModalResult屬性值锐涯。默認(rèn)情況下,ModalResult 屬性
的值為0填物,相當(dāng)于預(yù)定義的常量mrNone纹腌。如果ModalResult 屬性被賦值為其他非零值霎终,則窗體將關(guān)閉。
可以在運(yùn)行時(shí)對窗體的ModalResult 屬性進(jìn)行賦值升薯,代碼如下:
begin
? ModalForm.ModalResult := 100;
end;
表 --1 所示為預(yù)定義的 ModalResult值莱褒。
?常量 ?????????值
mrNone???? ?0 ?
mrOk ?????????idOk ?
mrCancel? ?idCancel ?
mrAbort???? ?idAbort ?
mrRetry? ? ? idRetry ?
mrIgnore? ? ?idIgnore ?
mrYes? ? ? ? ?idYes ?
mrNo? ? ? ? ? idNo ?
mrAll? ? ? ? ? mrNo+1 ?
2.打開一個(gè)無模式窗體
要打開一個(gè)無模式窗體,可以調(diào)用Show 方法涎劈。無模式窗體與有模式窗體的區(qū)別在于用戶可以在無模式窗體和其他窗體之間切換广凸。這樣,用戶就可以同時(shí)工作于一個(gè)應(yīng)用程序的幾個(gè)部分蛛枚。下面的代碼演示了怎樣動(dòng)態(tài)地創(chuàng)建一個(gè)無模式的窗體谅海。
var
? Modeless:TModeless;
begin
? if not Assigned(Modeless) then??????????????? //檢查無模式窗體的實(shí)例是否已經(jīng)存在?
? Modeless:=TModeless.Create(Application);??? //創(chuàng)建窗體
? Modeless.Show;??????????????????????????? //顯示無模式窗體 end;
上述代碼同時(shí)演示了怎樣防止一個(gè)窗體的多個(gè)實(shí)例存在。注意蹦浦,無模式的窗體允許用戶與應(yīng)用程序的其他部分交互扭吁,這樣,用戶可以照常使用菜單命令白筹,或者創(chuàng)建TModeless 的另一個(gè)實(shí)例智末。因此谅摄,需要考慮這些實(shí)例的創(chuàng)建和刪除問題徒河。
要特別注意窗體的實(shí)例:當(dāng)通過窗體的系統(tǒng)菜單或者窗體上的Close 按鈕關(guān)閉這個(gè)窗體時(shí),窗體并沒有真正從內(nèi)存中釋放送漠,它仍然還在內(nèi)存中顽照,除非關(guān)閉了主窗體(即應(yīng)用程序)。在上述程序示例中闽寡,then 后面的語句只會(huì)執(zhí)行一次代兵,前提是這個(gè)窗體不是自動(dòng)創(chuàng)建的。如果希望用戶關(guān)閉了窗體就在內(nèi)存中釋放它爷狈,必須處理它的OnClose 事件植影,并且把Action 參數(shù)設(shè)為caFree,這樣涎永,VCL 就會(huì)在這個(gè)窗體關(guān)閉時(shí)釋放它思币。
procedure
? TModeless.FormClose(Sender:TObject;var Action:TCloseAction); begin
? Action:=caFree;????? //當(dāng)關(guān)閉時(shí)釋放窗體實(shí)例?
end;
上述代碼就可以解決窗體實(shí)例在內(nèi)存釋放的問題了。還有一個(gè)問題羡微,注意下面這行代碼:
?if not Assigned(Modeless) then
上述代碼檢查TModeless 的實(shí)例是否已經(jīng)有Modeless 變量引用谷饿,這實(shí)際上就是檢查Modeless 是否為nil。盡管第1 次進(jìn)入例程的時(shí)候妈倔,Modeless 可能是nil博投,但第2 次進(jìn)入這個(gè)例程的時(shí)候,它已經(jīng)不是nil盯蝴。這是因?yàn)閂CL 并沒有把Modeless變量設(shè)為nil毅哗,因此听怕,必須手工把這個(gè)變量設(shè)為nil。
與模式窗體不同的是虑绵,無法在代碼中判斷無模式窗體什么時(shí)候?qū)h除叉跛,這樣就無法在創(chuàng)建窗體實(shí)例的例程中刪除窗體的實(shí)例。用戶有可能在應(yīng)用程序正在運(yùn)行的任何時(shí)候關(guān)閉無模式窗體蒸殿。因此筷厘,無模式窗體本身一定要把Modeless 變量設(shè)為nil,而且最好在處理窗體的OnDestroy 事件的處理過程中設(shè)置這個(gè)變量:
procedure
TModeless.FormDestroy(Sender: TObject);
begin
? Modeless:=nil;???? //把Modeless
? 變量設(shè)置為nil
end;
這樣就能保證每次關(guān)閉窗體時(shí)宏所,Modeless 變量總是被設(shè)為nil酥艳,從而防止Assigned()函數(shù)失敗。注意爬骤,同一時(shí)刻只能創(chuàng)建TModeless的一個(gè)實(shí)例充石。
注意,對于無模式窗體來說霞玄,要避免出現(xiàn)下列有缺陷的代碼:
begin
? Modeless:=TModeless.Create(Application);
? Modeless.Show;
end;
上述代碼會(huì)導(dǎo)致每次創(chuàng)建窗體的實(shí)例骤铃,重復(fù)以前被Modeless 引用的實(shí)例,從而消耗了大量的內(nèi)存坷剧。
盡管通過Screen.Forms可以訪問這些實(shí)例惰爬,但最好還是盡量避免使用上述代碼。向構(gòu)造器Create()傳遞nil造成無法在Modeless 實(shí)例變量被覆蓋后惫企,無法再引用這個(gè)窗體實(shí)例指針撕瞧。
3.窗體的圖標(biāo)和邊框
TForm 有一個(gè)BorderIcons屬性,包含下列元素:biSystemMenu狞尔、biMinimize丛版、biMaximize 和biHelp。只要讓這個(gè)集合不包含其中的某個(gè)元素偏序,就可以使窗體上不出現(xiàn)相應(yīng)的系統(tǒng)菜單页畦、最大化按鈕和最小化按鈕,但窗體上總是有關(guān)閉按鈕研儒。
還可以通過BorderStyle 屬性改變窗體的非客戶區(qū)豫缨。BorderStyle 有6 個(gè)值供用戶選擇,具體如下:
[if !supportLists]??? [endif]bsNone:無邊框殉摔,尺寸的大小不可以改變州胳。
[if !supportLists]??? [endif]bsSingle:單線邊框,尺寸的大小不可以改變逸月。
[if !supportLists]??? [endif]bsDialog:標(biāo)準(zhǔn)的對話框邊框栓撞,尺寸的大小不可以改變。
[if !supportLists]??? [endif]bsSizeable:標(biāo)準(zhǔn)的可變尺寸邊框。
[if !supportLists]??? [endif]bsToolWindow:和bsSingle 相同瓤湘,但標(biāo)題只有一個(gè)小的“關(guān)閉”按鈕瓢颅。
[if !supportLists]??? [endif]bsSizeToolWin:和bsSizeable 相同,但標(biāo)題只有一個(gè)小的“關(guān)閉”按鈕弛说。
注意:窗體屬性BorderIcons 的設(shè)置與屬性BorderStyle 的設(shè)置可能會(huì)發(fā)生互斥挽懦,例如屬性BorderIcons 的biMinimize 和biMaximize會(huì)與屬性BorderStyle 的bsDialog 沖突,屬性BorderIcons 的biHelp 會(huì)與屬性BorderStyle的bsSizeable 沖突木人。?