MFC學習記錄1
一、MFC六大關鍵技術
1、MFC初始化----尋找main函數
C++規定,全局對象的構造將比main或WinMain函數更早。
首先是全局構造
CObject構造函數 -> CCmdTarget -> CWinThread -> CWinApp -> theApp構造函數
然后進入WinMain函數
WinMain -> AfxWinMain -> AfxWinInit -> theApp.InitApplication -> theApp.InitInstance
接著執行線程過程。
theApp.Run()
最后清理
AfxWinTerm
2、執行時類型識別(RTTI)-- -- 查詢父子關系(true or false)
CRuntimeClass的實現要通過幾個復雜的宏DECLARE_DYNAMIX(Cxxx)和IMPLEMENT_DYNAMIC(Cxxx,Cxxxbase),在類內部聲明這兩個宏,就可以將該類加入到類型識別庫。而CObject的函數IsKindOf()則可以指向任何派生至CObject的類,然后調用它就可以找到基類。
3、動態生成(Dynamic Creation) ----- 如何從文件中讀取一個類并實現它
動態生成也通過CRuntimeClass來實現,加入兩個成員變量,并通過宏來實現。DECLARE_DYNCREATE 和IMPLEMENT_DYNCREATE 。
4、永久保存(Persistence) -- -- 將對象寫入到文件(Serialize)
這需要用到宏DECLARE_SERIAL / IMPLEMENT_SERIAL,以及CObject的虛函數 virtual void Serialize(CArchive& ar);
5 、消息映射(Message Mapping)---- 消息如何獲取
宏DECLARE_MESSAGE_MAP / BEGIN_MESSAGE_MAP / END_MESSAGE_MAP
6、命令繞行(Command Routing)---- 消息流動方向
一般Window消息(WM_xxx),一定是從子類流向父類,不可能旁流。
命令消息WM_COMMAND 的消息流向比較另類,可以橫向流動。
二、MFC生死因果
程序的誕生:
Application object 產生,內存于是獲得配置,初值亦設立了。
Afx WinMain 執行AfxWinInit,后者又調用AfxInitThread,把消息隊列盡量加大到96。
Afx WinMain 執行InitApplication。這是CWinApp 的虛擬函數,但我們通常不改寫它。
AfxWinMain 執行InitInstance。這是CWinApp 的虛擬函數,我們必須改寫它。
CMyWinApp::InitInstance 'new' 了一個CMyFrameWnd 對象。
CMyFrameWnd 構造式調用Create,產生主窗口。我們在Create 參數中指定的窗口類別是NULL, 于是MFC 根據窗口種類, 自行為我們注冊一個名為"AfxFrameOrView42d" 的窗口類別。
回到InitInstance 中繼續執行ShowWindow,顯示窗口。
執行UpdateWindow,于是發出WM_PAINT。
回到AfxWinMain,執行Run,進入消息循環。
程序開始運作:
程序獲得WM_PAINT 消息(藉由CWinApp::Run 中的::GetMessage 循環)。
WM_PAINT 經由::DispatchMessage 送到窗口函數CWnd::DefWindowProc 中。
CWnd::DefWindowProc 將消息繞行過消息映射表格(Message Map)。
繞行過程中發現有吻合項目,于是調用項目中對應的函數。此函數是應用程序利用BEGIN_MESSAGE_MAP 和END_MESSAGE_MAP 之間的宏設立起來的。
標準消息的處理例程亦有標準命名,例如WM_PAINT 必然由OnPaint 處理。程序的死亡:
使用者選按【File/Close】,于是發出WM_CLOSE。
CMyFrameWnd 并沒有設置WM_CLOSE 處理例程,于是交給預設之處理例程。
預設函數對于WM_CLOSE 的處理方式是調用::DestroyWindow, 并因而發出WM_DESTROY。
預設之WM_DESTROY 處理方式是調用::PostQuitMessage,因此發出WM_QUIT。
CWinApp::Run 收到WM_QUIT 后會結束其內部之消息循環, 然后調用ExitInstance,這是CWinApp 的一個虛擬函數。
如果CMyWinApp 改寫了ExitInstance , 那么CWinApp::Run 所調用的就是CMyWinApp::ExitInstance,否則就是CWinApp::ExitInstance。
最后回到AfxWinMain,執行AfxWinTerm,結束程序。

三、Document-View
1、Document
Document 在MFC 的CDocument 里頭被具體化。CDocument 本身并無任何具體數據,它只是提供一個空殼。當你開發自己的程序,應該從CDocument 衍生出一個屬于自己的Document 類別,并且在類別中聲明一些成員變量,用以承載(容納)數據。然后再(至少)改寫專門負責文件讀寫動作的Serialize 函數。應為他派生至CObject,所有它有CObject 所支持的一切性質,包括執行時期型別信息(RTTI)、動態生成(Dynamic Creation)、文件讀寫(Serialization)。
2、View
View 負責描述Document中的資料,也是在在MFC 的CView 里頭被具體化。它只是提供一個空殼。當你開發自己的程序,應該從CView 衍生出一個屬于自己的View 類別,并且在類別中(至少)改寫專門負責顯示資料OnDraw 函數(針對屏幕)或OnPrint 函數(針對打印機)。由于CView 衍生自CWnd,所以它可以接收一般Windows 消息(如WM_SIZE、WM_PAINT 等等),又由于它也衍生自CCmdTarget,所以它可以接收來自菜單或工具列的WM_COMMAND 消息。
3、Frame
框架窗口在Document/View之上,主要管理UI。
4、 Document Template
MFC 把Document/View/Frame 視為三位一體。其中用 Document Template來管理這個"三人組合"。MFC 有一個CDocTemplate 負責管理。

浙公網安備 33010602011771號