文档与视图结构

  • 文档、视图的关系,是一对多的映射,一个文档可以对应多个视图,而一个视图只能对应一个文档。例如,一个.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. 如何创建一个 Cocoapods 插件

    原文链接 前言 我们在使用 Cocoapods 过程中,如果发现它未能满足我们的要求该怎么办呢? 最简单的粗暴的办法就是 fork 一份 Cocoapods 源码,然后自己公司内部或者个人直接针对源码 ...

  2. numpy: np.logical_and/or/not (逻辑与/或/非)+python3-曲线拟合(polyfit/polyval)

    可以用拟合两个变量之间的关系,然后根据一个变量,去推测出另外一个变量的推测值

  3. Windows原理深入学习系列-信任等级检查

    这是[信安成长计划]的第 23 篇文章 0x00 目录 0x01 介绍 0x02 逆向分析 Win10_x64_20H2 0x03 WinDBG 0x04 参考文章 在之前的时候,一直以为 SACL ...

  4. AQS 详解之共享锁模式

    概括 AQS框架数据结构是一个先进先出的双向队列,当多个线程进行竞争资源时,那些竞争失败的线程会加入到队列中.他向上层提供了很多接口,其中一个是acquireShared获取共享模式的接口.本文将会根 ...

  5. redis不重启,切换到RDB备份到AOF备份

    redis不重启,切换RDB备份到AOF备份 确保redis版本在2.2以上 查看redis版本 redis-server -v 实验环境准备 本文是在redis4.0中,通过config set命令 ...

  6. 『现学现忘』Docker基础 — 31、实现MySQL同步数据

    目录 1.搜索镜像 2.拉取镜像 3.查看镜像 4.启动镜像 5.操作容器 (1)在MySQL中创建数据库 (2)外部连接Dokcer容器中的MySQL服务 (3)查看挂载情况 (4)测试MySQL服 ...

  7. Nebula Graph 在网易游戏业务中的实践

    本文首发于 Nebula Graph Community 公众号 当游戏上知识图谱,网易游戏是如何应对大规模图数据的管理问题,Nebula Graph 又是如何帮助网易游戏落地游戏内复杂的图的业务呢? ...

  8. 在使用Access连接后获取数据--出现此类问题如何解决---未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序解决办法

    转载:https://blog.csdn.net/yyzzhc999/article/details/79367114 using System; using System.Collections.G ...

  9. Unity-2D

    Unity-2D 1.Unity中的2D模式: 1)游戏在二维上展示 启用 2D 模式时将会设置正交(即无透视)视图:摄像机沿 Z 轴观察,而 Y 轴向上增加.因此可以轻松可视化场景并放置 2D 对象 ...

  10. 不会DRF?源码都分析透了确定不来看?

    目录 不会DRF?源码都分析透了确定不来看? 快速使用DRF写出接口 序列化和反序列化 drf快速使用 views.py serializer.py urls.py 在settings的app中注册 ...