相關(guān)資訊
本類常用軟件
-
福建農(nóng)村信用社手機(jī)銀行客戶端下載下載量:584204
-
Windows優(yōu)化大師下載量:416898
-
90美女秀(視頻聊天軟件)下載量:366961
-
廣西農(nóng)村信用社手機(jī)銀行客戶端下載下載量:365699
-
快播手機(jī)版下載量:325855
最為一個(gè)鞏固之前有關(guān)窗體和對象的有關(guān)知識(shí),下面就建立一個(gè)簡單的MDI示范程序,這個(gè)程序的功能是打開和保存圖形文件(包括位圖、圖標(biāo)等),為了完成這個(gè)任務(wù),我們有一個(gè)大概的計(jì)劃,計(jì)劃內(nèi)容如下:
(1)建立主窗體(一個(gè)MDI父窗體),包括菜單。
(2)為【File | Open…】 和【File | Save…】菜單選項(xiàng)編寫代碼。
(3)為Windows菜單上的Cascade、Tile和Arrange All選項(xiàng)編寫代碼。
(4)建立MDI子窗體。
(5)建立一個(gè)About對話框。
(6)然后再回憶和欣賞一下這段工作。
時(shí)間就是金錢,即刻就做吧 。
一、創(chuàng)建主窗口窗體
首先創(chuàng)建一個(gè)主窗口窗體,一個(gè)MDI應(yīng)用程序的主窗口的FormStyle屬性必須設(shè)置為fsMDIForm。不但要為應(yīng)用程序增加File Open和 File Save 對話框,還要增加一個(gè)菜單。
1、啟動(dòng)Delphi,并從主菜單選擇【File | New | Application】;
2、把主窗體的Name屬性設(shè)置為MainForm;
3、把Caption屬性設(shè)置為Picture Viewer;
4、把FormStyle屬性設(shè)置為fsMDIForm;
好了,下面為此窗體增加一個(gè)菜單,利用Delphi特性,引進(jìn)一個(gè)預(yù)定義菜單,具體如下:
1、點(diǎn)擊組件選項(xiàng)板的Standard標(biāo)簽,并點(diǎn)擊MainMenu按鈕;
2、把MainMenu組件點(diǎn)擊放置到窗體上,具體放到哪個(gè)地方無所謂了,因?yàn)樵谶\(yùn)行階段,代表菜單的圖標(biāo)只是占地方而不顯示,這是非可視化組件。
3、把MainMenu組件Name屬性改為MainMenu;
4、雙擊MainMenu組件,就會(huì)出現(xiàn)Menu Designer對話框;
5、在MainMenu上點(diǎn)擊鼠標(biāo)右鍵,選擇“Insert From Template…”,將出現(xiàn)Insert Template對話框;
6、選擇“MDI Frame Menu”并點(diǎn)擊OK,此菜單將顯示在Menu Designer上,關(guān)閉Menu Designer窗口。
現(xiàn)在又回到了主窗體,注意現(xiàn)在窗體上多了一條菜單,此時(shí)先不要點(diǎn)擊任何子菜單項(xiàng),我們先準(zhǔn)備File Open對話框和File Save對話框:
1、點(diǎn)擊組件選項(xiàng)板的Dialogs標(biāo)簽,選擇Open Picture Dialog組件,并把它放到窗體上,這也是一個(gè)非可視組件。
2、把Open對話框的Name屬性改為OpenPictureDialog;
3、把Open對話框的Title屬性改為“Open a Picture for Viewing”;
4、在窗體再增加一個(gè)Save Picture Dialog組件;
5、把此組件的Name屬性改為“SavePictureDialog”,把Title屬性改為“Save a Picture”;
此時(shí)窗體看起來應(yīng)該像下圖:
二、編寫【File | Open…】和【File | Save As…】菜單選項(xiàng)代碼
下面就準(zhǔn)備開始編寫代碼,Delphi提供了一種很好地編寫菜單處理程序的方法,從而使遇到的麻煩最小。還不要建立MDI子窗體,但要充分了解它,并用它來為菜單處理程序編寫代碼,記住在建立MDI子窗體之前一直不要編譯應(yīng)用程序(因?yàn)檫沒有建立MDI子窗體,編譯會(huì)出現(xiàn)錯(cuò)誤的)
1、在主窗體上選擇【File | Open…】菜單項(xiàng),這樣就會(huì)在Code Editor中為此菜單項(xiàng)建立一個(gè)事件處理程序。
2、為此事件處理程序鍵入下列代碼:
procedure TMainForm.Open1Click(Sender: TObject); var Child: TChild; begin if OpenPictureDialog.Execute then begin Child := TChild.Create(Self); with Child.Image.Picture do begin LoadFromFile(OpenPictureDialog.FileName); Child.ClientWidth := Width; Child.ClientHeight := Height; end; Child.Caption := ExtractFileName(OpenPictureDialog.FileName); Child.Show; end; end;
這段代碼首先打開一個(gè)“Open a Picture for Viewing”對話框,并得到一個(gè)文件名,如果點(diǎn)擊這個(gè)對話框的OK按鈕,就會(huì)產(chǎn)生一個(gè)TChild對象(TChild是MDI子類的名字,后面將要建立它。)圖像文件被顯示到窗體上的Image組件,并且MDI子窗口將會(huì)與圖像大小相匹配,最后子窗體的標(biāo)題會(huì)顯示被選中的圖像文件名。
Note
在上面的方法中,ExtractFileName函數(shù)是用來從路徑中提取文件名的函數(shù),文件名包含在OpenPictureDialog的FileName屬性中,相關(guān)的函數(shù)包括ExtractFilePath、ExtractFileDir、ExtractFileDrive和ExtractFileExt。
Note
前面我們說過所有動(dòng)態(tài)創(chuàng)建的對象到最后都要用Free刪除掉,但是上面的代碼中好像違反了這個(gè)規(guī)律,實(shí)際上并沒有,因?yàn)閂CL將負(fù)責(zé)釋放分配給MDI子窗口的內(nèi)存。注意TChild構(gòu)造程序中的單個(gè)參數(shù)是Self;這是通知VCL,MDI子窗體的擁有者就是此MDI窗體窗口。當(dāng)MDI窗體消失時(shí),它將刪除所有MDI子對象。
3、按下F12鍵,切換到主窗體MainForm,現(xiàn)在從菜單中選擇【File | Save As…】,將會(huì)顯示該菜單項(xiàng)處理事件。
4、鍵入以下代碼:
procedure TMainForm.SaveAs1Click(Sender: TObject); begin if SavePictureDialog.Execute then begin with ActiveMDIChild as TChild do { 檢查MDI子窗體是否被激活,只保存激活窗體的圖像文件} Image.Picture.SaveToFile(SavePictureDialog.FileName); end; end;
這段代碼比較簡潔,頭兩行是用來檢查MDI子窗口是否被激活,如果是激活的窗體,就會(huì)顯示“Save a Picture”對話框,若用戶點(diǎn)擊OK,那就將用TPicture類的SaveToFile方法把圖像存到盤上去。
Note
前面的這段代碼中用到了as操作符,ActiveMDIChild屬性返回一個(gè)指向TForm對象的指針,在這種情況下,實(shí)際上只需要一個(gè)指向TChild對象的指針(MDI子類是從TForm類派生來的),as操作符把ActiveMDIChild變量強(qiáng)制轉(zhuǎn)化為一個(gè)TChild指針,如果as不能完成這種強(qiáng)制轉(zhuǎn)化,as后面的語句將被忽略。
在繼續(xù)講解前,我們先把這個(gè)工程保存起來,將Unit1保存為PctViewU.pas,將工程文件dpr保存為PictView。
三、為【W(wǎng)indows】菜單編寫代碼
1、F12切換到MainForm窗體上,從窗體上MainMenu菜單上選擇【W(wǎng)indows | Tile】;
2、只需要為此事件處理程序中輸入一行代碼即可,最終的事件處理代碼如下:
procedure TMainForm.ile1Click(Sender: TObject); begin Tile; end;
3、切換到MainForm窗體,并為菜單【W(wǎng)indows | Cascade】創(chuàng)建代碼,如下:
procedure TMainForm.Cascade1Click(Sender: TObject); begin Cascade; end;
4、切換到MainForm窗體,再次為菜單【W(wǎng)indows | Arrange All】創(chuàng)建代碼如下:
procedure TMainForm.ArrangeAll1Click(Sender: TObject); begin ArrangeIcons; end;
好,主窗體工作完成了,下面將進(jìn)行創(chuàng)建MDI子窗體。
四、創(chuàng)建MDI子窗體
MDI子窗體非常簡單,實(shí)際上不必寫任何代碼,只要操作下列各步即可:
1、用工具欄上的New Form按鈕或者通過主菜單上的【File | New Form】來創(chuàng)建一個(gè)新窗體;
2、把它的Name屬性設(shè)置為Child,Caption屬性將被忽略,因?yàn)樵谶\(yùn)行階段將要?jiǎng)討B(tài)設(shè)置此屬性;
3、把FormStyle屬性設(shè)置為fsMDIChild,為了把這個(gè)窗體當(dāng)做MDI子窗體來處理,這是必須的。
為窗體本身要做的就這些,下面就在此窗體上放置一個(gè)Image組件,Image組件將顯示用戶選擇的圖形文件。
1、點(diǎn)擊組件選項(xiàng)板上的Additional標(biāo)簽,點(diǎn)擊Image按鈕,并把它放置到Child窗體上;
2、把它的Name屬性設(shè)置為Image;
3、把它的Stretch屬性設(shè)置為True;
4、把它的Align屬性設(shè)置為alClient,Image組件將縮放到窗體的客戶區(qū)大;
5、選擇Delphi主菜單的【File | Save】,以MDIChild保存此窗體單元。
6、切換到Code Editor,點(diǎn)擊PctViewU標(biāo)簽,然后從Delphi主菜單選擇【File | Use Unit】,選擇MDIChild單元,點(diǎn)擊OK,這樣該工程就可以編譯了。
此時(shí),整個(gè)MDI子窗體看上去如下:
我們的程序還沒有完成,因?yàn)檫差一個(gè)About框,此時(shí)我們更渴望看到程序的運(yùn)行,先點(diǎn)擊Run按鈕,就可以運(yùn)行程序了,選擇【File | Open…】就可以打開任何圖形文件了。
注意MDI子窗口會(huì)自動(dòng)縮放它所包含的圖形,打開幾個(gè)文件,然后試一試Window菜單的Cascade和Tile選項(xiàng)。
五、建立About對話框
到目前為止,我們自己隨意建立一個(gè)屬于自己的About框,我的About對話框效果如下:
1、將建立好的About窗體的Name屬性設(shè)置為AboutBox,BorderStyle屬性設(shè)置為bsDialog
2、以PVAboutU保存此About對話框窗體單元;
3、切換到Code Editor中的PctViewU標(biāo)簽,從Delphi主菜單選擇【File | Use Unit】將PVAboutU單元包含近來;
4、按F12切換到MainForm主窗體,從菜單上選擇【Help | About】,這樣就產(chǎn)生一個(gè)OnClick處理事件;
5、為此事件添加代碼如下:
procedure TMainForm.About1Click(Sender: TObject); begin AboutBox.ShowModal; end;
現(xiàn)在運(yùn)行它,點(diǎn)擊Run按鈕,試一試Help菜單的About選項(xiàng),運(yùn)行效果如下:
六、進(jìn)一步完善程序
此時(shí)這個(gè)程序已經(jīng)可以運(yùn)行了,但它不等于就沒有值得完善的地方。
對于這個(gè)程序還有兩個(gè)問題需要值得注意,它們?nèi)菀谆煜,首先,?dāng)啟動(dòng)該程序時(shí),會(huì)顯示一個(gè)空白MDI子窗口,這是因?yàn)镈elphi應(yīng)用程序會(huì)自動(dòng)建立所有窗體。我們可以從自動(dòng)產(chǎn)生的清單中刪除MDI子窗體。
1、從Delphi主菜單中選擇【Project | Options…】,將顯示Project Option對話框;
2、點(diǎn)擊Forms標(biāo)簽,其中“Auto-create forms”中顯示的就是所有會(huì)自動(dòng)創(chuàng)建產(chǎn)生的窗體清單;
3、點(diǎn)擊其中不想要自動(dòng)創(chuàng)建的窗體Child,選擇 >按鈕,就會(huì)從自動(dòng)創(chuàng)建列表中刪除該子窗口,并把它放置到“Available forms”列表中。
再次運(yùn)行此程序,這一次將不顯示空白MDI子窗體。
Caution
如果要從自動(dòng)產(chǎn)生清單中刪除一個(gè)窗體,就必須保證在用它之前要建立一個(gè)專門的窗體,如果不建立一個(gè)窗體,指向窗體的指針就不能初始化,這就意味著還沒有為此指針賦一個(gè)有意義的值(記住指針是由Delphi自動(dòng)產(chǎn)生)。試圖用這個(gè)指針,其結(jié)果將會(huì)產(chǎn)生一個(gè)非法錯(cuò)誤,當(dāng)從自動(dòng)產(chǎn)生清單中刪除一個(gè)窗體后,就必須負(fù)責(zé)在用它之前建立它。
還有一個(gè)問題,就是在MDI窗體上點(diǎn)擊關(guān)閉按鈕時(shí),發(fā)現(xiàn)子窗口并沒有關(guān)閉,而是最小化,因此我們要修改它,使得點(diǎn)擊關(guān)閉后真正被關(guān)閉。
1、在Form Designer中選擇Child子窗體,選中窗體本身,確認(rèn)在Object Inspector的Component Selector中選擇的是Child。
2、雙擊Events頁的OnClose事件,添加代碼如下:
procedure TChild.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end;
把關(guān)閉動(dòng)作設(shè)置為caFree,指示VCL關(guān)閉子窗體,并釋放與窗體有關(guān)的內(nèi)存,這時(shí)點(diǎn)擊MDI子窗體關(guān)閉按鈕就可以正常關(guān)閉了。
4、再次運(yùn)行此程序,證明此程序的表現(xiàn)與前面所述的一樣。