MFC---文档与视图结构
文档与视图结构
文档、视图的关系,是一对多的映射,一个文档可以对应多个视图,而一个视图只能对应一个文档。例如,一个
.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---文档与视图结构的更多相关文章
- MFC文档、视图和框架
文档.视图.框架 文档/视图结构是MFC提供的一种不错的设计,它将数据的处理和显示分开来,这样更便于我们对程序的维护和扩展. 文档 文档对象用于管理和维护数据,包括保存数据.取出数据以及 ...
- 理解MFC 文档、视图、框架[转]
理解文档/视图框架 出处.雷神 了解文档和视图的相互作用关系是编写MFC程序的基本功.但是MFC的应用程序框架把文档和视图之间 ...
- 深入分析MFC文档视图结构(项目实践)
k_eckel:http://www.mscenter.edu.cn/blog/k_eckel 文档视图结构(Document/View Architecture)是MFC的精髓,也是Observer ...
- MFC文档视图结构学习笔记
文档/视图概述 为了统一和简化数据处理方法,Microsoft公司在MFC中提出了文档/视图结构的概念,其产品Word就是典型的文档/视图结构应用程序 MFC通过其文档类和视图类提供了大量有关数据处理 ...
- VS2010/MFC编程入门之四十一(文档、视图和框架:分割窗口)
上一节中鸡啄米讲了文档.视图和框架结构中各对象之间的关系,本节主要讲讲在MFC中如何分割窗口. 分割窗口概述 分割窗口,顾名思义,就是将一个窗口分割成多个窗格,在每个窗格中都包含有视图,或 ...
- VS2010/MFC编程入门之三十九(文档、视图和框架:概述)
前面几节讲了菜单.工具栏和状态栏的使用,鸡啄米本节开始将为大家讲解文档.视图和框架的知识. 文档.视图和框架简介 在VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)创建的单文档工 ...
- VS2010/MFC编程入门之四十(文档、视图和框架:各对象之间的关系)
前面一节中鸡啄米进行了文档.视图和框架的概述,本节主要讲解文档.视图.框架结构中各对象之间的关系. 各个对象之间的关系 文档.视图.框架结构中涉及到的对象主要有:应用程序对象.文档模板对象.文档对象. ...
- MFC文档视图中窗口切换 (2012-05-11 18:32:48)
在文档试图应用程序,有时需要在工作区切换试图,以下就是如何切换试图了 .创建要切换的视图类,同时把构造函数,Create函数改变为public .在需要切换试图的动作响应中,加入切换代码,一般是在CM ...
- (九)文档和视图,Invalidate,数据库编程
一.文档视图结构 文档类(CDocument):存储加载(读写)数据视图类(CView):显示和修改数据 1)单文档 a)文档模板:把框架窗口.文档.视图关联在一起b)文档类(CDocument): ...
随机推荐
- 从原理学习Java反序列化
1 序列化与反序列化 1.1 概念 序列化: 将数据结构或对象转换成二进制串的过程 反序列化:将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程 1.2 使用场景 当你想把的内存中的对象状态 ...
- VTK读取数据
#include <vtkSmartPointer.h> #include <vtkSimplePointsReader.h> #include <vtkPolyData ...
- Mybatis——一级缓存与二级缓存
关于Mybatis的学习主要参考了狂神的视频 一级缓存 (1).使用范围:从sqlSession会话开始到结束 (2).使用:默认打开,无法关闭 (3).测试使用(需要打开日志观察数据库的连接情况): ...
- python3输出“水仙花数”
for num in range(100,1000): #如果num在[100,1000)范围,就依次循环取出num的值,第一次取100,下一次取101....最后一次取999 bai = num / ...
- 【OpenHarmony移植案例与原理】XTS子系统之应用兼容性测试用例开发
摘要:本文主要介绍ACTS应用兼容性测试用例开发编译. 本文分享自华为云社区<移植案例与原理 - XTS子系统之应用兼容性测试用例开发>,作者: zhushy . XTS(X Test S ...
- [SPDK/NVMe存储技术分析]006 - 内存屏障(MB)
在多核(SMP)多线程的情况下,如果不知道CPU乱序执行的话,将会是一场噩梦,因为无论怎么进行代码Review也不可能发现跟内存屏障(MB)相关的Bug.内存屏障分为两类: 跟编译有关的内存屏障: 告 ...
- 变频器通讯参数PKW和PZD的含义
SINAMICS S120 S150 参数手册 章节3.9 PROFIdrive 图3-41 功能图2422制造商专用报文和过程数据 参考:https://www.diangon.com/wenku/ ...
- 记录NLTK安装使用全过程--python
前言 之前做实验用到了情感分析,就下载了一下,这篇博客记录使用过程. 下载安装到实战详细步骤 NLTK下载安装 先使用pip install nltk 安装包 然后运行下面两行代码会弹出如图得GUI界 ...
- 使用Spring通过什么方式访问Hibernate?
在Spring中有两种方式访问Hibernate: 控制反转 Hibernate Template和 Callback. 继承 HibernateDAOSupport提供一个AOP 拦截器.
- 请简述下你在哪些场景下会选择 Kafka?
日志收集:一个公司可以用Kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如hadoop.HBase.Solr等. 消息系统:解耦和生产者和消费者.缓 ...