久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

MFC單文檔程序架構(gòu)解析

 liyanweicc 2011-07-27

MFC單文檔程序架構(gòu)解析

 

這里我以科院楊老師的單文檔程序來分析一下MFC單文檔的程序架構(gòu),,純屬個(gè)人見解,不當(dāng)之處煩請(qǐng)指教,!

首先我們了解到的是

 

圖(一)

theApp 是唯一一個(gè)在程序形成的時(shí)候就存在的全局變量,,它屬于CstockAppApp類,而CstockAppApp 繼承于CwinApp類,,我們看一下MSDN中CwinApp的繼承關(guān)系如下:

 

圖(二)

從繼承關(guān)系當(dāng)中,,我們發(fā)現(xiàn)theApp是作為程序的實(shí)體而存在的,是單文檔程序的核心,。

首先分析一下的是CsockAppApp這個(gè)類,,這里面有一個(gè)重要的函數(shù)

BOOL CStockAppApp::InitInstance()這個(gè)函數(shù),包含了單文檔程序中重要的信息,,特別要提到的是一下的一段代碼:

CSingleDocTemplate* pDocTemplate;

pDocTemplate = new CSingleDocTemplate(

IDR_MAINFRAME,

RUNTIME_CLASS(CStockAppDoc),

RUNTIME_CLASS(CMainFrame),       // main SDI frame windon

RUNTIME_CLASS(CStockAppView));

這里體現(xiàn)了幾個(gè)重要的思想,,第一動(dòng)態(tài)創(chuàng)建和動(dòng)態(tài)附加的一種思想,RUNTIME_CLASS是一個(gè)宏定義,,這里不做展開,,可以理解為最后的函數(shù)返回了實(shí)現(xiàn)了如下的語句

Retrun new CmainFramw 的功能,這里將三個(gè)不同的類對(duì)象附加到CsingleDocTemplate對(duì)象中,,這樣使得整個(gè)程序得以整體成立,。

接下來對(duì)剩下的三個(gè)類對(duì)象做分析

1. CmainFrame

CmianFrame類作為程序的框架類,其起到了一種容器的作用,,在這個(gè)容器當(dāng)中可以裝在多個(gè)視圖,,菜單,工具等,。要注意的有幾點(diǎn),,第一,因?yàn)?/span>mianfram是沒有視圖的,,因此如果在mainframe相應(yīng)Onpaint消息,自然是可以響應(yīng)這個(gè)消息的,,但是你會(huì)驚奇的發(fā)現(xiàn),,在你的繪制當(dāng)中如何也不會(huì)出現(xiàn)你預(yù)想出現(xiàn)的繪制內(nèi)容,為什么呢? 嘿嘿,,可以想象一下你在一個(gè)word程序里面,,當(dāng)你關(guān)閉了所有的白板(視圖)的時(shí)候,你會(huì)發(fā)現(xiàn)你已經(jīng)無法在編寫文字,,道理是一樣的,,在mainframe里面進(jìn)行繪制,程序是沒有問題,,但是繪制的內(nèi)容是在灰色上面,,windows不予顯示的。

第二點(diǎn)你可以發(fā)現(xiàn)在對(duì)菜單,,和工具條的單擊消息進(jìn)行相應(yīng)的時(shí)候你可以將消息響應(yīng)函數(shù)添加到cmainframe也沒有將消息響應(yīng)函數(shù)調(diào)價(jià)到cview當(dāng)中,,但是你會(huì)驚奇的發(fā)現(xiàn),兩者只在一個(gè)地方相應(yīng)的時(shí)候,,消息響應(yīng)函數(shù)沒有問題都能正確的執(zhí)行,,但是如果同時(shí)對(duì)一個(gè)按鈕或者菜單進(jìn)行單擊消息響應(yīng)的時(shí)候,你會(huì)發(fā)現(xiàn)windows會(huì)執(zhí)行的Cview里面的消息響應(yīng)函數(shù),。分析兩者之間的關(guān)系,,首先Cmianframe的繼承關(guān)系如下:

 

而對(duì)Cview類而言其繼承類關(guān)系如下圖所示:

 

可以看出兩個(gè)類之間并沒有直接的關(guān)系,但是我們通過程序的運(yùn)行可以知道消息的響應(yīng)是以Cview中為主的,,可以認(rèn)為存在一種類似于多態(tài)的關(guān)系,。

這里具體的消息路徑如下:

  SDI(單文檔)界面中,菜單響應(yīng)遵循這樣一個(gè)順序:菜單消息先由CMainFrame類接收,,CMainFrame并不直接在內(nèi)部尋找對(duì)應(yīng)的相應(yīng)函數(shù),,而是到CView類尋找。如果CView類有該消息的響應(yīng)函數(shù),,那么就直接調(diào)用CView類中的響應(yīng)函數(shù),,否則,轉(zhuǎn)到CDoc類尋找,,如果CDoc類中存在該消息的響應(yīng)函數(shù),,那么就直接調(diào)用CDoc類中的響應(yīng)函數(shù),否則,,返回到CMainFrame類尋找,。如果CMainFrame類中也沒有,返回到CApp類中尋找,。如果在CApp類中也沒有找到,,表示沒有該菜單的響應(yīng)函數(shù)。

 

同時(shí)CmainFrame作為整個(gè)程序的框架,,它提供了程序運(yùn)行的基礎(chǔ)環(huán)境,,這里再強(qiáng)調(diào)介紹一下兩點(diǎn)

1. 在CmainFrame中訪問Cview對(duì)象和Cdoc對(duì)象

要訪問這兩個(gè)對(duì)象可以使用全局函數(shù)GetActiveDocument()和GetActiveView()這樣可以獲得Doc對(duì)象和View對(duì)象的實(shí)體了

2. 在CmainFrame中調(diào)用Cview對(duì)象更新窗口,,這里使用方法如下:GetActiveView()->Invalidate(FALSE);// 這一句會(huì)是cview調(diào)用OnDraw消息響應(yīng)函數(shù)

GetActiveView()->UpdateWindow();//這句可以加上也可以不加,暫時(shí)沒有發(fā)現(xiàn)不加會(huì)出現(xiàn)什么問題,。

2.Cview

   Cview類作為視圖類,,其可以理解為一張畫布,在這張畫布上可以畫圖,,也可以畫控件,,其重要的函數(shù)有OnDraw這是主要繪圖出現(xiàn)的地方。在View中要實(shí)現(xiàn)重畫的時(shí)候可以按如下方式實(shí)現(xiàn)調(diào)用:

   void CTestView::OnChangeRect() 

{

// Change Rectangle size.

m_rcBox = CRect(20, 20, 210, 210);

 

// Invalidate window so entire client area 

// is redrawn when UpdateWindow is called.

Invalidate();  

 

// Update Window to cause View to redraw.

UpdateWindow();

}

 

// On Draw function draws the rectangle.

void CTestView::OnDraw(CDC* pDC)

{

//  ..  Other draw code here.

 

pDC->Draw3dRect(m_rcBox, 0x00FF0000, 0x0000FF00);

}

 在Cview內(nèi)中要獲取到CmianFrame可以使用下面的函數(shù):

AfxGetMainWnd()

3.doc類對(duì)象,。

個(gè)人覺得單文檔視圖的設(shè)計(jì)模式很接近MVC的設(shè)計(jì)模式,,Model層可以粗略的認(rèn)為是在Doc這個(gè)類對(duì)象里面,在單文檔視圖當(dāng)中Doc對(duì)象充當(dāng)?shù)囊彩菙?shù)據(jù)存儲(chǔ)的類,,可見確實(shí)是有一些MVC設(shè)計(jì)模式的意思,。這里介紹在其他類中要獲取Doc對(duì)象的方法

在Cmianframe中可以使用

   GetActiveDocument()

Cview類中可以使用

   這里要注意一點(diǎn),在Cview類中包含了一個(gè)Cdocument的對(duì)象m_pDocument這個(gè)對(duì)象即使指向Doc類的基類對(duì)象的,,而要實(shí)現(xiàn)基類對(duì)象到現(xiàn)在doc類對(duì)象的轉(zhuǎn)換只要添加如下函數(shù)即可

inline CStockAppDoc* CStockAppView::GetDocument()

{ return (CStockAppDoc*)m_pDocument; }

則可以實(shí)現(xiàn),。

 

附上三個(gè)類對(duì)象相互訪問方法:

1、主框架(CFrameWnd)中訪問視圖(CView)
CView* GetActiveView() const;
通常定義的視圖為CView的派生類,,在調(diào)用自定義視圖對(duì)象的方法時(shí)

應(yīng)該這樣寫:((CMouseKeyView*)GetActiveView())->MyFunc();

2,、主框架(CFrameWnd)中訪問文檔(CDocument)
GetActiveDocument,返回CDocument對(duì)象,;

3,、在視圖(CView)中訪問文檔(CDocument)
inline CMouseKeyDoc* CMouseKeyView::GetDocument()
{return (CMouseKeyDoc*)m_pDocument;}

4、在視圖(CView)中訪問框架(CFrameWnd)
CFrameWnd* GetParentFrame() const;

這里修改一下,,因?yàn)樯鲜龃a獲取的只是CMainFrame的父類對(duì)象CFrameWnd對(duì)象,,要獲取實(shí)際的CMainFrame對(duì)象可以進(jìn)行如下操作首先在頭文件中添加#include "MainFrm.h" 然后代碼如下:

CMainFrame* frm=(CMainFrame*)::AfxGetMainWnd();frm->test(); 就能成功咯

5、在文檔(CDocument)中訪問框架(CFrameWnd)
CWnd* AfxGetMainWnd();
CWnd* AfxGetApp()->m_pMainWnd;

6,、在文檔(CDocument)中訪問視圖(CView)
UpdateAllViews
功能:通知所有的視圖文檔已被修改的信息
原型:
void UpdateAllViews(
CView* pSender, // 要更新的視圖指針,,如果希望更新所有視

圖,將此參數(shù)設(shè)為NULL
LPARAM lHint=0L, // 包含更改消息的通知
CObject* pHint=NULL // 保管更改消息的對(duì)象
    }

7,、在其他類中訪問文檔類(CDocument)
CDocument* GetDocument()
{
CFrameWnd* frm=(CFrameWnd*)::AfxGetMainWnd();
ASSERT(frm);
CDocument* pDoc=frm->GetActiveDocument();
ASSERT(pDoc);
ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CMouseKeyDoc)));
return (CMouseKeyDoc*)pDoc;
}

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多