《新編Visual-Basic程序設計教程》第12章_第1頁
《新編Visual-Basic程序設計教程》第12章_第2頁
《新編Visual-Basic程序設計教程》第12章_第3頁
《新編Visual-Basic程序設計教程》第12章_第4頁
《新編Visual-Basic程序設計教程》第12章_第5頁
已閱讀5頁,還剩61頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第12章

多重窗體與MDI窗體程序設計多重窗體與MDI窗體概述多重窗體程序設計MDI窗體程序設計12.1多重窗體與MDI窗體概述多重窗體是指一個應用程序中有多個并列的普通窗體,每個窗體都是一個對象,可以有屬于自己的對象、屬性和事件過程,完成不同的功能。MDI窗體是指一個應用程序(父窗體)中包含多個文檔(子窗體),絕大多數(shù)基于Windows的大型應用程序都是MDI窗體,如MicrosoftExcel和MicrosoftWord等應用程序都是MDI窗體程序。MDI窗體可以同時打開多個文檔,它簡化了文檔之間的信息交換。在多重窗體中,窗體分為模態(tài)(Modal)和非模態(tài)(Nonmodal)兩種類型。在屏幕上顯示后用戶必須響應的窗體叫模態(tài)(Modal)窗體,除非用戶單擊OK(確定)或Cancel(取消)按鈕、或者關閉這個窗體,否則這種窗體將一直得到輸入焦點。用戶可以隨意在其間切換的窗體叫非模態(tài)(Nonmodal)窗體或無模式窗體。為了方便用戶使用,大多數(shù)Windows下的應用程序在顯示信息時,都使用非模態(tài)窗體。因此,在VisualBasic中建立新窗體時,非模態(tài)窗體是缺省設置。窗體的很多屬性都可以獨立設置,其中包括窗體的標題、大小、邊框類型、前景顏色、背景顏色、顯示字庫和背景畫面等。MDI窗體允許創(chuàng)建在單個容器窗體中包含多個窗體的應用程序,允許用戶同時顯示多個文檔,每個文檔顯示在它自己的窗體中。MDI窗體是有父子關系的窗體,可以根據(jù)窗體作用的不同,來確定窗體是父窗體還是子窗體。文檔或子窗體被包含在父窗體中,父窗體為應用程序中所有的子窗體提供工作空間,用戶在父窗體完成幾乎所有的工作。例如:MicrosoftExcel允許創(chuàng)建并顯示不同樣式的多文檔窗體,每個子窗體都被限制在Excel父窗體的區(qū)域之內。當最小化Excel父窗體時,所有的文檔窗體都被最小化,只有父窗體的圖標顯示在任務欄中。當關閉Excel父窗體時,所有的文檔窗體都被關閉,但關閉某個文檔窗口時,Excel父窗體不會被關閉。具體什么時候選用單窗體程序,什么時候使用多重窗體或MDI窗體呢?這需要根據(jù)應用程序的目的,來決定使用哪種界面樣式最好。例如:日歷程序最好設成單窗體程序,因為沒有必要同時打開一個以上日歷;一個處理保險索賠的應用程序可能要設計成MDI窗體,使用多文檔界面樣式,因為一個職員很可能會同時處理一個以上索賠,或者需要對兩個索賠進行比較;而一個管理信息系統(tǒng)(MIS系統(tǒng)),需要完成的功能比較多,比如最基本的功能添加、修改、刪除和查詢記錄等,這些功能的實現(xiàn)都需要窗體界面,而這些窗體一般都是并列使用,所以像學生成績管理系統(tǒng)這樣的應用程序一般設計成多重窗體程序。12.2多重窗體程序設計在多重窗體程序中,要建立的界面由多個窗體組成,每個窗體的界面的設計與前面學過的完全一樣。程序代碼也是針對每個窗體編寫的,因此也與單一窗體程序設計中的代碼編寫類似,只要注意各個窗體之間的相互關系就可以了。多重窗體實際上是單一窗體的集合,而單一窗體是多重窗體程序設計的基礎。掌握了單一窗體程序的設計,多重窗體的程序設計是很容易的。12.2.1添加窗體如果想在現(xiàn)有的工程中添加一個窗體,需要使用“添加窗體”對話框,如右圖所示,可以用三種方法打開“添加窗體”對話框:“新建”選項卡(1)通過“工程”(Project)菜單中的“添加窗體”(AddForm)命令。(2)單擊工具欄上的“添加窗體”按鈕。(3)在“工程資源管理器”窗口內單擊右鍵,在彈出菜單中選擇“添加”,再在下一級子菜單中選擇“添加窗體”。在“添加窗體”對話框里,可以選擇“新建”選項卡新建一個窗體,也可以選擇“現(xiàn)存”選項卡把一個屬于其他工程的窗體添加到當前工程中,這是因為每個窗體都是以獨立的文件保存的(擴展名為frm)。當新建一個窗體時,可以選擇欲建立窗體的類型(VisualBasic的不同版本預定義窗體集也不一樣),默認是建立一個新的空白窗體,你可以選擇建立為特定任務設計的半成品窗體。程序中第一個窗體被默認命名為Form1,后續(xù)的窗體則分別命名為Form2、Form3等,為了便于在代碼中引用窗體,最好是根據(jù)窗體的功能進行重新命名。當添加一個已經(jīng)存在的窗體到當前工程時,有兩個問題需要注意:(1)該工程內的每個窗體的Name屬性不能相同,否則不能將現(xiàn)存的窗體添加進來。(2)在該工程內添加進來的現(xiàn)存窗體實際上在多個工程中共享,因此,對該窗體所做的改變,會影響到共享該窗體的所有工程。12.2.2設置啟動對象在單一窗體程序中,程序的執(zhí)行沒有其他選擇,即只能從這個窗體開始執(zhí)行。多重窗體程序由多個窗體構成,而且多個窗體多是并列關系,VisualBasic怎么知道是從哪個窗體開始執(zhí)行呢?程序運行過程中,首先執(zhí)行的對象被稱為啟動對象。VisualBasic規(guī)定,對于多重窗體程序,必須指定其中一個對象為啟動對象。缺省情況下,第一個創(chuàng)建的窗體被默認指定為啟動對象,即啟動窗體。啟動對象既可以是窗體,也可以是Main子過程。如果啟動對象是Main子過程,則程序啟動時不加載任何窗體,以后由該過程根據(jù)不同的情況決定是否加載或加載哪一個窗體。需要注意的是,Main子過程必須放在標準模塊中,絕對不能放在窗體模塊內??梢酝ㄟ^“工程”菜單中“工程屬性”命令來指定啟動對象。執(zhí)行該命令后,將打開“工程屬性”對話框,然后選擇該對話框中的“通用”選項卡,將顯示的對話框如圖右所示?!巴ㄓ谩边x項卡在前圖所示的對話框中,單擊“啟動對象”欄右端的箭頭,將下拉顯示當前工程中所有窗體的列表,如下圖所示。此時條形光標位于當前啟動對象上,如果需要改變,則單擊作為啟動對象的名字,然后單擊“確定”按鈕,即可把所選擇的窗體設置為啟動對象。指定啟動對象12.2.3與多重窗體程序設計有關的語句和方法在單窗體程序設計中,所有的操作都在一個窗體中完成,不需要在多個窗體間切換。而在多窗體程序中,需要打開、關閉、隱藏或顯示指定的窗體,這可以通過相應的語句和方法來實現(xiàn)。下面介紹與多重窗體程序設計有關的語句和方法。1.Load語句該語句把一個在編程環(huán)境中已經(jīng)建立的窗體裝入內存。當VisualBasic執(zhí)行了該語句后,窗體并沒有顯示出來,只是被調入內存,但你可以在程序中的任一事件過程中訪問它,而且使用它所定義的任何屬性和方法。用Load語句裝入新窗體的語法格式為:例如,語句:LoadForm2,則工程中名稱為Form2的窗體就會被調入內存。如果想把該窗體的Caption屬性設置為“系統(tǒng)主界面”,可在任何事件過程中鍵入下述語句:Form2.Caption="系統(tǒng)主界面"。在首次使用Load語句將窗體調入內存時依次觸發(fā)窗體的Initialize和Load事件。Load窗體名稱2.Unload語句該語句與Load語句的功能相反,它從內存中刪除指定的窗體。該語句的語法格式為:Unload窗體名稱Unload的一種常見用法是UnloadMe,其意義是關閉窗體自己。在這里,關鍵字Me代表UnloadMe語句所在的窗體。3.Show方法該方法用來顯示一個窗體,它兼有加載和顯示窗體兩種功能。也就是說,使用Show方法時,如果窗體不在內存中(即以前沒有執(zhí)行Load語句),則Show方法自動把窗體裝入內存,然后再顯示出來。Show方法的語法格式為:[窗體名稱.]Show[模式]如果省略了“窗體名稱”,則顯示當前窗體。參數(shù)“模式”用來確定窗體是以模態(tài)加載還是非模態(tài)加載,它可以取0和1兩個值(注意不是False和True)。當“模式”值為1(或常量vbModal)時,表示窗體是“模態(tài)型”窗體。在這種情況下,鼠標只在此窗體內起作用,不能到其他窗口內操作,只有在關閉該窗口后才能對其他窗口進行操作。例如,MicrosoftWord中“幫助”菜單的“關于”命令所打開的對話框窗口就是這種窗口。當“模式”值為0(或省略該參數(shù))時,表示窗體為“非模態(tài)型”窗口,不用關閉該窗體就可以對其他窗口進行操作。例如,要以非模態(tài)窗體形式顯示Form2,可使用如下語句:Form2.Show。VisualBasic提供獨立的Load語句使程序能夠預先將窗體裝入內存,這樣,Show方法執(zhí)行得會非???,用戶往往感覺不到任何延遲。建議你最好預先裝入窗體,特別是當窗體包含很多對象或藝術修飾時,這樣做尤其必要。4.Hide方法該方法用來將窗體暫時隱藏起來,但并沒有從內存中刪除,因此它與Unload語句的作用是不一樣的。其語法格式為:當省略窗體名稱時,默認隱藏當前窗體。Hide方法和Unload語句的區(qū)別:使用Hide方法把窗體隱藏后,窗體雖然看不見了,但它仍駐留在內存中,可以供程序使用。隱藏窗體和通過設置窗體的Visible屬性使窗體不可見的效果是相同的。使用Unload語句卸載窗體,是把窗體從內存中清除,卸載窗體釋放了用來存儲窗體對象和圖形的內存空間,但并不釋放窗體事件過程占用的空間,這些事件過程常駐內存。窗體被卸載后,其運行時的值和屬性也就丟失了。當再裝入該窗體時,這些值恢復為程序代碼中設定的初始值。[窗體名稱.]Hide12.2.4不同窗體間數(shù)據(jù)的存取不同窗體數(shù)據(jù)的存取分為兩種情況:(1)存取控件中的屬性在當前窗體中要存取另一個窗體中某個控件的屬性,表示如下:另一個窗體名稱.控件名.屬性例如,設置當前窗體(Form1)中的文本框(Text1)的值,使它等于另一個窗體(Form2)中的兩個文本框(Text1和Text2)的數(shù)值之和,實現(xiàn)的語句如下:(2)存取變量的值根據(jù)變量的定義位置和所使用的變量定義語句的不同,VisualBasic中的變量可以分為3類,即局部變量、模塊變量及全局變量,其中模塊變量包括窗體模塊變量和標準模塊變量。各種變量位于不同的層次。Text1.Text=Val(Form2.Text1.Text)+Val(Form2.Text2.Text)在過程(事件過程或通用過程)內定義的變量叫做局部變量,其作用域是它所在的過程。某一過程的執(zhí)行只對該過程內的變量產生作用,對其他過程中相同名字的局部變量沒有任何影響。因此,可以在不同的過程中定義相同名字的局部變量,它們之間沒有任何關系。對于局部變量,可以使用Dim或Static語句聲明,也可以在需要時直接給出變量名。變量的類型可以使用類型說明符標識。如果沒有類型說明符,VisualBasic把該變量指定為變體數(shù)據(jù)類型。窗體變量可用于該窗體內的所有過程。一個窗體可以包含若干個過程,當同一窗體內的不同過程使用相同的變量時,則可以使用窗體變量。在使用窗體變量前,必須先聲明,也就是說窗體變量不能默認聲明。其方法是在程序代碼窗口的“對象”框中選擇“通用”,并在“過程”框中選擇“聲明”。聲明的時候,可以使用Dim、Private或Public語句。標準模塊變量與窗體變量是類似,這里不在敘述。全局變量的作用域最大,可以在工程的每個模塊、每個過程使用。和模塊級變量類似,全局變量也在“通用”部分聲明。所不同的是,全局變量必須用Public或Global語句聲明,不能用Dim語句聲明,更不能用Private語句聲明。同時,全局變量只能在標準模塊中聲明,不能在過程或窗體模塊中聲明。在應用程序中任何地方都可以修改全局變量,因此使用全局變量要格外小心,特別是在沒有強制要求定義變量的情況下。我們在多個窗體之間存取變量時,變量必須是窗體級變量,先用Public語句聲明,其引用格式如下:例如,工程中有兩個窗體(Form1和Form2),在Form1的“通用”里這樣聲明一個變量:PublictestAsString,則在Form2中就可以這樣引用Form1中的變量:a=Form1.test為了方便起見,要在多個窗體中存取的變量一般放在一個標準模塊內,用Public語句或Global語句聲明成全局變量。窗體名稱.變量名12.2.5多重窗體程序設計舉例例12.1

輸入學生五門課程的成績,計算總分及平均分并顯示。本例有三個窗體,名稱分別為frmMain、frmInput和frmOutput,其中frmMain作為本程序的主窗體,frmInput和frmOutput分別作為本程序的輸入和輸出窗體。另外,還要添加一個標準模塊Module1,在這個標準模塊內聲明多窗體間共用的全局變量。工程資源管理器窗口如下圖所示。工程資源管理器窗口frmMain窗體如下圖所示,這是本程序的主窗體,運行后看到的第一個窗體。該窗體上有三個命令按鈕,標題分別為:“輸入成績”、“計算成績”和“結束程序”;名稱分別為:cmdInput、cmdOutput和cmdExit,其中“輸入成績”和“計算成績”按鈕分別用來顯示frmInput和frmOutput窗體。frmMain窗體frmInput窗體如左圖所示,這是當在主窗體上單擊了“輸入成績”按鈕后彈出的窗體。該窗體上有五個用于輸入學生成績的文本框,名稱分別為:txtMath、txtChem、txtEng、txtPhy和txtChin。還有一個命令按鈕,標題為“確定”,名稱為:cmdOk。frmOutput窗體如右圖所示,這是當在主窗體上單擊了“計算成績”按鈕后彈出的窗體。該窗體上有用于顯示學生平均成績和總分的標簽,名稱為:labelAverage和LabelTotal。還有一個命令按鈕,標題為“返回”,名稱為“cmdReturn”。

frmInput窗體frmOutput窗體在Module1標準模塊內,聲明了在多個窗體間共用的全局變量,即:PublicsMathAsSinglePublicsChemAsSinglePublicsEngAsSinglePublicsPhyAsSinglePublicsChinAsSingle主窗體frmMain的事件過程如下:PrivateSubcmdInput_Click()Me.HidefrmInput.ShowEndSubPrivateSubcmdOutput_Click()Me.HidefrmOutput.ShowEndSubPrivateSubcmdExit_Click()EndEndSub輸入成績窗體frmInput的事件過程為:PrivateSubcmdOk_Click()sMath=Val(txtMath.Text)sChem=Val(txtChem.Text)sEng=Val(txtEng.Text)sPhy=Val(txtPhy.Text)sChin=Val(txtChin.Text)Me.HidefrmMain.ShowEndSub計算成績窗體frmOutput的事件過程如下:PrivateSubForm_Load()DimsTotalAsSinglesTotal=sMath+sChem+sEng+sPhy+sChinlabelAverage.Caption=sTotal/5LabelTotal.Caption=sTotalEndSubPrivateSubcmdReturn_Click()Me.HidefrmMain.ShowEndSub對于不同窗體間數(shù)據(jù)的存取,我們在前面已介紹了兩種方法,大家可以試著用另一種方法來實現(xiàn)本程序的功能。例12.2

設計一個模擬登陸系統(tǒng)程序,當輸入正確的用戶名和密碼時,顯示程序主窗體,并在主窗體上顯示用戶名。當用戶輸入錯誤時,提示用戶重新輸入,并且最多可以輸入三次。本例程序需要兩個窗體(frmLogin和frmMain),一個標準模塊(Module1)。frmLogin窗體就是一個自定義對話框,如下圖所示。窗體上有兩個文本框分別用來接收用戶輸入的用戶名和密碼,它們的名稱為txtName和txtPwd,其中txtPwd的PasswordChar屬性設置為“*”。窗體上還有兩個命令按鈕,標題為“確定”和“取消”,名稱為“cmdOK”和“cmdCancel”。為了不讓用戶隨意改變窗體的大小,再把窗體的BorderStyle屬性設置為3。frmLogin窗體frmMain窗體比較簡單,用一個標簽(LabelName)顯示當前用戶的用戶名,一個命令按鈕(cmdExit)用來關閉本窗口,如下圖所示。frmMain窗體在標準模塊(Module1)內聲明一個全局變量,用來存放用戶輸入的用戶名,如下:PublicuserAsStringfrmLogin窗體內的事件過程如下:DimtryAsIntegerPrivateSubcmdCancel_Click()UnloadMeEndSubPrivateSubcmdOK_Click()IftxtName.Text=""ThenMsgBox"請輸入用戶名!",vbOKOnly+vbExclamation,"錯誤"txtName.SetFocusExitSubEndIfIftxtPwd.Text=""ThenMsgBox"請輸入密碼!",vbOKOnly+vbExclamation,"錯誤"txtPwd.SetFocusExitSubEndIfIfTrim(txtName.Text)="vb"AndTrim(txtPwd.Text)="love"ThenMsgBox"你是合法用戶,歡迎使用!",vbOKOnly+vbInformation,"歡迎進入"user=Trim(txtName.Text)UnloadMefrmMain.ShowElsetry=try+1Iftry>=3ThenUnloadMeExitSubEndIfMsgBox"用戶名或密碼錯誤!您還有"&3-try&"次機會!",vbOKOnly+vbCritical,"警告"txtName.SetFocustxtName.Text=""txtPwd.Text=""EndIfEndSubfrmMain窗體內的事件過程比較簡單,如下所示:PrivateSubForm_Load()LabelName.Caption=userEndSubPrivateSubcmdExit_Click()UnloadMeEndSub12.3MDI窗體程序設計MDI窗體程序由父窗口和子窗口組成,父窗口又稱MDI窗體,它被作為子窗口的容器。子窗口又稱文檔窗口,它用于顯示各個文檔,所有的子窗口都具有相同的功能。12.3.1MDI窗體特性在運行時,MDI窗體及其所有的子窗體都呈現(xiàn)特定的性質,如下所述。(1)所有子窗體均顯示在MDI窗體的工作空間內。像其他的窗體一樣,用戶能移動子窗體和改變子窗體的大小,不過,它們被限制于這一工作空間內。(2)最小化一個子窗體時,它的圖標將顯示于MDI窗體上而不是在任務欄中。最小化MDI窗體時,此MDI窗體及其所有子窗體將由一個圖標來代表。還原MDI窗體時,MDI窗體及其所有子窗體將按最小化之前的狀態(tài)顯示出來。(3)最大化一個子窗體時,它的標題會與MDI窗體的標題組合在一起并顯示于MDI窗體的標題欄上。(4)通過設定AutoShowChildren屬性,子窗體可以在窗體加載時自動顯示(True)或自動隱藏(False)。(5)活動子窗體的菜單(若有)將顯示在MDI窗體的菜單欄中,而不是顯示在子窗體中。MDI窗體程序在所謂的“以文檔為中心的應用”中特別有用,在這種應用程序中,通常同時使用多個窗口來顯示或編輯文檔。12.3.2創(chuàng)建MDI應用程序前面已經(jīng)學習過,可以通過“添加窗體”對話框添加窗體,但這不是MDI窗體,只是多個普通窗體而已。如果創(chuàng)建一個MDI窗體應用程序,可以按以下步驟執(zhí)行:(1)在“工程”菜單中單擊“添加MDI窗體”菜單項,可以創(chuàng)建MDI應用程序的父窗體。注意,一個應用程序只能有一個MDI窗體,如果工程已經(jīng)有了一個MDI窗體,則該“工程”菜單上的“添加MDI窗體”命令就不可使用。MDI應用程序的父窗體是子窗體的容器,在該窗體中可以有菜單欄、工具欄、狀態(tài)欄等,但不可以有文本框等控件。(2)如果要創(chuàng)建子窗體,首先在“工程”菜單中單擊“添加窗體”菜單項,創(chuàng)建一個普通的窗體,然后將該窗體的MDIChild屬性設為True。一個應用程序可以包含許多相似或者不同樣式的MDI子窗體。若要建立多個子窗體,則重復上述操作就可以了。不過,創(chuàng)建以文檔為中心的應用程序,一般要求在運行時能提供若干子窗體以存取不同的文檔,而在設計時事先創(chuàng)建好若干個子窗體的方法是不可取的。一般是先創(chuàng)建一個子窗體作為這個應用程序文檔的模板,然后通過對象變量來實現(xiàn)。例如,假設已經(jīng)建立了一個名稱為“frmMDIChild”的子窗體模板,則使用下面的語句:就會為“frmMDIChild”建立一個新的實例NewDoc,新實例具有與“frmMDIChild”窗體相同的屬性、控件和代碼。在運行時,子窗體顯示在MDI父窗體工作空間之內(其區(qū)域在父窗體邊框以內及標題與菜單欄之下)。在設計時,子窗體并未被限制在MDI窗體區(qū)域之內,可以添加控件、設置屬性、編寫代碼以及設計子窗體功能,就像在其他VisualBasic窗體中做的那樣。DimNewDocAsNewfrmMDIChild通過查看MDIChild屬性或者檢查工程資源管理器,可以確定窗體是否是一個MDI子窗體。VisualBasic在“工程資源管理器”中為MDI窗體與MDI子窗體顯示了特定的圖標,如下圖所示?!肮こ藤Y源管理器”中的MDI窗體、MDI子窗體和標準窗體例12.3

設計一個簡單的多文檔記事本程序,在這個應用程序中,用戶可以打開多個文檔進行簡單編輯。用我們前面介紹的方法,建立MDI窗體應用程序的父窗體,在父窗體上設計程序中需要的菜單,各菜單項的屬性如下表所示菜單項Name屬性菜單項Name屬性文件mnuFile編輯mnuEdit….新建mnuNew….剪切mnuCut….保存mnuSave….全選mnuSelect….-mnuBar….退出mnuExit菜單屬性列表還要添加一個通用對話框控件(CommonDialog1)用來打開“另存為”對話框。最后把父窗體的Caption屬性設置為“多文檔記事本”,設計完整的父窗體如下圖所示。設計完整的父窗體添加MDI窗體程序的子窗體,首先添加一個普通窗體,然后把它的MDIChild屬性設置為True,名稱為“frmChild”,Caption屬性為“文檔”。要實現(xiàn)應用程序的編輯功能,需要在子窗體中引入一個文本框控件(Text1),設置Text1的MultiLine屬性為True,ScrollBars屬性值為3,即水平和垂直滾動條都存在。在程序代碼中,需要建立一個子程序來完成新建文檔的功能。則在父窗體的“通用”里新建一個過程LoadNewDoc,用來完成新建文檔的功能,代碼如下所示:PrivateSubLoadNewDoc()StaticDocCountAsLong'定義一個用于記數(shù)的靜態(tài)變量DimfrmDocAsfrmChild'定義frmDoc作為窗體對象DocCount=DocCount+1'每調用一次,記數(shù)加1SetfrmDoc=NewfrmChild'新建一個文檔窗體frmDoc.Caption="文檔"&DocCountfrmDoc.ShowEndSub在父窗體的“文件”菜單中“新建”菜單項的Click事件過程中編寫如下代碼:關于父窗體的“文件”菜單中其他菜單項的事件過程,涉及到后面的文件操作,這里不再介紹,有興趣的同學可以自己試著編寫代碼。下面介紹“編輯”菜單中“剪切”菜單項和“全選”菜單項代碼的編寫。在程序運行時建立了子窗體的許多實例(副本)來存取多個文檔時,它們具有相同的屬性和代碼,然后操作特定的窗體和特定的控件、保持各自的狀態(tài)信息,這對程序員來說是一個非常重要的問題。在VisualBasic中,提供了訪問MDI窗體的兩個屬性:ActiveForm和ActiveControl,前者表示具有焦點的或者最后被激活的子窗體,在程序中用它可以自動識別當前活動窗體,后者表示活動子窗體上具有焦點的控件。PrivateSubmnuNew_Click()LoadNewDocEndSub“剪切”菜單項的Click事件過程中的代碼如下:“全選”菜單項的Click事件過程中的代碼如下:PrivateSubmnuCut_Click()'將父窗體中活動的子窗體中的選中文本復制到剪貼板Clipboard.SetTextMDIForm1.ActiveForm.ActiveControl.SelText'清除活動窗體選中的文本MDIForm1.ActiveForm.ActiveControl.SelText=""EndSubPrivateSubmnuSelect_Click()'使用SelStart和SelLength選定文本MDIForm1.ActiveForm.Text1.SelStart=0MDIForm1.ActiveForm.Text1.SelLength=Len(MDIForm1.ActiveForm.Text1.Text)EndSub最后,在frmChild窗體的Form_Resize事件過程中添加如下代碼:上述代碼的作用是,當子窗體的尺寸改變時,其中的文本框也跟著改變。PrivateSubForm_Resize()MDIForm1.ActiveForm.Text1.Left=MDIForm1.ActiveForm.ScaleLeftMDIForm1.ActiveForm.Text1.Top=MDIForm1.ActiveForm.ScaleTopMDIForm1.ActiveForm.Text1.Width=MDIForm1.ActiveForm.ScaleWidthMDIForm1.ActiveForm.Text1.Height=MDIForm1.ActiveForm.ScaleHeightEndSub12.3.3MDI窗體及子窗體1.加載MDI窗體及子窗體加載子窗體時,其父窗體(MDI窗體)會自動加載并顯示。而加載MDI窗體時,其子窗體并不會自動加載。在例12.3中,子窗體是缺省的啟動窗體,因而在程序運行時,子窗體和MDI窗體兩者都會加載。如果在應用程序中改變啟動窗體為MDIForm1,然后運行應用程序,則只有MDI窗體被加載。當從“文件”菜單中選取“新建”命令時,才會加載第一個子窗體。MDI窗體有AutoShowChildren屬性,決定是否自動顯示子窗體。如果該屬性被設置為True,則當改變子窗體的屬性(如Caption等)后,會自動顯示該子窗體,不再需要使用Show方法;如果設置該屬性為False,則改變子窗體的屬性值后,不會自動顯示該子窗體,子窗體處于隱藏狀態(tài),直至用Show方法把它們顯示出來。這就允許在子窗體變成可見之前更新標題、位置和菜單等各種細節(jié)。2.設置子窗體的大小和位置如果MDI子窗體具有大小可變的邊框〔即BorderStyle=2〕,在其裝載時,Windows將決定其初始的高度、寬度和位置。邊框大小可變的子窗體,其初始大小與位置取決于MDI窗體的大小,而不是設計時子窗體的大小。當MDI子窗體的邊框大小不可變(即BorderStyle=0、1或3)時,則它將用設計時的Height和Width屬性被載入。如果設置AutoShowChildren為False,則在MDI子窗體載入以后,把它設為可見狀態(tài)之前,可以改變其大小和位置。定位窗體的代碼最好放在窗體的Load過程中,這樣會在窗體實際出現(xiàn)在屏幕上之前將窗體位置確定。要將窗體居中,需要在窗體的Load過程中簡單地添加代碼來計算并指定窗體左上角的位置,如下列代碼所示:利用坐標系統(tǒng)可以將窗體定位于屏幕或MDI窗體的任意位置。Me.Left=(Screen.Width-Me.Width)/2Me.Top=(Screen.Height-Me.Height)/23.MDI窗體程序子窗體的排列順序和方式在MDI應用程序中,缺省狀態(tài)下子窗體是按照窗口打開的順序排列的:當前活動窗體排在最前端,最先打開的窗體排在最底端。我們可以借助ZOrder方法動態(tài)地改變子窗體的排列順序。ZOrder方法的語法為:其中,Position取值為0時表示對象移至最前端,為1時表示對象移至最底端,缺省時值為0。例如,某一MDI應用程序有三個子窗體:Form1、Form2和Form3,若要將Form3移至最底端,則可在設計代碼時加上Form3.Zorder1即可。利用Zorder方法我們也可以創(chuàng)建浮動窗體,浮動窗體總是浮動到表面,也就是說它可以被其他窗體覆蓋,但馬上自動變成當前窗口并顯示在所有窗體的最上層。窗體名稱.ZOrder[Position]要創(chuàng)建浮動窗體,需要在窗體上添加一個定時器控件,并將它的Interval屬性設置為想讓窗體浮現(xiàn)的時間,如500毫秒。在Timer1_Timer事件過程中編寫如下代碼,便可以使用ZOrder方法使窗體浮動到頂部:使用過Word的用戶都知道,Word可同時打開多個文檔,并能以不同方式對文檔窗口進行排列,如平鋪、層疊等。這種重新排列子窗體的功能,在MDI應用程序中是可以通過編程來實現(xiàn)的。具體方法就是在相應的菜單控件的Click事件中調用Arrange方法,使用Arrange方法可以重新對齊子窗體,可以層疊、水平平鋪或者沿著MDI窗體的下部排列子窗體圖標等方式來顯示子窗體。Arrange方法的語法為:PrivateSubTimer1_Timer()ZOrderEndSubMDI窗體對象.ArrangeArrangement其中,Arrangement用來指定如何排列MDI應用程序的子窗體,其值可以是常數(shù)或數(shù)值,Arrangement的取值如下表所示。常數(shù)值描述vbCascade0層疊所有非最小化MDI子窗體vbTileHorizontal1水平平鋪所有非最小化MDI子窗體vbTileVertical2垂直平鋪所有非最小化MDI子窗體vbArrangeIcons3重排最小化MDI子窗體的圖標Arrangement的取值例如:若“平鋪”菜單項名為mnuHorizon,可編寫如下代碼,實現(xiàn)子窗體的平鋪:當平鋪或者層疊有著固定邊框類型的子窗體時,每個子窗體都像具有可變尺寸邊框那樣被定位,這使得子窗體可能重疊。即使MDI窗體被最小化,仍可以重新排列窗口和圖標,當MDI窗體最大化時,可以看到重排的結果。PrivateSubmnuHorizon_Click()MDIForm1.ArrangevbTileHorizontal'MDIForm1為MDI窗體名稱EndSub4.維護子窗體的狀態(tài)信息當子窗體被卸載時,其中的內容也會隨之消失,所以在用戶決定退出MDI應用程序時,必須有保存信息的機會,讓用戶執(zhí)行存盤操作,這樣才能確保數(shù)據(jù)不會丟失。當數(shù)據(jù)沒有改變而去存盤是沒有意義的,因此,應用程序必須隨時都能確定自上次保存以來子窗體中的數(shù)據(jù)是否有改變。這可以通過在每個子窗體中聲明一個公用變量來實現(xiàn)此功能,例如:當子窗體中的內容改變時,可將此變量設為True。在保存完數(shù)據(jù)后,再設為False。PublicDataChangeedAsBoolean在MDI應用程序中,在關閉應用程序時,VisualBasic將試圖卸載MDI窗體,當MDI窗體被卸載時,QueryUnload事件首先為MDI窗體調用,然后再為每一個打開的子窗體調用。如果在這些QueryUnload事件過程中沒有代碼,則取消Unload事件,然后,每一個子窗體被卸載,最后MDI窗體被卸載。由于QueryUnload事件在窗體卸載之前被調用,因此在窗體卸載前可以給用戶一個保存窗體、文件和一些數(shù)據(jù)的機會。我們可以在該事件過程中,判斷前面聲明的那個公用變量標志,然后提示用戶是否執(zhí)行保存操作,也可以在窗體的卸載事件(Unload)中判斷此變量標志,這樣,在MDI應用程序退出時就不會丟失數(shù)據(jù)了。5.顯示所有已打開子窗體標題如果想要實現(xiàn)這一功能,只要在設計MDI窗體及子窗體時的“窗口”菜單時,將WindowList屬性設置為True(即選中該復選框)即可。在運行時,VisualBasic自動管理與顯示標題清單,并在當前正有焦點的標題旁邊顯示一個復選標志。另外,還在窗口清單的上方自動放置一個分隔符條。WindowList屬性在運行時是只讀的,只能在設計時設置。只能將菜單欄中的某一個菜單的WindowList屬性設置為True,打開窗口的列表只出現(xiàn)在WindowList屬性設置為True的菜單對象中,如果單擊窗口列表中的某一個窗體名稱,就可以激活那個窗體。12.3.4MDI窗體的菜單和工具欄設計MDI應用程序的菜單設計與一般應用程序的菜單設計方法一致,可利用“菜單編輯器”來完成,但MDI應用程序的菜單還有其特殊性。在MDI應用程序中,每一個子窗體的菜單都顯示在MDI窗體上,而不是在子窗體本身。當子窗體有焦點時,該子窗體的菜單(如果有的話)就代替菜單欄上的MDI窗體的菜單。如果沒有可見的子窗體,或者帶有焦點的子窗體沒有菜單,則顯示MDI窗體的菜單。MDI應用程序使用幾套菜單的情況很普遍。當打開一個文檔時,應用程序顯示與該類文檔相關的菜單。通常,沒有可見子窗體時會顯示一個不同的菜單。例如,當沒有文件打開時,MicrosoftExcel只顯示“文件”與“幫助”菜單。當用戶打開一個文件時,其他菜單就會顯示出來,如“文件”、“編輯”、“視圖”、“插入”、“格式”、“工具”和“窗口”等。管理MDI應用程序中菜單的一個方法是把希望在任何時候都顯示的菜單控件放在MDI窗體上,當運行該應用程序時,如果沒有可見的子窗體,會自動顯示MDI窗體菜單。把應用于子窗體的菜單控件放置到子窗體中,在運行時,只要有一個子窗體可見,這些菜單標題就會顯示在MDI窗體的菜單欄中。雖然子窗體的菜單可替代主窗體的菜單,但在編寫菜單命令的響應事件的處理時卻不相同。在VisualBasic中,只能在本窗體內響應菜單命令,因此主菜單的命令處理只能在主窗體模塊中進行,而子窗體的命令處理只能在子窗體模塊中進行。即使子窗體的菜單顯示在主窗體的菜單位置,但它還是子窗體的菜單。有些應用程序支持多種類型的文檔。例如,在MicrosoftAccess中,可以打開表格、查詢、窗體和其他文檔類型。要在VisualBasic中創(chuàng)建這樣的應用程序,應使用兩個子窗體。設計一個帶有執(zhí)行工作單任務菜單的子窗體和另一個帶有完成圖表任務菜單的子窗體。在運行時,當工作單窗體的實例有焦點時,則顯示工作單菜單,而當選取圖表時,則顯示圖表窗體的菜單。如果所有的工作單和圖表都關閉,則顯示MDI窗體的菜單。大多數(shù)MDI應用程序的菜單欄中都有“窗口”這一特殊菜單項,這是一個顯示所有打開的子窗體標題的特殊菜單,如下圖所示。另外,有些應用程序將操縱子窗體的命令,比如“層疊”、“平鋪”與“排列圖標”,也放在這個菜單中。工具欄(也稱為發(fā)條或者控制欄)已經(jīng)成為許多基于Windows的應用程序的標準功能,它提供了應用程序中最常用的功能。利用工具欄可以對應用程序中最常用的命令快速訪問,還可以進一步增強應用程序的界面。VisualBasic中的“窗口”菜單創(chuàng)建工具欄的方法有兩種:手工創(chuàng)建或使用ToolBar等控件創(chuàng)建。1.手工創(chuàng)建工具欄手工創(chuàng)建工具欄是利用圖片框和命令按鈕或圖像框控件制作,比較煩瑣。具體步驟如下:(1)在MDI窗體上放置一個圖片框(PictureBox)控件,并設置其Align屬性,通常Align屬性可以設置為1或2。當Align屬性值為1時,圖片框的寬度會沿MDI窗體頂端自動伸展,直到填滿MDI窗體工作空間;當Align屬性值為2時,圖片框的寬度會沿MDI窗體底端自動伸展,直到填滿MDI窗體工作空間。工作空間就是窗體邊框以內的區(qū)域,不包括標題條、菜單欄或所有的工具欄、狀態(tài)欄或者可能在窗體上的滾動條。前面我們說過,只能把那些直接支持Align屬性的控件放置在MDI窗體上,而圖片框是支持這一屬性的唯一的標準控件。(2)在圖片框中,可以放置任何想在工具欄上顯示的控件。典型地,用命令按鈕或Image控件來創(chuàng)建工具欄按鈕。要在圖片框中添加控件,單擊工具欄中的控件按鈕,然后在圖片框中畫出它。(3)設置設計時屬性。使用工具欄的一個好處是可以顯示一個形象的命令圖示,Image控件是作為工具欄按鈕的一個很好的選擇,因為可以用它來顯示一個位圖。在設計時設置其Picture屬性來顯示一個位圖,再通過設置工具欄按鈕的ToolTipText屬性,實現(xiàn)自動提示功能。設置工具欄按鈕的ToolTipText屬性后,運行時當用戶把鼠標指針停留在該按鈕上時,就可以自動顯示ToolTipText屬性的內容。(4)調整各工具欄按鈕的位置和大?。ㄒ部梢栽贔orm_Load事件過程中編程實現(xiàn))。(5)編寫各工具欄按鈕的代碼。因為工具欄頻繁地用于提供訪問某些應用程序命令的快捷方法,因而在大部分時間內都是在按鈕的Click事件中調用其他過程。例如,在VisualBasic的工具欄上的“保存”按鈕,它的功能和“文件”菜單中“保存工程”菜單項的功能完全一樣。與其把這些功能代碼重復兩次,還不如把代碼放到窗體的一個公用過程中,然后在上面的任何一個事件過程調用這個過程。下圖是一個含有Image控件的工具欄。手工創(chuàng)建的工具欄2.使用ToolBar和ImageList控件創(chuàng)建工具欄使用ToolBar控件創(chuàng)建工具欄非常容易且很方便,它在VisualBasic的專業(yè)版與企業(yè)版中是可用的。使用這種方法創(chuàng)建工具欄比手工創(chuàng)建要方便得多,而且外形更美觀,更接近于Windows的風格。ToolBar控件包含用來創(chuàng)建工具欄的按鈕對象的集合,也就是顯示在工具欄上的一組按鈕。每個按鈕對象都可有圖像、標題和提示,其中,圖像是由相關的ImageList控件所提供。使用ToolBar和ImageList控件來創(chuàng)建工具欄的步驟如下:(1)鼠標右鍵單擊工具箱,選“部件”命令,打開“部件”對話框(也可以在“工程”菜單中選擇“部件”菜單項打開)。單擊“部件”對話框的“控件”選項卡,在控件的列表里選中“MicrosoftWindowsControls6.0”復選框,將ToolBar和ImageList等控件添加到工具箱,新添加的控件如右圖所示。工具箱(2)分別雙擊ToolBar和ImageList控件,把它們添加到窗體上。(3)設置ImageList控件的屬性。ImageList控件不單獨使用,專門為其他控件提供圖像庫,是一個圖像容器控件。工具欄按鈕的圖像就是通過ToolBar控件從ImageList控件的圖像庫中獲得的。用鼠標右鍵單擊ImageList控件,選擇“屬性”命令,可以打開“屬性頁”對話框,在“屬性頁”對話框里設置ImageList控件的屬性。該對話框包括三個選項卡:通用、圖像和顏色。其中“通用”選項卡用于設置圖片大小,“圖像”選項卡用于插入圖片,“圖像”選項卡如下圖所示。ImageList控件的“圖像”選項卡在“圖像”選項卡中,單擊“插入圖片”按鈕,選擇希望作為工具欄按鈕圖標的圖片,圖像文件的擴展名為.ico、.bmp、.gif、.jpg等。插入圖片后,“索引”框將從1開始,按插入順序自動編號,此編號與ToolBar控件屬性頁中“按鈕”選擇項的“圖像”框中的數(shù)字相對應,“圖像”框中的數(shù)字為1,則工具欄上該按鈕的圖標就是ImageList控件中索引值為1的圖片?!瓣P鍵字”表示每個圖像的標識名,可以在ToolBar控件中引用?!皠h除圖片”按鈕,用于刪除選中的圖片?!皥D像數(shù)”表示已經(jīng)插入的圖像數(shù)目。(4)右擊ToolBar控件,選擇“屬性”,打開ToolBar控件的屬性頁對話框。它也有三個選項卡:通用、按鈕和圖片。單擊“通用”選項卡,在“圖像列表”下拉框中選擇所需要的ImageList控件,建立ImageList控件與ToolBar控件間的關聯(lián),如右圖所示。ToolBar控件的“通用”選項卡在“樣式”下拉框中可以選擇工具欄的不同樣式:0-tbrStandard型或1-tbrFlat型。0-tbrStandard型工具欄按鈕呈突出狀,單擊時有按下并彈起的效果;1-tbrFlat型則呈平面,當鼠標移至按鈕上方時,按鈕突出顯示,與Windows95下的工具欄按鈕風格類似?!翱蓳Q行的”復選框被選中表示當工具欄的長度不能容納所有工具按鈕時,在下一行顯示。如果不選中該復選框,則當工具欄的長度不能容納所有工具按鈕時,剩余的就不再顯示。切換到“按鈕”選項卡,如下圖所示。ToolBar控件的“按鈕”選項卡最開始

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論