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中可以创建多种类型的窗口程序,如对话框程序.单文档结构程序(非文档/视图结构).单文档(文档/视图结构)以及多文档视图结构程序等. 在编写一般的小工具时,我们的首选显然是对话框程序,不过基于对 ...
随机推荐
- Polar Code(1)关于Polar Code
Polar Codes于2008年由土耳其毕尔肯大学Erdal Arikan教授首次提出,Polar Codes提出后各通信巨头都进行了研究.2016年11月18日(美国时间2016年11月17日), ...
- selenium之 chromedriver与chrome版本映射表(更新至v2.46)
chromedriver版本 支持的Chrome版本 v2.46 v71-73 v2.45 v70-72 v2.44 v69-71 v2.43 v69-71 v2.42 v68-70 v2.41 v6 ...
- statrc部分
statrc部分 1. 如何使用 #- 在app中编写 stark.py #- 在stark.py中进行定制 #- 默认配置: #site.register(models.UserInfo) #- 自 ...
- java socket编程(一)简介
#Java TCP Ip编程 其实下面几张图片就可以解释简单解释tcp-ip协议的大体流程了. ###计算机网络,分组报文和协议 网络是一组通过通信信道相互连接的机器组成. 组与组之间通过路由器连接 ...
- tomcat设置开机自动启动
windows下: 1 命令cmd 进入 磁盘: 回车 2 tomcat\bin目录 回车 3 service.bat install (注:tomcat一定要有service.bat ...
- java中函数的参数传递
转载 https://www.cnblogs.com/lixiaolun/p/4311863.html 转载https://www.cnblogs.com/wutianqi/p/8723582.ht ...
- oo第12次作业
一.规格化设计发展历史 在上世纪60年代,由于程序猿们难以忍受超级难懂的机器语言和稍微好懂一点点的汇编语言,便发明了结构化的程序语言,使得程序猿们能愉快地编写复杂程度适中的程序.但是需求是在不断增长的 ...
- java的线程中断
在java中中断线程可以使用interrupt()函数.此函数虽然不能终止线程的运行,但是可以改变线程的状态为true 即:isInterrupted()的值返回为true 注意:当函数调用了已经被阻 ...
- PID25 / 合并果子 ☆
这里用到了STL里面的priority_queue,我也不是很精通基本上属于现学现卖阶段,http://www.cnblogs.com/flyoung2008/articles/2136485.htm ...
- WCF调错方法
1.在VS cmd里,输入wcftestclient.exe 2.添加Service服务. 3.点击要测试的方法,输入参数,点击Invoke. 4.如果错误信息很模糊,则修改WCF程序所在的Web.c ...