关于MFC中Document, Frame, View以及Document Template结构关系

转载 2015年07月10日 17:28:39

MFC之所以能成为Application Framework, 很大的原因就在于其Document/View结构对于快速开发的支持. Document/View很好地划分了程序代码的前台后台, 让程序员可以专心于设计数据结构和UI.
Document即为“资料”, 按我理解就是饭店的厨师, 而View就是饭店的服务员. View负责点菜和上菜(对用户请求做出直接响应), 而Document负责烹饪, 即处理用户的要求.
除了Document和View, 还有一个Frame, 因为View要放在Frame内部, Frame就是承载View的框架. 而三者之间的关系是由Document Template来管理的, 一份Document Template管理一个Document/Frame/View三件组, 而一个程序可以有多个Document Template, 多个Document Template由一个CDocManager对象管理.


Document Template
一个MDI (多文档接口) 应用程序使用主框架窗口(main frame window)作为工作区, 在工作区里用户可以打开多个文档框架窗口, 每一个文档框架窗口用以显示一份文档.
Document Template是用来定义以下三种类之间关系的模板:
Document (文档)类, 从CDocument派生而来,  用于处理数据,  即所谓数据之体.
View (视图)类, 用于将来自Document类的数据显示出来, 可以从CView, CScrollView, CFormView和CEditView类派生,  也可以直接使用CEditView类.
框架窗口 (Frame Window)类, 用以包含View. 对于MDI程序, 可以从CMDIChildWnd派生, 也可以直接使用该类.


MDI应用程序可以支持不止一种文档,而且不同种类的文档可以同时打开 (比如一个text和一个bitmap). 对于每一种所支持的文档, 应用程序都应该有一份对应的Document template进行管理. 也就是说你的应用程序支持几种文档, 就应该有几个Document Template.
当用户创建新文档的时候, 应用程序就会使用Document Template. 如果程序支持的文档种类在一种以上, 那么程序框架就会从Document Templates处取得所有的文档类型名字, 显示在File New对话框里. 一旦用户选择了文档类型, 应用程序就会创建一个Document对象, 一个Frame Window对象和一个View对象, 并且将它们联系在一起 (通过Document Template).
通常程序员不需要使用CMultiDocTemplate的任何成员函数 (除了构造函数外). 框架会在内部自动处理CMultiDocTemplate对象.

为了管理通过相关View对象和Frame Window对象来构建Document的复杂过程, Framework使用两种Document Template类:
CSingleDocTemplate类用于SDI程序, CMultiDocTemplate类用于MDI程序. 一个CSingleDocTemplate在同一时刻只能创建并储存单一种类的一个文档, 一个CMultiDocTemplate在同一时刻可以管理单一种类的多个文档.
有些应用程序支持不止一种文档类型, 比如同时支持文本和图形. 这种应用程序为每个支持的类型使用单独的Document Template对象, 见下图:
这个应用程序支持两种文档类型,因此具备两个Document Template对象. 对于每一种文档类型可以打开多个文档, 每打开一个文档应用程序就为之创建三个对象: CMyDocument对象用于处理数据, CMyView对象用于显示, CMyFrameWnd用于装载View, 但是不管打开多少个同类型文档, 负责管理该类型的Document Template对象只有一个, 它负责管理的是上述三个类之间的关系, 负责在这三个类的对象创建之时指定它们之间的关系.
上面说到每打开一个Document, 会随之一起创建一个View和一个Frame Window,而这三者的创建工作就是由Document Template完成的, 当用户点击“File/New”或者“File/Open”后, 消息发出, 被theApp的OnFileNew()接到, 但它经过一系列的调用 (比较绕), 最终调用的是CMultiDocTemplate::OpenDocumentFile(), 该函数完成此三对象的创建, 其中View的创建又是非常的绕, 最终经过一系列的调用由CFrameWnd::CreateView()完成, 另外还会调用CView从CWnd继承来的函数Create()用于产生与该View对应的真实窗口. 而创建什么种类的Document, Window, View是在创建Document Template时由Document Template的构造函数的参数指定的. 下面显示了创建一个CMultiDocTemplate (用以管理MDI的document template) 的过程:


CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_EffectEditorTYPE,
RUNTIME_CLASS(CMyDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CMyView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);


传给构造函数的第一个参数是一个资源ID, 该资源用于提供该文档类型的菜单, 快捷键, 按钮等. 剩余三个参数用RUN_CLASS()宏提供CMultiDocTemplate创建Document/ Window/View时所需要的类型信息 (即对应的RuntimeClass对象, 当用户打开一个文件时, Document Template就可以据此动态创建出Document/Window/View, 这就很好体现了MFC动态创建的用途, 关于动态创建是由DECLARE_DYNCREATE()\IMPLEMENT_DYNCREATE() 宏实现的, 最后用AddDocTemplate()加载此Document Template, AddDocTemplate()实际上是将Document Template加到由theApp的一个指针CDocManager* m_pDocManager所维护的Document Template链表中CDocTemplate有三个成员变量分别持有Document/Window/View的RuntimeClass对象的指针, 另外还有一个资源ID成员.
Document Template对象是被theApp创建的. 在theApp的InitInstance()中的一个关键任务就是创建一个或多个适当种类的Document Template. theApp会在template list中保存指向每一个Document Template的指针并提供一个接口用于增加Document Template (AddDocTemplate()). 如果你想要支持两个或以上的文档类型, 你必须为每个文档类型显式地调用AddDocTemplate().
多个Document Template是由一个CDocManager对象管理的, 很多原本由CWinApp做的关于Document Template的工作如: AddDocTemplate(), OpenDocumentFile(), NewDocumentFile(), 在MFC4.0后都由CDocManager来做了.



CDocTemplate/CDocment/CFrameWnd/CView之间的指针互指关系
CDocTemplate有指向其余三者RuntimeClass对象的指针:
  CRuntimeClass* m_pDocClass;
  CRuntimeClass* m_pFrameClass;
CRuntimeClass* m_pViewClass;


还有指向Document列表的指针: CPtrList m_pDocList, 表示一个CDocTemplate可以维护多个同类型文档.
CDocument有CDocTemplate* m_pDocTemplate回指CDocTemplate, 另有CPtrList m_pViewList指向一个view的链表, 表示一个Document可以对应多个View.
CFrameWnd有CView* m_pViewActive指向当前活动在其中的View.
CView有CDocument* m_pDocument指向对应的Document.


CDocument/CFrameWnd/CView之间互相操作的函数
CDocument::UpdateAllViews()  -> CView:OnUpdate()
CView::GetDocument()
CView::GetParentFrame()
CFrameWnd::GetActiveView()
CFrameWnd::GetActiveDocument()


View和Document的通信
程序员通过改写CMyView的如下函数达到View和Document通信的目的:
CView::OnInitialUpdate(): 负责view的初始化.
CView::OnUpdate(): Frameword在Document发生变化时调用此函数, 此为预留给程序员的 "用Document的变化指导View" 的接口.
CView::OnDraw(): 该函数作为WM_PAINT的间接响应, 负责View的更新.
CDocument::UpdateAllViews()/CView::OnUpdate()这一对函数是命令与执行的关系, 调用UpdateAllViews()就会通知所有的View, 通知方法就是调用其OnUpdate().

MFC中的Document-View结构

MFC之所以为Application Framework,最重要的一个特征就是它能够将管理数据的程序代码和负责显示数据的程序代码分离开来,而这种能力有Document/View提供。 想要实现数据管理...
  • wzxq123
  • wzxq123
  • 2016年07月21日 12:08
  • 1540

关于MFC中Document, Frame, View以及Document Template结构关系

MFC之所以能成为Application Framework, 很大的原因就在于其Document/View结构对于快速开发的支持. Document/View很好地划分了程序代码的前台后台, 让程序...
  • u014371234
  • u014371234
  • 2014年07月28日 15:48
  • 313

WebKit中Page,Frame和Document的关系

在chrome浏览器中,打开一个新的标签页时,渲染进程就会创建一个新的WebView,该WebView是整个网页生成和渲染的入口,它是WebKit提供的一个公共接口。WebView的构造函数中会创建一...
  • yl02520
  • yl02520
  • 2014年02月16日 12:27
  • 4593

在C++ MFC中Single document和Dialog based有什么具体的区别?

在我个人看来有两个区别 1,SDI比dialog based有更丰富的默认窗体,比如,默认的菜单, 2,SDI有document-view的代码结构,而DIALOG based没有这个D-V结...
  • u014683488
  • u014683488
  • 2014年04月29日 17:28
  • 1093

MFC中Document/View结构

(1)在MFC中,文档类负责管理数据,提供保存和加载数据的功能;视类负责数据的显示,以及给用户提供对数据的编辑和修改功能。 (2)MFC给我们提供Document/View结构,将一个应用程序所需要...
  • candyliuxj
  • candyliuxj
  • 2011年09月17日 08:49
  • 1648

利用MFC Document/View框架完成图形显示和保存功能

Document/View结构 首先总结下MFC的Document/View结构相关的知识点: (1)在MFC中,文档类负责管理数据,提供保存和加载数据的功能;视类负责数据的显示,以及提供...
  • xiao3404
  • xiao3404
  • 2017年02月19日 16:18
  • 894

Designing ActiveX Components with the MFC Document/View Model

W hether youre an experienced Win32® guru or a junior Windows® wanna-be, you...
  • l12345678
  • l12345678
  • 2007年07月27日 14:56
  • 7117

Document/View的初始化过程

最近正在看《mfc深入浅出》,看到第8章Document/View深入探讨时候,对Document/View的建立过程不是很清楚,于是下大力气猛啃书和各种百度,明白了一些,做个小结: 先从CTest...
  • smells2
  • smells2
  • 2011年11月14日 16:37
  • 2526

cannot find the word template:WordToRqm.dot的解决方法

powerdesigner安装后: C:"Program Files"Sybase"PowerDesigner 12"Add-ins"Microsoft Word Import Export 下的 W...
  • wangjun_pfc
  • wangjun_pfc
  • 2008年10月10日 14:59
  • 6772

将Doc/View 应用程序打造成 ActiveX 控件

众所周知,MFC提供了一个非常强大的,但是又不太容易理解的编程模型叫做文档/视图结构。它的基本思想就是将数据的表现和数据的存在分开管理。MFC提供了很多现在的类来达成这个目标,通常,利用CFrameW...
  • prolibertine
  • prolibertine
  • 2006年12月19日 08:11
  • 2063
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于MFC中Document, Frame, View以及Document Template结构关系
举报原因:
原因补充:

(最多只允许输入30个字)