Document
Document
在
MFC
的
CDocument
里面被实例化
. CDocument
本身并无实际用途
,
它只提供一个空壳
.
当我们开发自己的程序时,应该从CDocument派生一个属于自己的Document类,并且在类中声明一些成员变量,用以承载(容纳)数据.然后再(至少)改写专门负责文件读写操作的Serialize函数.事实上,AppWizard为我们把空壳都准备好,
由于
CDocument
派生自
CObject
,所以它就有
CObject
所支持的一切性质,包括
RTTI,Dynamic Creation,Serialization.
又由于它也派生
CCmdTarget,
所以它可以接受来自菜单或工具栏的
WM_COMMAND
消息。
View
View
负责描述(呈现)
Document
中的数据。
View
在
MFC
的
CView
中被实例化。
CView
只提供一个空壳,在开发过程中,应该从
CView
派生一个属于自己的
View
类,且在类中(至少)改写专门负责显示数据的
OnDraw()
函数(针对屏幕)或
OnPaint()
函数(针对打印机)。其实
AppWizard
为我们把空壳都准备好了。
由于
CView
派生自
CWnd,
所以它可以接受一般的
Windows
消息(如
WM_SIZE,WM_PAINT
等等),又由于它也派生自
CCmdTarget
,因此它也可以接受菜单或工具栏的
WM_COMMAND
消息。
传统
C/SDK
程序中,当窗口函数收到
WM_APINT
时,就调用
BeginPaint,
获得一个
Device Context(DC),
然后在这个
DC
上作画。这个
DC
代表屏幕装置。在
MFC
里面,一旦
WM_PAINT
发生,
Framework
会自动调用
OnDraw
函数。
View
事实上是个没有边框的窗口。真正出现时,其外围还有一个有边框的窗口,我们称之为
Frame
窗口。
Document Frame(View Frame)
若我们的程序管理两种不同类型的数据,比如说一个是TEXT,一个是BITMAP,作为程序设计者要为使用者多考虑一些:使用者可能在操作TEXT数据时,换一套TEXT专用的使用界面,在使用者操作BITMAP数据时,也换一套BITMAP界面。这份工作是由Frame窗口负责。
为什么UI的管理不由View直接负责,却要交给Frame窗口。将UI管理机能隔离出来,可以降低彼此之间的依存性,也可以是机能重复使用于各种场合,如SDI,MDI,OLE,In-Place editing(即地编辑)之中。如此一来,View的弹性也会大一些。
Document Template
MFC
把Document/View/Frame视为三位一体。每当使用者欲打开(或新增)一份文件,程序应该做出Document,View,Frame各一份。这个“三口组”成为一个运行单元,由所谓的Document Template掌管。MFC中有一个类CDocument负责此事。它又有两个派生类,分别CMultiDocTemplate 和CSingleDocTemplte.
若我们的程序能够处理两种数据类型,必须制造两个Document Template出来,并使用AddDocTemplate函数将它们一一加入系统之中。这和程序是不是MDI并无关系。若程序支持多种数据类型,但却是个SDI,那只不过表示每次只能开启一份文件。
CDocTemplate
是个抽象类,定义一些用来处理
”
Document/View/Frame
三口组
”
的基础函数。
CDocTemplate
管理CDocument/CView/CFrameWnd
Document Template
管理“三口组“,CWinAPP又来管理Document Template.
File/New File/Open
↓
↓
CWinApp
选择适当的Document Template
↓
CMyDoc
构造Document对象
↓
CCwndFrame CMyView
构造Frame窗口对象 构造View对象
↓
↗
↓
产生Frame窗口 <———— 产生View窗口
↓
读文件(若是File/Open)
↓
将View窗口初始化
↓
在View中显示资料
注意:构造View对象和产生View窗口的关系。View窗口就是地地道道的Windows窗口,而为了对象管理,MFC把View窗口外包一个专门的C++类别,那就是CView。所以当然是先构造(Construct)一个View对象,再由其构造函数产生(Create)对应的View窗口。
解释CDocTemplate,CDocument,CView,CFrameWnd之间的关系:
# CWinApp
拥有一个对象指针:CDocManager *m_pDocManager
# CDocManager
拥有一个指针链表CPtrList m_templateList,用来维护一系列的Document Template.一个程序若支持两种文件类型,就应该有两份Document Templates,应用程序应该在CMyViewApp::InitInstance中以AddDocTemplate将这些Document Templates加入到由CDocManager所维护的链表中。
# CDocTemplate
拥有三个成员变量,分别持有Document,View,Frame的CRuntimeClass指针,另有一个成员变量m_nIDResource,用来表示此Document显示时应该采用的UI对象。这四份数据应该在CMyWinApp::InitInstance函数构造CDocTemplate时指定,成为构造函数的参数。
# CDocument
有一个成员变量CDocTemplate * m_pDocTemplate,回指Document Template;另有一个成员变量CPtrList m_viewList,表示它可以同时维护一系列的Views。
# CFrameWnd
有一个成员变量CView * m_pViewActive,指向当前活动的View.
# CView
有一个成员变量CDocumnet *m_pDocumnt,指向相关的Document.