22.多重文件介面

對許多需要同時開啟多個文件的應用程式而言,多重文件界面(Multiple Document Interface,MDI)提供了一個理想的架構,讓程式設計師可以建構極具彈性的使用者界面,然而多重文件界面仍有一些鮮為人知的細節,使得設計人員無法完全地把它的功能發揮到極致。本章的重點在介紹建構MDI應用程式的主要概念,讓你對設計MDI應用程式能得心應手。

如何建立MDI應用程式?
 

這一節針對建立MDI應用程式的基本概念作一簡要的說明,至於細節部分,請參考Visual Basic的線上說明或線上手冊。

MDI表單
 

MDI表單是所有子表單的收納器,一個專案中只能有一個MDI表單,要在專案中加入一個MDI表單,請在「專案」功能表中選擇「新增MDI表單」,然後在「新增MDI表單」對話方塊中,點選二下MDI表單圖像。MDI表單的屬性項目比一般表單的屬性項目要少,此外,MDI表單不一定非得是啟動表單,如果要把MDI表單設成啟動表單,可以在「專案」功能表中選擇專案「屬性」,然後在「專案屬性」對話方塊的「一般」頁籤下,指定MDI表單為「啟動物件」。

MDI子表單
 

一個專案中可以有任意個包含於MDI表單中的子表單(MDI專案中也可以有任意個獨立的一般表單)。要建立一張MDI子表單,請將一般表單的MDIChild屬性設為True,這樣這張表單就成了MDI表單的子表單了。在程式執行的階段,程式本身必須負責載入這些子表單,同時子表單的顯示、隱藏以及卸載等動作都要用程式來控制。在設計階段,子表單看起來和一般表單沒有兩樣,但它們之間最大差別是兩者在執行階段所表現的行為大不相同。


 

 圖22-1 顯示的是執行中的MDI表單

ActiveForm和ActiveControl屬性
 

當ActiveForm和ActiveControl屬性在一起使用時,可以使MDI表單引用目前作用中的控制項,這個控制項是在目前擁有駐點的子表單中。舉例來說,假設你的MDI應用程式在好幾個子表單上都有相同的文字方塊控制項,那麼當某個子表單文字方塊中的文字被選取,而且「複製」選項被點選時,ActiveForm.ActiveControl.SelText所引用的就是目前作用中文字方塊中的文字。

Me關鍵字
 

Me關鍵字所引用的是目前作用中的子視窗。當某個子表單本身擁有多個執行實體時,Me關鍵字讓子表單中的程式碼可以作用在目前擁有駐點的子表單執行實體上。

Tag屬性
 

Tag屬性可以讓你儲存程式所需用到的額外資料,因此,Tag屬性可以用來辨識每一份子表單。怎麼做?每當產生一份子表單的執行實體時,你可以分別指定不同的數字或字串給每個 實體的Tag屬性。這樣等於建立了一個索引,可以用來追蹤每一份子表單的執行實體。

MDI表單的基本特性
 

與其他表單比較,MDI表單是一種很獨特的表單,以下這些即是MDI表單的基本特性:

  1. 子表單永遠只出現在MDI表單中,即使子表單被最小化之後仍然是在MDI表單中,而當MDI表單被最小化時,子表單會跟著最小化,此時使用者會看不見子表單。
  2. >如果某個子表單上面有功能表,那麼當這個子表單取得駐點時,MDI表單上也會有這個功能表。在執行階段,子表單的功能表會被併入到MDI表單的功能表中,因此,在子表單上你看不到功能表。
  3. 在MDI表單上加入功能表沒有問題,但是在MDI表單上加入控制項卻有些限制 。只有含Align屬性的控制項才能放進MDI表單中。(這種限制有方法可以解除──只要在MDI表單上畫上一個圖片方塊控制項,然後就可以在圖片方塊控制項上面放上你想要用的控制項)。如果MDI表單上有任何控制項,則子表單不會和控制項的任何一部份重疊。
  4. 用Dim As New陳述式可以為子表單產生多個執行實體,前面提到的ActiveForm、ActiveControl、Tag屬性及Me關鍵字,都和處理多個子表單執行實體有很大的關聯。
  5. MDI表單的Picture屬性可以讓你用點陣圖或其他圖案作為MDI表單的背景。

參考資料:

 第三十二章"資料庫" 的Jot應用程式將會介紹如何使一個單一的子表單產生多個視窗(子表單執行實體)。


如何在MDI表單中加入商標圖案?
 

要在MDI表單的正中央擺上一個圖案會有一些困難需要克服,因為MDI表單的Picture屬性會使圖案向表單左上角對齊,而且只有能對齊(含Align屬性)的控制項才可以擺在MDI表單中。圖22-2所顯示的是一個MDI表單中央擺上一個圖案的假想應用程式。

如果要解決這個問題,請試試這個範例。請建立一個MDI表單專案,專案中內含一個子表單frmLogo;加入一個Image控制項imgLogo (商標圖案在這裡)到子表單中,你不能把Image控制項放在MDI表單裡,而且如果在MDI表中用一個Picture控制項來收納Image控制項,當MDI表單改變大小時,商標就不會在MDI表單的正中央。把商標圖案放在子表單中,可以使子表單永遠向中央對齊而達成使商標在正中央的目的。

接著,把子表單的Border屬性設為"0 - 沒有框線",去掉子表單的框線和標題,然後將子視窗的大小調整成和Image控制項的大小一樣,最後把商標圖形檔載入imgLogo裡,最後,把以下這段程式加入到MDI表單中:


 

 圖22-2 MDI表單中央擺上一個商標圖案
Option Explicit

Private Sub MDIForm_Resize()
    'Move logo to upper-left corner of Image control
    frmLogo.imgLogo.Move 0, 0
    'Size form to size of image it contains
    frmLogo.Width = frmLogo.imgLogo.Width
    frmLogo.Height = frmLogo.imgLogo.Height
    'Center logo form on MDI form
    frmLogo.Left = (ScaleWidth - frmLogo.Width) \ 2
    frmLogo.Top = (ScaleHeight - frmLogo.Height) \ 2
    'Show logo
    frmLogo.Show
End Sub

當MDI表單的大小被改變時,MDIForm_Resize先把圖形移動到子表單的左上角,重新調整子表單的大小,接著把商標再度定位在子表單的中央,最後再把子表單擺到MDI表單的正中央。