文档、视图、框架

文档/视图结构是MFC提供的一种不错的设计,它将数据的处理和显示分开来,这样更便于我们对程序的维护和扩展。

文档

       文档对象用于管理和维护数据,包括保存数据、取出数据以及修改数据等操作,在数据被修改以后,文档可以通知其对应的所有视图更新显示。

文档类继承于CDocument类,主要成员函数:

virtual BOOL OnNewDocument( );

       创建新文档。可以重载使用。

virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);

       打开文档。参数lpszPathName为要打开的文档的路径。可以重载使用。

virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);

       保存文档。参数lpszPathName指定文档保存到的全路径。可以重载使用。

CDocTemplate* GetDocTemplate( ) const;

       获取此文档类型对应的文档模板对象的指针。如果此文档没有被文档模板管理则返回NULL。

virtual POSITION GetFirstViewPosition( ) const;

       获取文档中视图列表的第一个视图的位置。

virtual CView* GetNextView(POSITION& rPosition) const;

       利用此函数可以迭代处理文档的所有视图。参数rPosition为上一次调用GetFirstViewPosition或GetNextView成员函数返回的POSITION值的引用。

void AddView(CView* pView);

       为文档增加一个视图。参数pView为要增加的视图对象的指针。

void RemoveView(CView* pView);

       移除某个视图与文档的关联。参数pView为要移除的视图对象的指针。

void UpdateAllViews(CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL);

       在文档被更改后调用此函数更新视图。参数pSender指向修改文档的视图,实际应用时常用来指定哪个视图不需要更新,如果更新所有视图则设为NULL,参数lHint包含了文档修改的信息,参数pHint指向存储文档修改信息的对象。

视图

       视图对象将文档中的数据可视化,负责从文档对象中取出数据显示给用户,并接受用户的输入编辑,将数据的改变反映给文档对象。视图充当了文档和用户之间媒介的角色。

视图类继承于CView类,CView类中与文档/视图结构相关的成员函数包括:

CDocument* GetDocument( ) const;

       获取视图关联的文档对象的指针。如果视图没有关联到文档上则返回NULL。

框架

       一个文档可能有多个视图界面,这就需要有框架来管理了。框架就是用来管理文档和视图的。框架窗口是应用程序的主窗口,应用程序执行时会先创建一个最顶层的框架窗口。视图窗口是没有菜单和边界的子窗口,它必须包含在框架窗口中,即置于框架窗口的客户区内。

框架类继承于CFrameWndEx类,CFrameWndEx类又继承于CFrameWnd类,CFrameWnd类中用于管理文档和视图的成员函数包括:

virtual CDocument* GetActiveDocument( );

       获得当前活动视图对应文档对象的指针,如果不存在则返回NULL。

CView* GetActiveView( ) const;

       获得当前活动视图对象的指针,如果不存在则返回NULL。

void SetActiveView(CView* pViewNew, BOOL bNotify = TRUE);

       设置活动视图。参数pViewNew为要激活的视图对象的指针,参数bNotify指定视图是否接收激活通知。

文档模板

       文档模板中存放了与文档、视图和框架相关的信息。应用程序通过文档模板创建文档对象、框架窗口对象和视图对象。另外,文档、视图和框架之间的关系也是由文档模板来管理的。

 

文档、视图、框架结构中各对象之间的关系

       1. 应用程序对象保存了一个文档模板的列表。在任何对象中调用全局函数AfxGetApp都可以获得应用程序对象的指针。通过调用CWinAppEx::GetFirstDocTemplatePosition、CWinAppEx::GetNextDocTemplate函数可以遍历所有的文档模板。

       2. 文档模板对象用于维护文档、视图和框架窗口的映射关系,它包含有一个已打开文档的列表。我们可以通过调用CDocTemplate::GetFirstDocPosition、CDocTemplate::GetNextDoc来遍历该文档模板对应的所有文档。

       3. 框架窗口对象中包含有指向当前活动视图对象的指针。AfxGetApp()->m_pMainWnd即为主框架窗口对象的指针。我们可以通过调用CFrameWndEx::GetActiveView来获取当前活动视图对象的指针,并且使用CFrameWndEx::GetActiveDocument函数可以获得当前活动视图对应的文档。

       4. 文档对象中维护着该文档的视图列表,以及创建该文档的文档模板对象的指针。我们可以通过调用CDocument::GetFirstViewPosition,CDocument::GetNextView来遍历该文档关联的所有视图,调用CDocument::GetDocTemplate获取创建该文档的文档模板对象的指针。

       5. 视图是框架窗口的子窗口,它保存有指向对应的文档对象的指针。我们可以通过调用CView::GetParentFrame获取其所属的框架窗口对象的指针,调用CView::GetDocument获取该视图对应的文档对象的指针。

       另外,在MDI多文档程序中,调用CMDIFrameWnd::MDIGetActive可以获取当前活动的MDI子窗口。

文档和视图的关系

        应用程序可以是单文档程序也可以是多文档程序。单文档程序中主框架窗口和文档框架窗口重合,而多文档程序的主框架窗口中有客户窗口,客户窗口中又包含了多个文档框架窗口。

       文档和视图是一对多的关系。一个文档可以对应多个视图,例如在Word中一个文档有普通视图、大纲视图、Web版式视图、阅读版式视图等多种视图。而一个视图只能属于一个文档。最简单的应用程序是单文档单视图程序,除此之外还有单文档多视图程序、多文档程序等。

       每个文档对象都保存着一个视图列表,可以通过CDocument::AddView函数添加视图,通过CDocument::RemoveView函数删除视图,在数据发生变化时调用CDocument::UpdateAllViews函数更新所有视图。

       在MFC中文档可以有三种视图模式

       1. 文档有多个视图对象,它们是同一个视图类的对象,每个视图对象位于一个独立的文档框架窗口中。

       2. 文档的基于同一个视图类的多个视图对象,位于同一个文档框架窗口中。Word的子窗口就是这种视图模式。

  3.文档的视图对象属于不同的视图类,但所有的视图对象位于同一文档框架窗口中。

 

分割窗口:CSplitterWnd类

MFC分割窗口的方式有两种,动态分割和静态分割。

       动态分割窗口通常用于创建同一个文档对应的多个视图,而且这些视图一般都是同一类型的视图,能够在用户编辑文档的不同部分时提供方便。动态分割窗口最多可以有两行两列。

       静态分割窗口比较常见。静态分割窗口指在窗口创建时,分割的窗格就已经生成了,而且用户不能改变窗格的数量和顺序。静态分割窗口最多支持16行16列。通常静态分割窗口的每个窗格中包含不同类的视图,当然也可以是同一类的视图。

 

CSplitterWnd类中包含一个分割器窗口,该分割器窗口就是一个包含多个窗格的窗口。我们分割窗口时就是直接在此分割器窗口中分割的。

virtual BOOL Create(
CWnd* pParentWnd,
int nMaxRows,
int nMaxCols,
SIZE sizeMin,
CCreateContext* pContext,
DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | SPLS_DYNAMIC_SPLIT,
UINT nID = AFX_IDW_PANE_FIRST
);
//创建动态分割窗口。参数pParentWnd为分割器窗口的父框架窗口;参数nMaxRows为分割器窗口的最大行数,不能超过2;参数nMaxCols为分割器窗口的最大列数,也不能超过2;参数sizeMin为窗格能显示的最小尺寸,如果窗格尺寸小于sizeMin则不显示;参数pContext为指向CCreateContext结构的指针,大多数情况下可以赋值为父框架窗口的pContext;参数dwStyle指定窗口风格;参数nID为分割窗口的ID,除非分割器窗口嵌入到另一个分割器窗口中,否则可以取值AFX_IDW_PANE_FIRST。
virtual BOOL CreateStatic(
CWnd* pParentWnd,
int nRows,
int nCols,
DWORD dwStyle = WS_CHILD | WS_VISIBLE,
UINT nID = AFX_IDW_PANE_FIRST
);
//创建静态分割窗口。参数pParentWnd、dwStyle和nID同上;参数nRows为行数,不能超过16;参数nCols为列数,同样不能超过16。
virtual BOOL CreateView(
int row,
int col,
CRuntimeClass* pViewClass,
SIZE sizeInit,
CCreateContext* pContext
);
//静态分割窗口创建窗格视图。参数row指定分割器窗口中放置新视图的行;参数col指定放置新视图的列;参数pViewClass指定新视图的CRuntimeClass对象;参数sizeInit指定新视图的初始大小;参数pContext为指向CCreateContext结构的指针,通常可以赋值为传递给父框架窗口的重载函数CFrameWnd::OnCreateClient的pContext参数值。

 

创建动态分割窗口的步骤为:

       1. 在父框架类中定义一个CSplitterWnd类型的成员对象。

       2. 重载父框架类的CFrameWnd::OnCreateClient成员函数。

       3. 在重载的CFrameWnd::OnCreateClient函数中调用CSplitterWnd成员对象的Create函数。

创建静态分割窗口的步骤为:

       1. 在父框架类中定义一个CSplitterWnd类型的成员对象。

       2. 重载父框架类的CFrameWnd::OnCreateClient成员函数。

       3. 在重载的CFrameWnd::OnCreateClient函数中调用CSplitterWnd成员对象的CreateStatic成员函数,然后可以调用CSplitterWnd成员对象的CreateView成员函数为每个窗格创建视图。

 

如果大家想创建在其中某个窗格中再嵌套分割窗口,那么就需要再定义一个CSplitterWnd对象,以父窗格所在的CSplitterWnd对象为父框架窗口创建分割窗口即可。

MFC文档、视图和框架的更多相关文章

  1. 深入分析MFC文档视图结构(项目实践)

    k_eckel:http://www.mscenter.edu.cn/blog/k_eckel 文档视图结构(Document/View Architecture)是MFC的精髓,也是Observer ...

  2. MFC文档视图结构学习笔记

    文档/视图概述 为了统一和简化数据处理方法,Microsoft公司在MFC中提出了文档/视图结构的概念,其产品Word就是典型的文档/视图结构应用程序 MFC通过其文档类和视图类提供了大量有关数据处理 ...

  3. MFC文档视图中窗口切换 (2012-05-11 18:32:48)

    在文档试图应用程序,有时需要在工作区切换试图,以下就是如何切换试图了 .创建要切换的视图类,同时把构造函数,Create函数改变为public .在需要切换试图的动作响应中,加入切换代码,一般是在CM ...

  4. MFC 文档/视图

    1.文档修改后,关闭时需要保存,主要用到2个函数,在需要更改文档内容的函数里调用SetModifiedFlag(TRUE),另一个就是SaveModified()函数,简单的例子: BOOL CMFC ...

  5. MFC 文档视图关系

    参考:http://www.360doc.com/content/11/1102/09/3054335_160991088.shtml 写的很详细可以看看 IDC_:控件的ID命名前缀(Control ...

  6. 文档/视图(01):第一个Demo

    学习文档视图编程的第一个demo,程序比较简单,主要对文档模板,文档,视图等相互关系的一个了解. 功能:菜单添加一个[操作]项,然后新建四份空白文档,点击[操作]之后,在四份空白文档上面各绘制一个Bu ...

  7. 理解MFC 文档、视图、框架[转]

    理解文档/视图框架                                      出处.雷神 了解文档和视图的相互作用关系是编写MFC程序的基本功.但是MFC的应用程序框架把文档和视图之间 ...

  8. VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)

    VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)-软件开发-鸡啄米 http://www.jizhuomi.com/software/141.html   上一讲中讲了VS20 ...

  9. MFC单文档视图程序简介

    在视图应用程序中,应用程序的数据由文档对象代表,数据的视图由视图对象代表.MFC的Cdocument类是文档对象的基类,Cview类是视图对象的基类.应用程序的主窗口,其操作功能在MFC的Cframe ...

随机推荐

  1. 使用Yeoman搭建 AngularJS 应用 (12) —— 让我们搭建一个网页应用

    原文地址:http://yeoman.io/codelab/local-storage.html 安装Bower程序包 我们使用另一个Angular模块,"angular-local-sto ...

  2. textarea中限制输入字符长度

    要在textarea中限制输入字符的长度,比如在twitter中要限制字符为140个,可实现的方法有: 1. <textarea name="A" cols="45 ...

  3. <span> <div> 局部 keydown ,keyup事件。页面部分div $(document) 无效,可能焦点,添加焦点。

    前天改一个bug, js 实现的一个 面板拖拉,左右各两个列表,中间面板画线连接,页面左侧列表选中后,key 事件无效.右侧选中确有效,很奇怪,查看源码,左侧选中后,$(document).on(&q ...

  4. HDU4756+Prim

    题意简单:去掉最小生成树的某一条边并补上一条,求MaxVal 思路:贪心(借鉴Yamidie的思路...) 分别求出最小生成树和次最小生成树,再在这两棵树上求最小生成树 #include<std ...

  5. hdu 4336 Card Collector 容斥原理

    读完题目就知道要使用容斥原理做! 下面用的是二进制实现的容斥原理,详见:http://www.cnblogs.com/xin-hua/p/3213050.html 代码如下: #include< ...

  6. mybatis知识点

    1.Mybatis比IBatis比较大的几个改进是什么 a.有接口绑定,包括注解绑定sql和xml绑定Sql , b.动态sql由原来的节点配置变成OGNL表达式, c. 在一对一,一对多的时候引进了 ...

  7. SPRING IN ACTION 第4版笔记-第八章Advanced Spring MVC-007-给flowl加权限控制<secured>

    States, transitions, and entire flows can be secured in Spring Web Flow by using the <secured> ...

  8. jQuery 的 $("someobjectid”).event() 的绑定

    经验证,jquery 的 $("someobjectid”).event()事件绑定,如果放在某个会被重新初始化的对象里,就会被多次绑定. 如下 <div id="divID ...

  9. 动态改变QSS

    通常,一旦设置使用setObjectName来初始设置QSS: list_widget = new QListWidget(); list_widget->setObjectName(" ...

  10. Android:控件GridView的使用

    如果是列表(单列多行形式)的使用ListView,如果是多行多列网状形式的优先使用GridView. <?xml version="1.0" encoding="u ...