文档与视图结构

  • 文档、视图的关系,是一对多的映射,一个文档可以对应多个视图,而一个视图只能对应一个文档。例如,一个.html文件,可以用记事本打开,也可以用浏览器打开,这里的.html文件就是文档,记事本和浏览器就是这个文档的两个视图。

  • 文档和视图结构的优势在于数据的管理与显示分离,数据总是要以一定的结构来存储,而视图负责数据的呈现。数据往往有多种呈现方式,例如一份报表,可以用表格的形式呈现,也可以用图表的形式呈现。根据不同的需求以不同的形式呈现,这就是视图的特性。

  • 在使用文档/视图体系开发应用程序过程中,涉及的不仅仅是文档与视图。总体来说,涉及4个部分:文档模板、文档、视图和框架窗口。

  • 新建一个项目名称为MDITest的多文档应用程序,应用程序的初始化过程如下:

// CMDITestApp 初始化

BOOL CMDITestApp::InitInstance()
{
// 如果一个运行在 Windows XP 上的应用程序清单指定要使用
//ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的公共控件类
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls); CWinAppEx::InitInstance(); // 初始化 OLE 库
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
} AfxEnableControlContainer(); EnableTaskbarInteraction(); // 使用 RichEdit 控件需要 AfxInitRichEdit2()
// AfxInitRichEdit2();
// 标准初始化
// 如果未使用这些功能并希望减小
// 最终可执行文件的大小,则应移除下列
// 不需要的特定初始化例程
// 更改用于存储设置的注册表项
// TODO: 应适当修改该字符串,
// 例如修改为公司或组织名
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
LoadStdProfileSettings(4); // 加载标准 INI 文件选项(包括 MRU) InitContextMenuManager(); InitKeyboardManager(); InitTooltipManager();
CMFCToolTipInfo ttParams;
ttParams.m_bVislManagerTheme = TRUE;
theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams); // 注册应用程序的文档模板。文档模板
// 将用作文档、框架窗口和视图之间的连接
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_MDITestTYPE,
RUNTIME_CLASS(CMDITestDoc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
RUNTIME_CLASS(CMDITestView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate); // 创建主 MDI 框架窗口
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
{
delete pMainFrame;
return FALSE;
}
m_pMainWnd = pMainFrame;
// 仅当具有后缀时才调用 DragAcceptFiles
// 在 MDI 应用程序中,这应在设置 m_pMainWnd 之后立即发生 // 分析标准 shell 命令、DDE、打开文件操作的命令行
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo); // 调度在命令行中指定的命令。如果
// 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// 主窗口已初始化,因此显示它并对其进行更新
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow(); return TRUE;
}
  • 在初始化过程中,首先创建CMultiDocTemplate类型的多文档模块,并使用AddDocTemplate把多文档模板对象添加到文档模板管理器。

  • 然后创建CMainFrame类型的框架窗口,最后显示并更新框架窗口。通过文档模板抽象基类CDocTemplate,把框架窗口、文档与视图三者关联起来。对于单文档应用程序,需要使用单文档模板类CSingleDocTemplate,而对于多文档应用程序,需要使用多文档模板类CMultiDocTemplate。

  • 文档模板之所以能够将文档、视图和框架窗口三者相关联,是因为文档模板类CDocTemplate中定义了文档、视图和框架窗口的CRuntimeClass对象指针。而这三个CRuntimeClass对象的初始化恰好在文档模板的构造函数中实现。

  • 文档派生于CDocument类,负责存储应用程序的数据,并把这些数据提供给其他部分,可以在源码中查看CDocument类定义。

  • 一个文档可以与多个视图关联,每一个视图仅仅是与其相关联文档数据的一种表现形式,在CDocument类中定义了一个CPtrList类型的变量m_viewList,用于维护与当前文档对象相关联的视图链表。使用成员函数AddView可以添加视图,使用成员函数RemoveView可以删除视图。

  • MFC的CView类是所有视图类的基类,主要有两大功能:

    • 将与其相关联文档的数据呈现给用户。
    • 接受用户对数据的修改,并反馈给文档。
  • 在CView类中,定义了一个文档对象指针m_pDocument,在应用程序中可以使用CView的成员函数GetDocument获取与特定视图对象相关联的文档对象。

  • 当视图中的数据被修改后,除了需要通知文档修改数据外,还需要使用CDocument类的成员函数UpdateAllViews通知所有与该文档相关联的视图更新显示数据。

  • 在文档/视图结构中,文档负责数据的管理,视图负责数据的显示,框架窗口则负责管理这些界面。框架窗口有两种模式:单文档窗口SDI和多文档窗口MDI。在SDI环境下,同时最多只能一个框架窗口;而在MDI环境下则没有这个限制。

单文档和多文档

  • 使用AppWizard创建SDI和MDI的过程相似,主要区别是创建SDI时不生成CChildFrame类,CMainFrame类的基类为CMainWnd;而在创建MDI时会生成两个框架类,一个是CMainFrame类,由CMDIFrameWnd类派生而来,另一个是CChildFrame类,由CMDIChildWnd类派生而来。

  • 在单文档(SDI)中,CMainFrame对象不但构成了应用程序框架,也包含了视图对象。单文档(SDI)应用程序在一个主框架上只有一个子框架窗口。

  • 在多文档(MDI)中,CMainFrame对象是在应用程序类的InitInstance中被创建,而视图则被包含在CChildFrame对象中。多文档(MDI)应用程序在一个主框架上可以有多个子框架窗口。

MFC---文档与视图结构的更多相关文章

  1. MFC文档、视图和框架

    文档.视图.框架 文档/视图结构是MFC提供的一种不错的设计,它将数据的处理和显示分开来,这样更便于我们对程序的维护和扩展. 文档        文档对象用于管理和维护数据,包括保存数据.取出数据以及 ...

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

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

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

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

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

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

  5. VS2010/MFC编程入门之四十一(文档、视图和框架:分割窗口)

    上一节中鸡啄米讲了文档.视图和框架结构中各对象之间的关系,本节主要讲讲在MFC中如何分割窗口. 分割窗口概述       分割窗口,顾名思义,就是将一个窗口分割成多个窗格,在每个窗格中都包含有视图,或 ...

  6. VS2010/MFC编程入门之三十九(文档、视图和框架:概述)

    前面几节讲了菜单.工具栏和状态栏的使用,鸡啄米本节开始将为大家讲解文档.视图和框架的知识. 文档.视图和框架简介 在VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)创建的单文档工 ...

  7. VS2010/MFC编程入门之四十(文档、视图和框架:各对象之间的关系)

    前面一节中鸡啄米进行了文档.视图和框架的概述,本节主要讲解文档.视图.框架结构中各对象之间的关系. 各个对象之间的关系 文档.视图.框架结构中涉及到的对象主要有:应用程序对象.文档模板对象.文档对象. ...

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

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

  9. (九)文档和视图,Invalidate,数据库编程

    一.文档视图结构 文档类(CDocument):存储加载(读写)数据视图类(CView):显示和修改数据 1)单文档 a)文档模板:把框架窗口.文档.视图关联在一起b)文档类(CDocument): ...

随机推荐

  1. 神奇的 CSS,让文字智能适配背景颜色

    最近几天,有好几个同学都问了同样一个问题. 页面上有一段文本,能否实现这段文本在不同背景色下展示不同的颜色?也就是俗称的智能变色.像是下面这样: 文本在黑色底色上表现为白色,在白色底色上表现为黑色.看 ...

  2. Owin + WebApi + OAuth2 搭建授权模式(授权码模式 Part I)

    绪 最近想要整理自己代码封装成库,也十分想把自己的设计思路贴出来让大家指正,奈何时间真的不随人意. 想要使用 OWIN 做中间件服务,该服务中包含 管线.授权 两部分.于是决定使用 webapi .O ...

  3. 2022年官网下安装Kibana最全版与官网查阅方法(Kibana8.1.0+Elasticsearch8.1.0)

    一.环境整合(需要提前装好) 构建工具(参考工具部署方式) 软件名称 版本 相关文章推荐 Elasticsearch ..* https://www.cnblogs.com/liuyangfirst/ ...

  4. info sharp Are you trying to install as a root or sudo user? Try again with the --unsafe-perm flag

    执行 npm install 编译出错,提示 ERR! sharp EACCES: permission denied, mkdir '/root/.npm' info sharp Are you t ...

  5. 【机器学习基础】无监督学习(2)——降维之LLE和TSNE

    在上一节介绍了一种最常见的降维方法PCA,本节介绍另一种降维方法LLE,本来打算对于其他降维算法一并进行一个简介,不过既然看到这里了,就对这些算法做一个相对详细的学习吧. 0.流形学习简介 在前面PC ...

  6. spring——IOC理论

    这里主要是对于IOC理论提出的一个认识 dao接口 public interface Fruit { String getFruit(); } dao接口的实现类 public class Fruit ...

  7. Nginx--sub_filter模块

    客户端浏览器访问替换html中的字符: location / { root /web/htdocs; random_index on; index index.html index.htm; subs ...

  8. MySQL&SQL server&Oracle&Access&PostgreSQL数据库sql注入详解

    判断数据库的类型 当我们通过一些测试,发现存在SQL注入之后,首先要做的就是判断数据库的类型. 常用的数据库有MySQL.Access.SQLServer.Oracle.PostgreSQL.虽然绝大 ...

  9. Drools 规则引擎应用 看这一篇就够了

    1 .场景 1.1需求 商城系统消费赠送积分 100元以下, 不加分 100元-500元 加100分 500元-1000元 加500分 1000元 以上 加1000分 ...... 1.2传统做法 1 ...

  10. 修道士与野人问题(BFS广度搜索)

    #include "iostream.h" #include "string.h" //定义一个状态节点 typedef struct //存储各个状态 { i ...