基於MFC文檔/視/框架程序之利劍

作者:njustcxy

在我的同事當中,有不少人在用VC/MFC,但許多人總是容易被MFC的文檔視這種框架弄得暈頭轉向,儘管在他們的桌子旁堆了很多有關VC的資料。在我的學習過程中我發現下面的理解以及一些調用函數是最爲關鍵的,每當有人問我有關與此的問題,我給他(她)共享了下面的文檔後就不用重複解釋很多東西了。儘管這些都能從MSDN中最終找到答案,但有些人就是懼怕MSDN;希望您擁有這份資料後,可以大大減少你的懼怕。
l         預備
1.         文檔類通常與數據的存取以及其它處理過程有關,而視主要用來表現文檔數據的,但每個視必須依附於一個框架(在SDI中依附於MainFrame,在MDI中依附於ChildFrame),框架上可以放置工具欄、菜單等;
2.         某種類型的文檔、框架、視共同關聯構成一個文檔模板類(基類是CDocTemplate,其子類CSingleDocTemplate與CMutiDocTemplate分對應於SDI和MDI),文檔模板類在WinApp的初始化時構造;
3.         一個APP可以有N個文檔模板,但SDI及MDI框架嚮導默認生成的都只有一種模板(若需要更多則可以模仿添加);一個文檔模板在程序中可多次生成多個文檔實例,此所謂多文檔接口MDI(多文檔不僅可以是多個同類型的文檔還可以是多個不同類型的文檔);一種數據可以有N種表現形式,所以一個文檔可以有N個視與之關聯;
4.         在某一時刻只可能有一個活動的文檔、視、和框架。即當前文檔、視、和框架。
理解了這些再加上下面的操作就可以令你處理這類問題時得心應手了。
l         MDI對象之間的交互函數
函數
返回值
Global
AfxGetApp
CWinApp *(指向當前程序)
Global
AfxGetMainWnd
CWnd *(指向程序主窗口框架)
CMDIFrameWnd
MDIGetActive
CMDIChild Wnd *(指向當前活動的MDI子窗口)
CWnd
GetParentFrame
CFrameWnd *(指向父窗口框架)
CFrameWnd
GetActiveView
CView*(指向當前活動視)
CFrameWnd
GetActiveDocument
CDocument *(指向當前活動文檔)
CView
GetDocument
CDocument* (同該視圖類相聯繫)
CDocument
GetFirstViewPosition
同文檔相關的視圖列表中的第一個視圖類位置
CDocument
GetNextView
同文檔相關的視圖列表中的下一個視圖類位置
e.g.        CMainFrame* mfrm=(CMainFrame *)AfxGetMainWnd();
e.g.:得到當前視:
        CFrameWnd* pMain = (CFrameWnd*) AfxGetMainWnd();
       CFrameWnd *pChild = (CFrameWnd *) pMain->GetActiveFrame();
       CView* m_pAgentView = (CView *)pChild->GetActiveView();
l         訪問當前活動視圖和活動文檔
1.         對於SDI程序,主框架窗口就是文檔框窗,可以採用以下方法取得當前文檔和視圖:
u       取得活動文檔:
CMyDocument* pDoc;
pDoc=(CMyDocument*)((CFrameWnd*)AfxGetApp()->m_pMainWnd)->GetActiveDocument();
pDoc=(CMyDocument*)((CFrameWnd*)AfxGetMainWnd())
這兩者是等效的。
u       取得活動視圖:
CMyView* pView;
pView=(CMyView*)((CFrameWnd*)AfxGetApp()->m_pMainWnd)->GetActiveView();
2. 對於MDI程序,由於子窗口才是文檔框窗,因此首先要用GetActiveFrame()取得活動子框架窗口,然後通過該子窗口獲取活動文檔和視圖:
CMDIChildWnd* pChild=(CMDIChildWnd*)((CFrameWnd*)AfxGetApp()->m_pMainWnd)->GetActiveFrame();
u     取得活動文檔:
CMyDocument* pDoc=pChild->GetActiveDocument();
CMyView* pView=(CMyView*)pChild->GetActiveView();
可以把上述函數片段做成靜態成員函數,比如:
static CMyDocument::GetCurrentDoc()
{
CMDIChildWnd* pChild=(CMDIChildWnd*)((CFrameWnd*)AfxGetApp()- >m_pMainWnd)->GetActiveFrame();
CMyDocument* pDoc=pChild->GetActiveDocument();
}
這樣就可以通過以下方式取得活動文檔(或視圖):
CMyDocument::GetCurrentDoc();
注:靜態成員函數調用時不需要一個具體的對象與之相關聯。
l         文檔模板中找文檔
例:
       CMultiDocTemplate* pDocTmpl;
       pDocTmpl = ((CImpApp*)AfxGetApp())->m_pDocTemplate;
       POSITION posDoc= pDocTmpl->GetFirstDocPosition();
       while(NULL!=posDoc)
       {
              pFrmDoc = (CFrmDoc*) pDocTmpl->GetNextDoc(posDoc);
              nDocOrder++;
       }
願這些能成爲您操作MDISDI類程序的利劍,歡迎補充和提意見!
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章