複製鏈接
請複製以下鏈接發送給好友

MDI

(多文檔界面)

鎖定
MDI(Multiple Document Interface)多文檔界面,與此對應就有單文檔界面 (SDI), 它是微軟公司從Windows 2.0下的MicrosoftExcel電子表格程序開始引入的,Excel電子表格用户有時需要同時操作多份表格,MDI正好為這種操作多表格提供了很大的方便,於是就產生了MDI程序。
用AppWizard產生一個MDI工程t(無OLE等支持),AppWizard創建了一系列文件,構成了一個應用程序框架。這些文件分四類:頭文件(.h),實現文件(.cpp),資源文件(.rc),模塊定義文件(.def),等。
構成應用程序的對象
圖1-1解釋了該應用程序的結構,箭頭表示信息流向。
從CWinApp、CDocument、CView、CMDIFrameWnd、CMDIChildWnd類對應地派生出CTApp、CTDoc、CTView、CMainFrame、CChildFrame五個類,這五個類的實例分別是應用程序對象、文檔對象、視對象、主框架窗口對象和文檔邊框窗口對象。主框架窗口包含了視窗口、工具條和狀態欄。對這些類或者對象解釋如下。
(1)應用程序
應用程序類派生於CWinApp。基於框架的應用程序必須有且只有一個應用程序對象,它負責應用程序的初始化、運行和結束。
(2)邊框窗口
如果是SDI應用程序,從CFrameWnd類派生邊框窗口類,邊框窗口的客户子窗口(MDIClient)直接包含視窗口;如果是MDI應用程序,從CMDIFrameWnd類派生邊框窗口類,邊框窗口的客户子窗口(MDIClient)直接包含文檔邊框窗口。
如果要支持工具條、狀態欄,則派生的邊框窗口類還要添加CToolBar和CStatusBar類型的成員變量,以及在一個OnCreate消息處理函數中初始化這兩個控制窗口。
邊框窗口用來管理文檔邊框窗口、視窗口、工具條、菜單、加速鍵等,協調半模式狀態(如上下文的幫助(SHIFT+F1模式)和打印預覽)。
(3)文檔邊框窗口
文檔邊框窗口類從CMDIChildWnd類派生,MDI應用程序使用文檔邊框窗口來包含視窗口。
(4)文檔
文檔類從CDocument類派生,用來管理數據,數據的變化、存取都是通過文檔實現的。視窗口通過文檔對象來訪問和更新數據。
(5)視
視類從CView或它的派生類派生。視和文檔聯繫在一起,在文檔和用户之間起中介作用,即視在屏幕上顯示文檔的內容,並把用户輸入轉換成對文檔的操作。
(6)文檔模板
文檔模板類一般不需要派生。MDI應用程序使用多文檔模板類CMultiDocTemplate;SDI應用程序使用單文檔模板類CSingleDocTemplate。
應用程序通過文檔模板類對象來管理上述對象(應用程序對象、文檔對象、主邊框窗口對象、文檔邊框窗口對象、視對象)的創建。
構成應用程序的對象之間的關係
這裏,用圖的形式可直觀地表示所涉及的MFC類的繼承或者派生關係,如圖1-2所示意。
圖1-2所示的類都是從CObject類派生出來的;所有處理消息的類都是從CCmdTarget類派生的。如果是多文檔應用程序,文檔模板使用CMultiDocTemplae,主框架窗口從CMdiFarmeWnd派生,它包含工具條、狀態欄和文檔框架窗口。文檔框架窗口從CMdiChildWnd派生,文檔框架窗口包含視,視從CView或其派生類派生。
構成應用程序的文件
通過上述分析,可知AppWizard產生的MDI框架程序的內容,所定義和實現的類。下面,從文件的角度來考察AppWizard生成了哪些源碼文件,這些文件的作用是什麼。表1-1列出了AppWizard所生成的頭文件,表1-2列出了了AppWizard所生成的實現文件及其對頭文件的包含關係。
表1-1 AppWizard所生成的頭文件
頭文件
用途

stdafx.h
標準AFX頭文件

resource.h
定義了各種資源ID

t.h
#include "resource.h"定義了從CWinApp派生的應用程序對象CTApp


childfrm.h
定義了從CMDIChildWnd派生的文檔框架窗口對象CTChildFrame

mainfrm.h
定義了從CMDIFrameWnd派生的框架窗口對象CMainFrame

tdoc.h
定義了從CDocument派生的文檔對象CTDoc

tview.h
定義了從CView派生的視圖對象CTView

表1-2 AppWizard所生成的實現文件
實現文件
所包含的頭文件
實現的內容和功能
stdafx.cpp
#include "stdafx.h"
用來產生預編譯的類型信息。
t.cpp
# include "stdafx.h"# include "t.h"# include "MainFrm.h"# include "childfrm.h"#include "tdoc.h"#include "tview.h"
定義CTApp的實現,並定義CTApp類型的全局變量theApp。
childfrm.cpp
#inlcude "stdafx.h"#include "t.h"#include “childfrm.h”
實現了類CChildFrame
childfrm.cpp
#inlcude "stdafx.h"#include "t.h"#include "childfrm.h"
實現了類CMainFrame
tdoc.cpp
# include "stdafx.h"# include "t.h"# include "tdoc.h"
實現了類CTDoc
tview.cpp
# include "stdafx.h"# include "t.h"# include "tdoc.h"# include "tview.h"
實現了類CTview
從表1-2中的包含關係一欄可以看出:
CTApp 的實現用到所有的用户定義對象,包含了他們的定義;CView 的實現用到CTdoc;其他對象的實現只涉及自己的定義;
當然,如果增加其他操作,引用其他對象,則要包含相應的類的定義文件。
對預編譯頭文件説明如下:
所謂頭文件預編譯,就是把一個工程(Project)中使用的一些MFC標準頭文件(如Windows.H、Afxwin.H)預先編譯,以後該工程編譯時,不再編譯這部分頭文件,僅僅使用預編譯的結果。這樣可以加快編譯速度,節省時間。
預編譯頭文件通過編譯stdafx.cpp生成,以工程名命名,由於預編譯的頭文件的後綴是“pch”,所以編譯結果文件是projectname.pch。
編譯器通過一個頭文件stdafx.h來使用預編譯頭文件。stdafx.h這個頭文件名是可以在project的編譯設置裏指定的。編譯器認為,所有在指令#include "stdafx.h"前的代碼都是預編譯的,它跳過#include "stdafx. h"指令,使用projectname.pch編譯這條指令之後的所有代碼。
因此,所有的CPP實現文件第一條語句都是:#include "stdafx.h"。
另外,每一個實現文件CPP都包含了如下語句:
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
這是表示,如果生成調試版本,要指示當前文件的名稱。__FILE__是一個宏,在編譯器編譯過程中給它賦值為當前正在編譯的文件名稱。