MFC单文档视图程序简介
在视图应用程序中,应用程序的数据由文档对象代表,数据的视图由视图对象代表。MFC的Cdocument类是文档对象的基类,Cview类是视图对象的基类。应用程序的主窗口,其操作功能在MFC的CframeWnd和CMDIFrameWnd类中实现,已经不再以消息处理为工作焦点了,主要用作视图、工具栏以及其他用户界面对象的容器。
单文档界面应用程序只支持打开一个文档。
1、 文档、视图基础知识。
图1展示了SDI文档、视图应用程序的示意图。框架窗口是应用程序的顶层窗口,通常带有WS_OVERLAPPEDWINDOW样式的窗口,带有可缩放边框、标题栏等按钮。视图是子窗口,大小与框架窗口相适应,实际中作为框架窗口的客户区。应用程序的数据保存在文档对象中,数据的可视化表示保存在在视图中。对于一个SDI应用程序,框架窗口类是从CframeWnd派生来的,文档类是从Cdocument派生来的,而视图类是从Cview或相关类派生而来的。

图1
文档视图应用程序不会为框架窗口获取客户区设备描述表,而是获得视图的设备描述表并在视图中绘制输出。
2、 文档对象、视图对象、框架窗口对象
2.1 文档对象
在文档视图体系结构中,数据被保存在文档对象中,文档对象在主结构初始化时从Cdocument派生出的类时创建的。这里的文档是广义的,泛指能够保存和处理数据的东西。
通常文档对象为其他对象,主要是视图提供了公用成员函数,使用它可以访问文档的数据。所有数据的处理都由文档对象自己完成。
Cdocument中最常用的两个非虚拟类成员函数是SetModifiedFlag和UpdateAllViews。前者设置或清除文档中已经修改的标志,该标志说明文档是否包含没有保存的数据,通常情况下修改了文档数据之后都要调用该函数。UpdateAllViews命令所有与文档关联的视图更新它们自己。实际上,是UpdateAllViews调用每个视图的OnUpdate函数,其默认操作是使视图无效实现重绘。
Cdocument中还有一些虚函数经常被覆盖。
OnNewDocument,在新文档被创建时,由主结构调用,覆盖它是为了每次创建新文档对象时都对文档对象应用专门的初始化。
OnOpenDocument,在从磁盘上装载文档时,由主结构调用。覆盖它是为了每次装载新文档时都对文档对象应用专门的初始化。
DeleteContents,主结构调用它来删除文档的内容。覆盖它是为了在文档关闭之前释放分配给文档的内存和其他资源。
Serialize,主结构调用它在文档和磁盘之间串行化输出或输入,覆盖它是为了提供针对文档的串行化程序一边文档可以被装载和保存。
通常情况下,文档对象只会在应用程序启动时初始化一次,通过OnNewDocument和OnOpenDocument函数我们可以实现对文档对象的重新初始化。一般来说,MFC应用程序更经常覆盖OnNewDocument而不是OnOpenDocument,因为后者间接调用了Serialize函数,Serialize函数初始化文档的永久数据成员,而如果你用非永久数据成员时,你可以在OnOpenDocument函数中初始化。当你想在新文档被创建时初始化,那么就需要覆盖OnNewDocument函数。在文档被创建或打开前,主结构调用DeleteContents函数删除文档对象的数据。当文档打开或者关闭时会调用Serialize函数将文档的数据写入或写出。
2.2 视图对象
文档对象的任务就是管理应用程序的数据,视图对象就有两个用途:提供文档的可视化表示;将用户输入转换为操作文档数据的命令。视图对象包括了Cview及其派生出来的一系列类,比如CscrollView类。一个文档对象可以对应多个视图对象,但是一个视图对象只能有一个文档对象。通过GetDocument函数我们可以获得自己的文档对象。
Cview中同样包含了几个主要的可覆盖函数。OnDraw,主结构创建CpaintDC对象,并使用该对象调用视图的OnDraw函数。OnInitialUpdate函数在视图第一次附加到文档时被调用,覆盖是为了每次在文档被创建或装载时都初始化视图对象。视图对象也只在程序初始化时构造一次,然后重复使用。在SDI中,每当文档被打开或者创建时,都要调用OnInitialUpdate函数。该函数默认调用OnUpdate。我们可以使用OnInitialUpdate函数初始化视图类的数据成员。UpdateAllViews调用OnUpdate,通常我们覆盖OnUpdate函数让其只重绘更新部分而不是整个视图。
2.3 框架窗口对象
SDI应用程序只有一个框架窗口CframeWnd,用作顶层视图并用来包含视图。在MDI应用应用程序中CMDIFrameWnd用作顶层窗口,CMDIChildWnd窗口在顶层窗口中浮动用来包含应用程序文档的视图。
2.4 总结
整个应用程序中,文档对象最先初始化,之后是框架窗口对象,最后才是视图对象。
3、命令传送过程以及预定义命令ID和命令处理程序
3.1 命令传送过程
框架首先会将消息发送给活动视图处理,如果没有处理视图就会发送给对应的文档对象处理。如果文档对象没有处理,那么该消息会传递给文档模板,接着是框架窗口,最后是应用程序对象。如果都没有处理,那么该消息将被::DefWindowProc函数处理。
记住,只有命令消息和用户界面消息才是这样传递的。标准的Windows消息WM_xxx必须在接收这些消息的窗口中处理,鼠标键盘消息传递给视图,其他的基本上给框架窗口。文档对象和应用程序对象不接收非命令消息。
3.2 预定义的命令ID和命令处理程序
CwinApp、Cdocument、CframeWnd和其他MFC类为常用菜单命令提供了默认处理程序。比如,菜单中的退出选项是默认添加的。你完全可以自己创建和设计自定义的命令ID,并提供消息映射表输入项来关联自己的命令ID和默认的命令处理程序。
MFC单文档视图程序简介的更多相关文章
- VC++ MFC单文档应用程序SDI下调用glGenBuffersARB(1, &pbo)方法编译通过但执行时出错原因分析及解决办法:glewInit()初始化的错误
1.问题症状 在VC++环境下,利用MFC单文档应用程序SDI下开发OpenGL程序,当调用glGenBuffersARB(1, &pbo)方法编译通过但执行时出错,出错代码如下: OpenG ...
- MFC单文档视图中嵌入GLFW窗口
开始学习OpenGL由于有一段时间,但是glfw只有窗口区,虽然通过某种手段(移步这里)可以加入工具栏,但仍然无法作为一个标准的GUI,而直接在MFC或Qt里面使用OpenGL API感觉有诸多制肘, ...
- 【2016.3.30项目技术记录】]VS2010自动生成MFC单文档框架程序的修改:去除属性框,在CViewTree类中添加鼠标单击响应
转自http://blog.csdn.net/yanfeiouc2009/archive/2010/06/07/5653360.aspx 手头上有个东西要用到单文档,由于想省事,直接用VS2010做了 ...
- MFC单文档视图拆分窗口和相关链接
第一步:准备2个视图类(如CTViewOne, CTViewTwo) 第二步:在CMainFrame类的头文件中添加数据成员变量: //MainFrm.h protected: CSplitterWn ...
- VC-基础:MFC单文档程序架构解析
MFC单文档程序架构解析 这里我以科院杨老师的单文档程序来分析一下MFC单文档的程序架构,纯属个人见解,不当之处烦请指教! 首先我们了解到的是 图(一) theApp 是唯一一个在程序形成的时候就存在 ...
- MFC单文档程序架构解析
MFC单文档程序架构解析 MFC单文档程序架构解析 这里我以科院杨老师的单文档程序来分析一下MFC单文档的程序架构,纯属个人见解,不当之处烦请指教! 首先我们了解到的是 图(一) theApp 是唯一 ...
- VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)
VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)-软件开发-鸡啄米 http://www.jizhuomi.com/software/141.html 上一讲中讲了VS20 ...
- MFC中 创建基于CFormView的文档视图程序
在MFC中可以创建多种类型的窗口程序,如对话框程序.单文档结构程序(非文档/视图结构).单文档(文档/视图结构)以及多文档视图结构程序等. 在编写一般的小工具时,我们的首选显然是对话框程序,不过基于对 ...
- 如何优雅的写UI——(2)MFC下基于CFormView的文档视图程序
在MFC中可以创建多种类型的窗口程序,如对话框程序.单文档结构程序(非文档/视图结构).单文档(文档/视图结构)以及多文档视图结构程序等. 在编写一般的小工具时,我们的首选显然是对话框程序,不过基于对 ...
随机推荐
- mysql学习笔记--go使用mysql
一. 连接数据库 a. //用户名:密码@[连接方式](主机名:端口号)/数据库名 db,_:=sql.Open("mysql","root:7758521123jf@( ...
- B/S架构与C/S架构
一,概念: 首先软件体系结构定义了软件的局部和总体计算的构成,以及这些部件之间的相互作用关系.部件包括诸如服务器,客户,数据库,过滤器,程序包,过程,子程序等一切软件的 组成成分. C/ ...
- 计算C#程序执行时间
static void SubTest() { DateTime beforDT = System.DateTime.Now; //耗时巨大的代码 ...
- Spring+Quartz集群环境下定时调度的解决方案
集群环境可能出现的问题 在上一篇博客我们介绍了如何在自己的项目中从无到有的添加了Quartz定时调度引擎,其实就是一个Quartz 和Spring的整合过程,很容易实现,但是我们现在企业中项目通常都是 ...
- jmeter的各种调用
1. 开发将dubbo协议的接口转化成了webservices后,jmeter直接添加http请求,输入网址就好,但是这种需要增加开发测试页面的工作量 2.jmeter自身无法调用zk连接服务器(Jm ...
- CSS3--2D&3D的使用
transform 过渡属性 向元素进行2D或3D转换 transform-origin:该元素基于某个点来旋转 transform-style: preserve-3d 规定嵌套元素如何在3D空间 ...
- java进阶系列之装饰器模式
1.介绍 装饰器模式顾名思义就是装饰某个对象的,是一种结构型模式.装饰器模式允许向一个现有对象添加新的功能,同时不改变其结构,用户可以随意的扩展原有的对象.它是作为现有的类的一个包装.装饰器模式一方面 ...
- JavaScript数据类型,构造函数
JavaScript 的数据类型分为两类:原始类型和对象类型. JavaScript中的原始类型包括数字.字符串和布尔值 JavaScript中有两种特殊的原始值:null和undefined. Ja ...
- mysql锁机制(Innodb引擎)
InnoDB实现了两种类型的行锁. 共享锁(S):允许一个事务去读一行,阻止其他事务获得相同的数据集的排他锁. 排他锁(X):允许获得排他锁的事务更新数据,但是组织其他事务获得相同数据集的共享锁和排他 ...
- IDEA 错误: 找不到符号
在IDEA添加了一个新的Mapper.xml文件,然后删除,重新编译该文件所在的模块时,提示我编写的类找不到符合. 解决方法:右键.java文件,选择“complile ....”(ctrl+shif ...