在视图应用程序中,应用程序的数据由文档对象代表,数据的视图由视图对象代表。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单文档视图程序简介的更多相关文章

  1. VC++ MFC单文档应用程序SDI下调用glGenBuffersARB(1, &pbo)方法编译通过但执行时出错原因分析及解决办法:glewInit()初始化的错误

    1.问题症状 在VC++环境下,利用MFC单文档应用程序SDI下开发OpenGL程序,当调用glGenBuffersARB(1, &pbo)方法编译通过但执行时出错,出错代码如下: OpenG ...

  2. MFC单文档视图中嵌入GLFW窗口

    开始学习OpenGL由于有一段时间,但是glfw只有窗口区,虽然通过某种手段(移步这里)可以加入工具栏,但仍然无法作为一个标准的GUI,而直接在MFC或Qt里面使用OpenGL API感觉有诸多制肘, ...

  3. 【2016.3.30项目技术记录】]VS2010自动生成MFC单文档框架程序的修改:去除属性框,在CViewTree类中添加鼠标单击响应

    转自http://blog.csdn.net/yanfeiouc2009/archive/2010/06/07/5653360.aspx 手头上有个东西要用到单文档,由于想省事,直接用VS2010做了 ...

  4. MFC单文档视图拆分窗口和相关链接

    第一步:准备2个视图类(如CTViewOne, CTViewTwo) 第二步:在CMainFrame类的头文件中添加数据成员变量: //MainFrm.h protected: CSplitterWn ...

  5. VC-基础:MFC单文档程序架构解析

    MFC单文档程序架构解析 这里我以科院杨老师的单文档程序来分析一下MFC单文档的程序架构,纯属个人见解,不当之处烦请指教! 首先我们了解到的是 图(一) theApp 是唯一一个在程序形成的时候就存在 ...

  6. MFC单文档程序架构解析

    MFC单文档程序架构解析 MFC单文档程序架构解析 这里我以科院杨老师的单文档程序来分析一下MFC单文档的程序架构,纯属个人见解,不当之处烦请指教! 首先我们了解到的是 图(一) theApp 是唯一 ...

  7. VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)

    VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)-软件开发-鸡啄米 http://www.jizhuomi.com/software/141.html   上一讲中讲了VS20 ...

  8. MFC中 创建基于CFormView的文档视图程序

    在MFC中可以创建多种类型的窗口程序,如对话框程序.单文档结构程序(非文档/视图结构).单文档(文档/视图结构)以及多文档视图结构程序等. 在编写一般的小工具时,我们的首选显然是对话框程序,不过基于对 ...

  9. 如何优雅的写UI——(2)MFC下基于CFormView的文档视图程序

    在MFC中可以创建多种类型的窗口程序,如对话框程序.单文档结构程序(非文档/视图结构).单文档(文档/视图结构)以及多文档视图结构程序等. 在编写一般的小工具时,我们的首选显然是对话框程序,不过基于对 ...

随机推荐

  1. excel 上传读写到数据库

    <HTML> <div class="input-group"> <form id="abc" action="http ...

  2. PCIE 3.0中使用的动态均衡概念

    一.PCIE 3.0中使用的动态均衡概念 因为PCIE 3.0信号的速率可以达到8Gb/s,而且链路通道走线也可能会很长,这可能会导致高速信号衰减过大,在接收端无法得到张开的眼图.因此在PCIE 3. ...

  3. swift 关于FDFullscreenPopGesture的右滑返回

    关于导航栏右滑返回的工具库 FDFullscreenPopGesture 是 OC 版本,用了 runtime 等各种骚操作 关于 swift ,我在 UINavigationController 的 ...

  4. struts1.x 核心控制器 和 用户自定义控制器扩展类;

    ServletAction继承于HttpServlet,是struts1.x中和核心控制器. 配置于web.xml文件中,指定config属性,该config属性用于指定formBean和action ...

  5. HihoCoder - 1103 Colorful Lecture Note

    Little Hi is writing an algorithm lecture note for Little Ho. To make the note more comprehensible, ...

  6. 探索未知种族之osg类生物---渲染遍历之裁剪一

    前言 上面我们用了四节课的内容,讲解了一些osg概念性的内部原理.希望大家可以再看今天的讲解之前先再仔细的研究一下前四节的内容.这样你就会对整个osg的渲染过程有一个更加清晰的认知,有助于理解下面两个 ...

  7. 非root用户启动redis容器报错mkdir: cannot create directory '/bitnami/redis': Permission denied

    问题:使用docker启动容器时,报错如下 zh@debian:~/testPath$ docker-compose up redis Starting testpath_redis_1 ... do ...

  8. yii2.0 邮件发送如何配置

    邮件发送配置: 打开配置文件将下面代码添加到 components => [...]中(例:高级版默认配置在/common/config/main-local.php)         'mai ...

  9. 天然气管道Gaz[POI2007]

    --BZOJ1034 题目描述 Mary试图控制成都的天然气市场.专家已经标示出了最好的天然气井和中转站在成都的地图.现在需要将中转 站和天然气井连接起来.每个中转站必须被连接到正好一个钻油井,反之亦 ...

  10. python14 常用模块 二

    一.json模块 强大:不同语言之间可以进行数据交换 序列化:把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serializati ...