在我的同事当中,有不少人在用 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++;
}