前面有講到MFC文檔視圖架構中比較關鍵的5個類.CWinApp,CDocument,CView,CFrameWnd,CSingleDocTemplate
程式一啟動,5個類就全部有被執行個體化.不過代碼中只能看到CWinApp和CSingleDocTemplate兩個類的執行個體化.其他3個封裝在一些父類的操作中,我們看不到了.也不用去管.只管拿來用就行.我們知道類一旦執行個體化之後就被調用對象的成員變數和函數了.
5個類之間的關係
1.CWinApp 建立CSingleDocTemplate,並有一個指標指向它
2.CSingleDocTemplate 建立CDocument,和CFrameWnd,並有兩個指標分別指向它們
3.CFrameWnd 建立CView,並有指標指向它
4.CDocument 中有指標指向CView
5.CView 類中有指標指向CDocument
windows的上的程式運行是基於訊息處理的.也就是沒有啥訊息傳過來(比如用滑鼠去點它或鍵盤操作發送訊息過去)那程式就靜靜的呆那裡不動的.而一有訊息來了就調用某個函數去處理,去處理訊息的函數叫回調(callback)函數,是由作業系統而不是應用程式自己去調用該函數.
訊息分類
windows訊息分為三類
1.標準訊息:
除WM_COMMAND之外所有以WM開頭的訊息.比如WM_CREATE,在MFC中就對應的宏是ON_WM_CREATE();
2.命令訊息
來自功能表列,快速鍵,工具列按鈕的訊息.MFC中對應的宏是ON_COMMAND(ID_XXX, CallBackFunction);
例如ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
3.通知訊息:
由控制項產生的訊息.
有時也把2,3類訊息統稱為非標準訊息.
只有繼承自CWnd的類可以處理標準訊息.(2,3類訊息自然也能處理).CView和CFrameWnd就是繼承自CWnd.
繼承自CCmdTarget的類可以處理第2和第3類訊息.我們前面講到5種關鍵的類都是繼承自CCmdTarget.
5種常見標準訊息
常見的標準訊息有WM_CREATE, WM_CLOSE, WM_DESTROY, WM_SIZE, WM_PAINT
標準訊息只能由繼承自CWnd的類處理.上面的訊息涉及到視窗的建立,關閉,銷毀,視窗大小調整,顏色調整.
像CView,CFrameWnd, CDialog類都是一個個的視窗,它們建立和關閉肯定是由自己來處理.在MFC中通過一些宏指定一個函數來處理這些訊息.
標準訊息在MFC中的處理
1.WM_CREATE
對應宏ON_WM_CREATE(), 然後寫個函數afx_msg void OnCreate()來做相應的處理,注意這個函數名是定了的,可不能改的.
該訊息是指視窗建立(實際上是顯示之前)時發出,所以OnCreate就是在視窗顯示之前做些初始化設定.視窗的建立應該是執行個體化一個視窗類別,debug時看到肯定是先調用建構函式,然後才調用到OnCreate函數的
2.WM_CLOSE
對應宏ON_WM_CLOSE(),再定義個函數afx_msg void OnClose();
3.WM_DESTROY.
對應宏ON_WM_DESTROY(),再定義個函數afx_msg void OnDestroy();
OnClose與OnDestroy關係
close是關閉視窗,destroy是銷毀視窗.關閉視窗跟隱藏視窗很類似(只不過完全看不到了,但擁有的資源沒被釋放).destroy是真正的銷毀視窗釋放資源.
一般的調用順序是這樣:
(1).使用者點擊關閉發送WM_CLOSE訊息,然後OnClose函數做相應處理,例如你可能彈出對話方塊問使用者是否確定關閉不.如果點否定就沒關閉視窗又返回原樣.如果確定則調用DestroyWindows().
(2).DestroyWindows中發送WM_DESTROY訊息
(3).處理WM_DESTROY訊息,並調用PostQuitMessage(),發送WM_QUIT訊息.結束訊息迴圈.
所以要讓一個視窗正常銷毀可以先調用OnClose然後接著接著一連串處理,也可以不調用它直接調用OnDestroy.
4.WM_SIZE
視窗大小改變時發出的訊息.對應的宏是ON_WM_SIZE().對應的處理函數是
afx_msg void OnSize(UINT nType, int cx, int cy);
其中cx,cy自然是視窗的橫座標與縱座標.nType指視窗改變時的類型,比如有SIZE_MAXIMIZED 就是指視窗被最大化.
5.WM_PAINT
對應的宏是ON_WM_PAINT,對應的處理函數是afx_msg void OnPaint();
OnSize是指改變視窗大小,OnPaint就是處理顏色相關的操作.OnSize的操作一般會調用RedrawWindow,它再發出一個WM_PAINT訊息.