文档与视图结构

  • 文档、视图的关系,是一对多的映射,一个文档可以对应多个视图,而一个视图只能对应一个文档。例如,一个.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. 新的ASP.NET Core 迁移指南

    最近在微信里做了一个调查: Web Forms应用程序升级到.NET 6, 收到550份调查,调查还在继续,欢迎参与调查.可以访问链接:https://wj.qq.com/s2/9822949/ac3 ...

  2. [动态规划] 适合DJ银行的日子

    [动态规划] 适合DJ银行的日子 前言:开始的时候用常规模拟做的超时了,然后看官方题解,大致意思就是连续n天单调可以用动态规划的思想 你和一群强盗准备打劫银行.给你一个下标从 0 开始的整数数组 se ...

  3. Jmeter beanshell把数据写入csv文件中,最后清除csv数据

    有时候我们需要使用jmeter去结合csv文件去做一些简单的数据驱动处理: 例如把数据库数据黏贴到csv文件中或者把网页上的数据填入到csv文件中: 直接我一般是用手自己黏贴复制过csv文件中,比较麻 ...

  4. RabbitMQ入门-5.6-课堂笔记-01

  5. 模型 _meta API ( options )

    模型 _meta API class Options[源代码] 模型 _meta API是Django ORM的核心.它使系统的其他部分(如查找,查询,表单和管理员)能够了解每个模型的功能. API可 ...

  6. C++设计模式 - 访问器模式(Visitor)

    行为变化模式 在组件的构建过程中,组件行为的变化经常导致组件本身剧烈的变化."行为变化" 模式将组件的行为和组件本身进行解耦,从而支持组件行为的变化,实现两者之间的松耦合. 典型模 ...

  7. Java基础 - 泛型详解

    2022-03-24 09:55:06 @GhostFace 泛型 什么是泛型? 来自博客 Java泛型这个特性是从JDK 1.5才开始加入的,因此为了兼容之前的版本,Java泛型的实现采取了&quo ...

  8. Redis的持久化方案(三)

    Redis的所有数据都是保存到内存中的. Rdb:快照形式,定期把内存中当前时刻的数据保存到磁盘.Redis默认支持的持久化方案. aof形式:append only file.把所有对redis数据 ...

  9. Java 中会存在内存泄漏吗,请简单描述?

    理论上 Java 因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是 Java 被 广泛使用于服务器端编程的一个重要原因):然而在实际开发中,可能会存在无 用但可达的对象,这些对象不能被 GC 回 ...

  10. ACM - 图论 - P3385 负环

    P3385 负环 题目描述 给定一个 \(n\) 个点的有向图,请求出图中是否存在从顶点 \(1\) 出发能到达的负环. 负环的定义是:一条边权之和为负数的回路. 输入格式 本题单测试点有多组测试数据 ...