国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

《深入淺出MFC》– Document-View深入探討

2019-11-08 02:28:36
字體:
來源:轉載
供稿:網友

1.其實Document/View不是什么新東西,Xerox PARC實驗室是這種觀念的濫觴。它是Smalltalk環境中的關鍵性部分,在那里它被稱為Model-View-Controller(MVC)。其中的Model就是MFC的Document,而Controller相當于MFC的Document Template。

 

2.Document在MFC的CDocument里頭被實例化。CDocument本身并無實際用途,他只是提供一個空殼。你應該從它派生一個自己的類,然后改寫負責文件讀寫操作的Serilize函數。由于CDocument派生自CObject,所以他就有了CObject所支持的一切性質,包括RTTI、動態創建、文件讀寫。又由于它也派生自CCmdTarget,所以它可以接受來自菜單或工具欄的WM_COMMAND消息。

 

3.View負責呈現Document中的數據。

View在MFC的CView里頭被實例化,同樣應該派生屬于自己的View類,并且在類中改寫專門負責顯示數據的OnDraw函數或OnPRint函數。由于CView派生自CWnd,所以它可以接收一般的Windows消息,又由于它也派生自CCmdTarget,所以它可以接受來自菜單或工具欄的WM_COMMAND消息。

在MFC中,一旦WM_PAINT發生,Framework會自動調用OnDraw函數,View事實上是個沒有邊框的窗口。真正出現時,其外圍還有一個有邊框的窗口,我們稱之為Frame窗口。

 

4.Document Frame(View Frame)

你可能愿意在使用者操作TEXT數據時,換一套TEXT專用的使用者界面,在使用者操作BITMAP數據時,換一套BITMAP專用的使用者界面。這份工作正式Frame窗口負責。

 

5.Document Template

每當使用者欲打開一份文件,程序應該做出Document、View、Frame各一份。這三個成為一個運行單元,由所謂的Document Template掌管。MFC有一個CDocTemplate負責此事,他又有兩個派生類,分別是CMultiDocTemplate和CSingleDocTemplate。如果你的程序能夠處理兩中數據類型,你必須制造兩個Document Template,并使用AddDocTemplate函數將他們一一加入系統之中。

 

6.誰來管理Document Template呢?是CWinApp。來看看InitInstance中應有的相關行為:

CMultiDocTemplate* pDocTemplate;pDocTemplate = new CMultiDocTemplate(    IDR_MFCTYPE,    RUNTIME_CLASS(CMfcDoc),    RUNTIME_CLASS(CChildFrame), // custom MDI child frame    RUNTIME_CLASS(CMfcView));AddDocTemplate(pDocTemplate);

Document Template產生Document/View/Frame的行動:

image7.當使用者單機File/New命令項,這一命令由CWinApp::OnFileNew接手處理。然后調用CDocManager::OnFileNew->CMultiDocTemplate::OpenDocumentFile.

在OpenDocumentFile中CreateNewDocument動態產生Document,CreateNewFrame動態產生Document Frame。在CreateNewFrame中,不僅Frame被動態創建出來了,其對應窗口也以LoadFrame產生出來了。Document Frame窗口產生之際由于WM_CREATE的產生引發CFrameWnd::OnCreate被喚起。

image不僅View對象被動態創建出來了,其對應的實際Windows窗口也以Create函數產生出來。

 

8.CDocTemplate、CDocument、CView、CFrameWnd 之間的關系

①CWinApp 擁有一個對象指針:CDocManager* m_pDocManager。

②CDocManager 擁有一個指標串行 CPtrList m_templateList, 用來維護一系列的 Document Template。一個程序若支持兩「種」文件型態,就應該有兩份Document Templates,應用程序應該CMyWinApp::InitInstance 中以 AddDocTemplate 將這些 Document Templates 加入由 CDocManager 所維護的鏈表之中。

③CDocTemplate 擁有三個成員變數, 分別持有 Document 、View、Frame 的 CRumtimeClass 指針,另有一個成員變量 m_nIDResource,用來表示此 Document 顯現時應該采用的 UI 對象。這四份數據應該在 CMyWinApp::InitInstance 函數 建構 CDocTemplate(注1)時指定之,成為建構式的參數。當使用者欲打開一 份文件(通常是借著【File/Open】或【File/New】命令項),CDocTemplate 即可借由 Document/View/Frame 之CRuntimeClass 指標(注2)進行動態生成。

注1:在此我們必須有所選擇,要不就使用 CSingleDocTemplate,要不就使用 CMultiDocTemplate , 兩者都是 CDocTemplate 的衍生類別。如果你選用 CSingleDocTemplate,它有一個成員變數 CDocument* m_pOnlyDoc,亦即它一次只能打開一份 Document。如果你選用 CMultiDocTemplate,它有一個成員變數 CPtrList m_docList,表示它能同時打開多個 Documents。

④CDocument 有一個成員變數 CDocTemplate* m_pDocTemplate,回指其Document Template;另有一個成員變量 CPtrList m_viewList,表示它可以同時維護一系列的 Views。

⑤CFrameWnd 有一個成員變量 CView* m_pViewActive, 指向目前正作用中的View。

⑥CView 有一個成員變量 CDocument* m_pDocument,指向相關的 Document。

image9.MFC Collection Classes

imageMFC Collection classes所支持的對象中,有兩種特別需要說明,一是Ob,一是Ptr:

①Ob表示派生自CObject的任何對象。MFC提供CObList、CObArray兩種類。

②Ptr表示對象指針。MFC提供CPtrList、CPtrArray兩種類。

 

10.Serializable的必要條件

欲讓一個對象有Serialize能力,它必須派生自一個Serializable類。一個類意欲成為Serializable,必須有下列五大條件;

        1.  從CObject派生下來。如此一來可保有RTTI、DynamicCreation等機能。

        2.  類的聲明部分必須有DECLARE_SERIAL宏。此宏需要一個參數:類名稱。

        3.  類的實現部分必須有IMPLEMENT_SERIAL宏。此宏需要三個參數:一是類名稱,三是schema no.。

        4.  改寫Serialize虛函數,使它能夠適當地把類的成員變量寫入文件中。

        5.  為經類加上一個default構造函數(也就是無參數之構造函數)。這個條件常為人所忽略,但它是必要的,因為若一個對象來自文件,MFC必須先動態創建它,而且在沒有任何參數的情況下調用其構造函數,然后才從文件中讀出對象數據。

一個類若要能夠進行Serializable操作,必須準備Serialize函數,并且在“類別型錄網”中自己的那個CRuntimeClass元素里的schema字段里設置0xFFFF以外的號碼。

 

11.CArchive類管理文件緩沖區。它是Serialize的對象。CArchive針對許多C++數據類型,windows數據類型以及CObject派生類定義了Operator<<和operator>>重載運算符。

一個C++類如果想要有Serialization機制,就得直接或間接派生自CObject。為的是從CObject派生下列三個運算符:

_AFX_INLINE CArchive &AFXAPI operator<<(CArchive&ar,const CObject*pOb);

_AFX_INLINE CArchive &AFXAPI operator>>(CArchive&ar,CObject*&2pOb);

_AFX_INLINE CArchive &AFXAPI operator>>(CArchive&ar,const CObject*&pOb);

一個類如果希望有Serialization機制,它的第二要件就是使用SERIAL宏。

這個宏包含DYNCRETE宏,并且在類的聲明之中加上:

friend CArchive &AFXAPI operator>>(CArchive&ar,class_name* &pOb);

在類的應用程序文件中加上:

CArchive &AFXAPI operator>>(CArchive&ar,class_name*&pOb) /

{ pOb=(class_name*)ar.ReadObject(RUNTIME_CLASS(class_name)); /

       return ar;}

 

12.當多個視圖顯示同一個文檔,為了保持各個視圖操作的文檔內容的一致性,需要以消息通知使用同一份文檔的其他視圖,CView中有三個虛函數:

    1:CView::OnInitialUpdate:負責View的初始化。

    2:CView::OnUpdate,當FrameWork調用此函數時,表示Document的內容已經發生了變化。

    3:CView::OnDraw:在WM_PAINT消息時會調用此函數,此函數負責更新View窗口的內容。

讓所有的View窗口同步更新數據的關鍵在于兩個函數:

    1:CDocument::UpdateAllViews,它會遍歷使用這個文檔的各個視圖,逐個調用它們的OnUpdate函數。

    2:CView::OnUpdate,這是個虛函數,可以改寫。它的作用就是告訴View,document的內容已經改變,你需要更新了。

具體步驟為:    1:在CView中調用GetDocument獲得CDocument指針。

    2:在CView中調用CDocument::OnUpdateAllViews;

    3:所有使用這一份Document的view都被調用OnUpdate。

image

轉載請標注來源:http://www.blogfshare.com

By:AloneMonkey


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 潢川县| 永城市| 荥经县| 临洮县| 辛集市| 星子县| 安达市| 永胜县| 常熟市| 交城县| 黄浦区| 罗山县| 龙井市| 静宁县| 太白县| 蕲春县| 高邮市| 郓城县| 鄂伦春自治旗| 萨迦县| 孝昌县| 斗六市| 灌南县| 休宁县| 萝北县| 灵武市| 芜湖县| 邹平县| 济宁市| 木兰县| 民乐县| 延安市| 宁阳县| 海安县| 中方县| 治多县| 观塘区| 军事| 礼泉县| 永靖县| 金乡县|