mfc單文件程式架構解析
這裡我以科院楊老師的單文件程式來分析一下mfc單文件的程式架構,純屬個人見解,不當之處煩請指教!
首先我們了解到的是
圖(一)
圖(二)
csingledoctemplate* pdoctemplate;
pdoctemplate = new csingledoctemplate(
idr_mainframe,
runtime_class(cmainframe), // main sdi frame windon
這裡體現了幾個重要的思想,第一動態建立和動態附加的一種思想,runtime_class是乙個巨集定義,這裡不做展開,可以理解為最後的函式返回了實現了如下的語句
retrun new cmainframw 的功能,這裡將三個不同的類物件附加到csingledoctemplate物件中,這樣使得整個程式得以整體成立。
接下來對剩下的三個類物件做分析
1. cmainframe類
cmianframe類作為程式的框架類,其起到了一種容器的作用,在這個容器當中可以裝在多個檢視,選單,工具等。要注意的有幾點,第一,因為
mianfram
是沒有檢視的,因此如果在
mainframe
相應onpaint
訊息,自然是可以響應這個訊息的,但是你會驚奇的發現,在你的繪製當中如何也不會出現你預想出現的繪製內容,為什麼呢? 嘿嘿,可以想象一下你在乙個
word
程式裡面,當你關閉了所有的白板(檢視)的時候,你會發現你已經無法在編寫文字,道理是一樣的,在
mainframe
裡面進行繪製,程式是沒有問題,但是繪製的內容是在灰色上面,
windows
不予顯示的。
第二點你可以發現在對選單,和工具條的單擊訊息進行相應的時候你可以將訊息響應函式新增到cmainframe
也沒有將訊息響應函式調價到
cview
當中,但是你會驚奇的發現,兩者只在乙個地方相應的時候,訊息響應函式沒有問題都能正確的執行,但是如果同時對乙個按鈕或者選單進行單擊訊息響應的時候,你會發現
windows
會執行的
cview
裡面的訊息響應函式。分析兩者之間的關係,首先
cmianframe
的繼承關係如下:
而對cview類而言其繼承類關係如下圖所示:
可以看出兩個類之間並沒有直接的關係,但是我們通過程式的執行可以知道訊息的響應是以cview中為主的,可以認為存在一種類似於多型的關係。
這裡具體的訊息路徑如下:
同時cmainframe作為整個程式的框架,它提供了程式執行的基礎環境,這裡再強調介紹一下兩點
1. 在cmainframe中訪問
cview物件和
cdoc物件
要訪問這兩個物件可以使用全域性函式getactivedocument()和getactiveview()這樣可以獲得doc
物件和view
物件的實體了
2. 在cmainframe中呼叫
cview物件更新視窗,這裡使用方法如下:getactiveview()->invalidate(false);// 這一句會是
cview
呼叫ondraw
訊息響應函式
getactiveview()->updatewindow();//這句可以加上也可以不加,暫時沒有發現不加會出現什麼問題。
2.cview類
cview類作為檢視類,其可以理解為一張畫布,在這張畫布上可以畫圖,也可以畫控制項,其重要的函式有
ondraw
這是主要繪圖出現的地方。在
view
中要實現重畫的時候可以按如下方式實現呼叫:
void ctestview::onchangerect()
// on draw function draws the rectangle.
void ctestview::ondraw(cdc* pdc)
在cview內中要獲取到
cmianframe
可以使用下面的函式:
afxgetmainwnd()
3.doc類物件。
個人覺得單文件檢視的設計模式很接近mvc的設計模式,model層可以粗略的認為是在doc這個類物件裡面,在單文件檢視當中doc物件充當的也是資料儲存的類,可見確實是有一些mvc設計模式的意思。這裡介紹在其他類中要獲取doc物件的方法
在cmianframe中可以使用
getactivedocument()
在cview
類中可以使用
這裡要注意一點,在cview類中包含了乙個cdocument的物件m_pdocument這個物件即使指向doc
類的基類物件的,而要實現基類物件到現在
doc類物件的轉換只要新增如下函式即可
則可以實現。
附上三個類物件相互訪問方法:
1、主框架
(cframewnd)
中訪問檢視
(cview)
cview* getactiveview() const;
通常定義的檢視為cview
的派生類,在呼叫自定義檢視物件的方法時
應該這樣寫:((cmousekeyview*)getactiveview())->myfunc();
2、主框架
(cframewnd)
中訪問文件
(cdocument)
getactivedocument,返回
cdocument
物件;3、在檢視
(cview)
中訪問文件
(cdocument)
inline cmousekeydoc* cmousekeyview::getdocument()
4、在檢視
(cview)
中訪問框架
(cframewnd)
cframewnd* getparentframe() const;
這裡修改一下,因為上述**獲取的只是cmainframe
的父類物件
cframewnd
物件,要獲取實際的
cmainframe
物件可以進行如下操作首先在標頭檔案中新增#include "mainfrm.h" 然後**如下:
cmainframe* frm=(cmainframe*)::afxgetmainwnd();frm->test(); 就能成功咯
5、在文件
(cdocument)
中訪問框架
(cframewnd)
6、在文件
(cdocument)
中訪問檢視
(cview)
updateallviews
功能:通知所有的視**檔已被修改的資訊
原型:void updateallviews(
cview* psender, // 要更新的檢視指標,如果希望更新所有視
圖,將此引數設為null
lparam lhint=0l, // 包含更改訊息的通知
cobject* phint=null // 保管更改訊息的物件
}7、在其他類中訪問文件類
(cdocument)
cdocument* getdocument()
MFC單文件程式架構解析
首先我們了解到的是 圖 一 圖 二 csingledoctemplate pdoctemplate pdoctemplate new csingledoctemplate idr mainframe,runtime class cmainframe main sdi frame windon 這裡體...
MFC單文件程式架構解析
mfc單文件程式架構解析 這裡我以科院楊老師的單文件程式來分析一下mfc單文件的程式架構,純屬個人見解,不當之處煩請指教!首先我們了解到的是 圖 一 圖 二 csingledoctemplate pdoctemplate pdoctemplate new csingledoctemplate idr...
MFC學習(七) 單文件程式
1 mfc單文件程式的主要類 1 文件類 document 即應用程式處理的資料物件,文件一般從 mfc 中 cdocument 中派生。cdocument 類用於相應資料檔案的讀取以及儲存 cview 類所需要觀察和處理的資訊。2 視類 view 視相當於文件在應用程式中的觀察視窗,它確定了使用者...