文档与视图的关系可以是一对一或者一对多
UpdateAllViews()用来更新所有与文档相关的视图
文档模板的创建和维护是在CWinApp中的InitInstance()中实现的,例如单文档模板:







应用程序类:派生于CWinApp,总体程序管理,例如初始化程序和最后的程序清除工作,文档视图结构,程序的主窗口
文档类:派生于CDocument,数据的存储与读取
视图类:派生于CView,显示数据,交互输入,可以用GetDocument()获取文档指针,用于读取和操作文档中的数据,从而实现对文档数据的修改。CView是虚拟类,包含了纯虚函数,例如OnDraw(),所以它本身不能直接用于声明对象。
主框架类:单/多文档分别派生于CFrameWnd和CMDIFrameWnd,管理用户界面对象,例如菜单、工具条、状态栏、加速键表。调用OnActiveView()通知当前视图。
-----------------------------------------------------------------分割线-----------------------------------------------------------------
文档的本质:文档是用来保存数据以及关于数据的处理的,当程序响应“File→Open”或“File→New”的时候都会打开一份文档。文档可以拥有多个视图。文档和视图的关系可以这样理解:文档是被视图观察的对象。
视图本质:视图在Windows中就是一个窗口,也就是一个可视化的矩形区域。视图是用来表示文档的数据的。但是每个视图必需依附于一个框架(SDI中是MainFrame,MDI是ChildFrame)。
框架的本质:框架实际是也是一个Windows窗口。但是在框架上可以放置菜单、工具栏、状态栏等。而视图则放在框架的客户区。因此MFC中我们看到的窗口实际上Frame和View共同作用的结果。
在某一时刻,程序中只有一个活动的文档、框架和视图,即当前的文档、框架、视图。应用程序类管理文档模板,文档模板管理框架、视图、文档。
一般而言,写代码时,文档类和视图类改得较多,框架类改得比较少,文档模板类几乎不会被修改。下面突出重点,讲一下文档和视图类的相关内容。
1.文档和视图的相互访问
文档与视图的关系是一对多关系。在MFC中,文档用CDocument类及其派生类处理,视图类由CView及其派生类处理。应用程序向导生成程序框架时,会自动为CXXView类生成GetDocument函数,可能通过此函数访问文档类。由于一个文档类对应多个视图类,可以遍历视图列表,代码如下:












2.视图类的刷新
文档数据发生了变化,所有的视图必须作相应的更新,这时可以用CDocument类的UpdateAllView函数,其原型如下:
void UpdateAllViews( CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL );
pSender:指向修改文档的视图的指针,为NULL表示刷新所有的视图。
lHint:表示关于修改的信息。
pHint:表示关于修改信息的CObject类指针。
此函数的实现如下:
















从实现代码中可以看出,UpdateAllViews调用各视图的OnUpdate,OnUpdate会调用Invalidate(TRUE)刷新视图。由于OnUpdate类是虚函数,所以会调用的是派生类的OnUpdate,可以根据需要,重写OnUpdate函数。
3.CView类的OnInitialUpdate()函数
新建或打开文档时,此函数会被调用,CView类的OnInitialUpdate()函数除了调用OnUpdate()函数之外,不做其他任何事情。如果想对视图进行初始化,可以在CView的派生类的OnInitialUpdate()函数进行。
4.CDocument类的DeleteContents()函数
当文档关闭时,应用程序框架会自动调用此函数。如果需要对文档进行清理操作,就可重写此函数。