第 1 节 文档视图结构
MFC能够成为“应用程序框架”,最重要的东西除了巧妙地实现了消息循环,另一个很精华的东西可能就要算文档视图结构了。文档视图结构包含4个东西:文档、视图、框架和文档模板,暂且我们把它称成4元素。其实它是仿照精典的MVC模式,将显示、控制逻辑、数据分离开来。在MFC中,文档存储数据,而View将数据显示出来,一个文档可以有多个视图,而一个视图却只能有一个文档。文档和视图的关系由“文档模板”来进行管理。那么框架的作用是什么呢?框架是用来放视图等元素的。如果要增加一个视图,必须再增加一个框架,然后用文档模板将它们管理起来。
那么一个MFC的应用程序的对象是怎么构成的呢?首先,所有的都是一个theApp对象,这个对象是整个应用程序。theApp对象是CXXXApp的实例化,而CXXXApp的父类是CWinAppEx,CWinAppEx的父类是CWinApp。
第 2 节 框架的产生
4元素中的框架是怎么产生出来的呢?首先,多文档结构可能有多个框架,单文档结构却只有一个框架。无论单文档和多文档结构,它们都有一个主框架m_pMainWnd,这是定义在CWinApp的父类CWinThread里面里的一个指针。当然,如果我们想将单文档结构的应用程序改成多文档的结构,可以添加框架的指针。
这个框架的指针是怎么产生对象的呢,是在CXXXApp的InitInstance函数里面被new出来的,如下所示。
注意单文档和多文档所继承的框架是不同的,单文档继承的是CFrameWndEx,这是CFrameWnd的子类。单文档的框架下是不能再放子框架的了。
而多文档继承的是CMDIFrameWndEx,它是CMDIFrameWnd的子类,它是可以放子框架CMDIChildWndEx类。
第 3 节 视图的产生
视图是怎么产生出来的呢,首先,视图的指针定义在CMainFrame里面,所以说视图应该看作框架的一部分。看到m_wndView并不是一个指针,而是直接定义的一个对象。
在CMainFrame的函数OnCreate(这个函数在建造主框架的时候调用)的时候调用如下函数:
第 4 节 文档的产生
文档的指针是定义在XXXView的你类CView里面的,这预示着什么呢,预示着一个View会对应一个Document,而且一个View只有一个文档的指针,说明一个View只能对应一个Document(用户当然可以自己加,但是违背设计的目的)。
但是它怎么生成一个对象,或者它怎么绑定到一个文档上的呢。调用函数可以将一个视图绑定在一个文档上面:
在CView的OnCreate函数里面调用AddView进行视图和文档的绑定的。
但是在CView里面有个函数GetDocument可以获得这个文档:
第 5 节 文档模板的产生
文档模板的生成是在CXXXApp的InitInstance函数里面实现的,它将文档、视图和框架绑在一起,并管理它们。
函数AddDocTemplate是将文档模板加入一个文档模板的列表里面,然后有一套系统里面管理。只是单文档的时候,加入的文档模板是CSingleDocTemplate,而在多文档的时候,加入的文档模板为:CMultiDocTemplate。
第 6 节 文档视图的互访