關於多個檔介面

多文檔介面中的每個檔 (MDI) 應用程式會顯示在應用程式主視窗工作區內的個別子視窗中。 典型的 MDI 應用程式包括文字處理應用程式,可讓使用者使用多個文字檔,以及允許使用者使用多個圖表和試算表的試算表應用程式。 如需詳細資訊,請參閱下列主題。

框架、用戶端和子視窗

MDI 應用程式有三種視窗:框架視窗、MDI 用戶端視窗,以及一些子視窗。 框架視窗就像應用程式的主視窗:其具有調整大小框線、標題列、視窗功能表、最小化按鈕,以及最大化按鈕。 應用程式必須註冊框架視窗的視窗類別,並提供視窗程式來支援它。

MDI 應用程式不會在框架視窗的工作區中顯示輸出。 相反地,它會顯示 MDI 用戶端視窗。 MDI 用戶端視窗是屬於預先註冊視窗類別MDICLIENT的特殊子視窗類型。 用戶端視窗是框架視窗的子視窗;它會作為子視窗的背景。 它也支援建立和管理子視窗。 例如,MDI 應用程式可以藉由將訊息傳送至 MDI 用戶端視窗來建立、啟用或最大化子視窗。

當使用者開啟或建立檔時,用戶端視窗會建立檔的子視窗。 用戶端視窗是應用程式中所有 MDI 子視窗的父視窗。 每個子視窗都有調整大小框線、標題列、視窗功能表、最小化按鈕,以及最大化按鈕。 因為子視窗已裁剪,所以會限制在用戶端視窗,而且不能出現在它外部。

MDI 應用程式可以支援一種以上的檔。 例如,典型的試算表應用程式可讓使用者同時使用圖表和試算表。 針對它支援的每個檔案類型,MDI 應用程式必須註冊子視窗類別,並提供視窗程式來支援屬於該類別的視窗。 如需視窗類別的詳細資訊,請參閱 視窗類別。 如需視窗程式的詳細資訊,請參閱 視窗程式

以下是典型的 MDI 應用程式。 它名為 Multipad。

多板 mdi 應用程式框架視窗和用戶端視窗

子視窗建立

若要建立子視窗,MDI 應用程式會呼叫 CreateMDIWindow 函式,或將 WM_MDICREATE 訊息傳送至 MDI 用戶端視窗。 建立 MDI 子視窗更有效率的方式是呼叫 CreateWindowEx 函式,並指定 WS_EX_MDICHILD 擴充樣式。

若要終結子視窗,MDI 應用程式會將 WM_MDIDESTROY 訊息傳送至 MDI 用戶端視窗。

子視窗啟用

任何一次都可以在用戶端視窗中顯示任意數目的子視窗,但只有一個可以作用中。 作用中的子視窗位於所有其他子視窗前面,並反白顯示其框線。

使用者可以按一下它來啟動非作用中的子視窗。 MDI 應用程式會將 WM_MDIACTI加值稅E 訊息傳送至 MDI 用戶端視窗,以啟動子視窗。 當用戶端視窗處理此訊息時,它會將 WM_MDIACTI加值稅E 訊息傳送至要啟動之子視窗的視窗程式,以及要停用之子視窗的視窗程式。

若要防止子視窗啟動,請傳回FALSE來處理子視窗的WM_NCACTI加值稅E訊息。

系統會追蹤重迭視窗堆疊中每個子視窗的位置。 此堆疊稱為 Z-Order。 使用者可以從使用中視窗的視窗功能表按一下 [ 下一步], 以 Z 順序啟動下一個子視窗。 應用程式會藉由將 WM_MDINEXT 訊息傳送至用戶端視窗,以 Z 順序啟動下一個 (或上一個) 子視窗。

若要擷取使用中子視窗的控制碼,MDI 應用程式會將 WM_MDIGETACTIVE 訊息傳送至用戶端視窗。

多個檔功能表

MDI 應用程式的框架視窗應該包含具有視窗功能表的功能表列。 視窗功能表應該包含在用戶端視窗內排列子視窗或關閉所有子視窗的專案。 一般 MDI 應用程式的視窗功能表可能包含下表中的專案。

功能表項目 目的
圖格 以磚格式排列子視窗,讓每個視窗在用戶端視窗中全部顯示。
Cascade 以串聯格式排列子視窗。 子視窗彼此重迭,但每個專案的標題列都是可見的。
排列圖示 沿著用戶端視窗底部排列最小化子視窗的圖示。
全部關閉 關閉所有子視窗。

 

每當建立子視窗時,系統會自動將新的功能表項目附加至視窗功能表。 功能表項目的文字與新子視窗功能表列上的文字相同。 按一下功能表項目,使用者可以啟動對應的子視窗。 當子視窗終結時,系統會自動從視窗功能表移除對應的功能表項目。

系統最多可以將十個功能表項目新增至視窗功能表。 建立第十個子視窗時,系統會將 [更多 Windows] 專案新增至視窗功能表。 按一下此專案會顯示 [ 選取視窗] 對話方塊。 對話方塊包含清單方塊,其中包含目前可用的所有 MDI 子視窗標題。 使用者可以按一下清單方塊中的標題來啟動子視窗。

如果您的 MDI 應用程式支援數種類型的子視窗,請量身打造功能表列以反映與使用中視窗相關聯的作業。 若要這樣做,請為應用程式支援的每種子視窗類型提供個別的功能表資源。 啟用新類型的子視窗時,應用程式應該將 WM_MDISETMENU 訊息傳送至用戶端視窗,並將控制碼傳遞給對應的功能表。

當沒有任何子視窗存在時,功能表列應該只包含用來建立或開啟檔的專案。

當使用者使用方向鍵流覽 MDI 應用程式的功能表時,索引鍵的行為會與使用者流覽一般應用程式的功能表不同。 在 MDI 應用程式中,控制項會從應用程式的視窗功能表傳遞至使用中子視窗的視窗功能表,然後傳遞至功能表列上的第一個專案。

多個檔加速器

若要接收和處理其子視窗的快速鍵,MDI 應用程式必須在其訊息迴圈中包含 TranslateMDISysAccel 函式。 迴圈必須先呼叫 TranslateMDISysAccel才能呼叫 TranslateAcceleratorDispatchMessage 函式。

MDI 子視窗之視窗功能表上的快速鍵與非 MDI 子視窗的快速鍵不同。 在 MDI 子視窗中,ALT+ – (減去) 鍵組合會開啟視窗功能表、CTRL+F4 按鍵組合會關閉作用中的子視窗,而 CTRL+F6 鍵組合會啟動下一個子視窗。

子視窗大小和相片順序

MDI 應用程式會傳送訊息至 MDI 用戶端視窗,以控制其子視窗的大小和位置。 為了最大化作用中的子視窗,應用程式會將 WM_MDIMAXIMIZE 訊息傳送至用戶端視窗。 當子視窗最大化時,其工作區會完全填滿 MDI 用戶端視窗。 此外,系統會自動隱藏子視窗的標題列,並將子視窗的視窗功能表圖示和 [還原] 按鈕新增至 MDI 應用程式的功能表列。 應用程式可以將用戶端視窗還原為其原始 (預先初始化) 大小和位置,方法是將用戶端視窗傳送 WM_MDIRESTORE 訊息。

MDI 應用程式可以使用串聯或磚格式排列其子視窗。 當子視窗重迭時,視窗會出現在堆疊中。 堆疊底部的視窗會佔用螢幕的左上角,其餘視窗會垂直和水準位移,讓每個子視窗的左框線和標題列都可見。 若要以串聯格式排列子視窗,MDI 應用程式會傳送 WM_MDICASCADE 訊息。 一般而言,當使用者按一下視窗功能表上的 [串聯 ] 時,應用程式就會傳送此訊息。

當子視窗並排顯示時,系統會以整個方式顯示每個子視窗,這不會重迭任何視窗。 所有視窗都會視需要調整大小,以符合用戶端視窗的大小。 若要以磚格式排列子視窗,MDI 應用程式會將 WM_MDITILE 訊息傳送至用戶端視窗。 一般而言,當使用者按一下視窗功能表上的 [磚 ] 時,應用程式就會傳送此訊息。

MDI 應用程式應該為它支援的每個子視窗類型提供不同的圖示。 應用程式會在註冊子視窗類別時指定圖示。 當子視窗最小化時,系統會自動在用戶端視窗的下半部顯示子視窗的圖示。 MDI 應用程式會將 WM_MDIICONARRANGE 訊息傳送至用戶端視窗,引導系統排列子視窗圖示。 一般而言,當使用者按一下視窗功能表上的 [ 排列圖示 ] 時,應用程式就會傳送此訊息。

圖示標題視窗

因為 MDI 子視窗可能最小化,所以 MDI 應用程式必須避免操作圖示標題視窗,就像是一般的 MDI 子視窗一樣。 當應用程式列舉 MDI 用戶端視窗的子視窗時,會出現圖示標題視窗。 不過,圖示標題視窗與其他子視窗不同,在於它們是由 MDI 子視窗所擁有。

若要判斷子視窗是否為圖示標題視窗,請使用 GetWindow 函式搭配GW_OWNER索引。 非標題視窗會傳回 Null。 請注意,此測試不適用於最上層視窗,因為功能表和對話方塊是擁有的視窗。

子視窗資料

因為子視窗數目會根據使用者開啟的檔數目而有所不同,所以 MDI 應用程式必須能夠關聯資料 (,例如,目前檔案的名稱會與每個子視窗) 關聯。 作法有二:

  • 將子視窗資料儲存在視窗結構中。
  • 使用視窗屬性。

視窗結構

當 MDI 應用程式註冊視窗類別時,它可能會針對這個特定視窗類別特定的應用程式資料,在視窗結構中保留額外的空間。 若要在此額外空間中儲存和擷取資料,應用程式會使用 GetWindowLongSetWindowLong 函式。

若要維護子視窗的大量資料,應用程式可以配置資料結構的記憶體,然後將包含結構之記憶體的控制碼儲存在與子視窗相關聯的額外空間中。

視窗屬性

MDI 應用程式也可以使用視窗屬性來儲存個別檔的資料。 個別檔資料 是特定子視窗中所包含檔案類型的特定資料。 屬性與視窗結構中的額外空間不同,您在註冊視窗類別時不需要配置額外的空間。 視窗可以有任意數目的屬性。 此外,當位移用來存取視窗結構中的額外空間時,屬性會以字串名稱來參考。 如需視窗屬性的詳細資訊,請參閱 視窗屬性