C++ 编程 第十章 文档视图结构
- 格式:ppt
- 大小:527.50 KB
- 文档页数:19
VC随笔文档视图结构使用断点调试观察MFC应用程序框架的创建过程:由于一个对象被创建时会自动调用构造函数,而一个窗口被创建时会调用OnCreate函数,因此在下列地方设置断点:1、应用程序类、文档类、框架窗口类、视图类的构造函数开始处(函数开始大括号所在行)2、CMy2DCADApp::InitInstance函数开始处、添加文档模板处、结尾处(函数结束大括号所在行)3、CMainFrame::OnCreate函数开始处、结尾处设置完断点后,按F5键,程序进入调试状态,可见在编辑窗口中,程序首先停止在应用程序类CMy2DCADApp 的构造函数中,说明程序最初构造的是应用程序类对象。
再按一次F5,编辑窗口中的黄色箭头停留在CMy2DCADApp::InitInstance函数的开始处,表明此时MFC框架中的WinMain函数开始执行,并调用了应用程序类的InitInstance函数。
再按一次F5,编辑窗口中的黄色箭头停留在InitInstance函数中添加文档模板对象处。
此时文档模板对象被创建。
再按一次F5,编辑窗口中的黄色箭头停留在文档类CMy2DCADDoc的构造函数开始处,表明开始创建文档对象。
再按一次F5,编辑窗口中的黄色箭头停留在框架窗口类CMainFrame的构造函数开始处,表明开始创建框架窗口类对象。
再按一次F5,编辑窗口中的黄色箭头停留在框架窗口类CMainFrame::OnCreate函数开始处,表明开始创建框架窗口。
再按一次F5,编辑窗口中的黄色箭头停留在视图类CMy2DCADView的构造函数开始处,表明开始创建视图类对象。
再按一次F5,编辑窗口中的黄色箭头停留在CMainFrame::OnCreate函数结尾处,表明视图窗口和框架窗口都已经创建完毕。
再按一次F5,编辑窗口中的黄色箭头停留在CMy2DCADApp::InitInstance函数的结尾处,表明程序初始化完毕。
文档/视图结构一、文档/视图的概念●在MFC中,文档类负责管理数据,提供保存和加载数据的功能。
视图类负责数据的显示,以及给用户提供对数据的编辑和修改功能。
●MFC给我们提供Document/View结构,将一个应用程序所需要的“数据处理与显示”的函数空壳都设计好了,这些函数都是虚函数,我们可以在派生类中重写这些函数。
有关文件读写的操作在CDocument的Serialize函数中进行,有关数据和图形显示的操作在CView的OnDraw函数中进行。
我们在其派生类中,只需要去关注Serialize和OnDraw 函数就可以了,其它的细节我们不需要去理会,程序就可以良好地运行。
●当我们按下“打开文件”菜单项时,Application Framework会激活打开文件对话框,让你指定文件名,然后自动调用CMiniCADDoc::Serialize读取文件。
Application Framework 还会调用CMiniCADView::OnDraw,传递一个显示DC,让你重新绘制窗口内容。
●MFC给我们提供Document/View结构,是希望我们将精力放在数据结构的设计和数据显示的操作上,而不要把时间和精力花费在对象与对象之间、模块与模块之间的通信上。
●一个文档对象可以和多个视图类对象相关联,而一个视图类对象只能和一个文档对象相关联。
●MFC对“文档”的设计思想是:一个类中的所有成员变量,都应该能够保存到一个文件中去,反之,也应该能从一个文件中读出来,加载到该类相应的成员变量中去。
MFC 对此的实现机制就是文档/视图的串行化(Serialize)。
二、串行化基础知识:使用CArchive类对存储在内存中的变量进行存取。
打开“006菜单工具栏状态栏”一章中的项目“2MiniCAD_图形保持”,添加菜单项“写文件”和“读文件”,对应代码如下:void CMiniCADDoc::OnFileWrite(){CFile file("C:\\1.dat", CFile::modeCreate | CFile::modeWrite);CArchive ar(&file, CArchive::store); //将CFile类和CArchive类关联起来,保存//ar.IsStoring();int i = 4;char ch = 'a';float f = 1.3f;CString str("ITJob");ar << i << ch << f << str;AfxMessageBox("成功写入数据到文件C:\\1.dat");}以二进制形式查看C:\1.dat文件的内容,如下void CMiniCADDoc::OnFileRead(){CFile file("C:\\1.dat", CFile::modeRead);CArchive ar(&file, CArchive::load); //将CFile类和CArchive类关联起来int i;char ch;float f;CString str;CString strResult;ar >> i >> ch >> f >> str;strResult.Format("从文件C:\\1.dat成功读取到数据:%d, %c, %f, %s", i, ch, f, str);AfxMessageBox(strResult);}上述代码说明,CArchive类具有对文件的读写功能,可以通过其流操作符<<将变量存入文件,通过>>将文件中的数据读取到变量中来。
文档/视图在MFC1.0中,应用程序有两个主要的组件:代表应用程序自身的应用程序对象和代表应用程序窗口的窗口对象。
应用程序对象的主要任务是创建窗口,反过来窗口再处理消息。
MFC几乎就是对WindowsAPI的封装。
在MFC2.0中,引入文档/视图体系结构,改变了MFC应用程序编制的方式。
在Doc/View中,应用程序的数据由文档对象代表,而数据的视图由视图对象代表。
文档和视图合作来处理用户的输入并绘制结果数据的文字和图形表示。
应用程序的主窗口,其操作功能在CFrameWnd和CMDIFrameWnd 类中实现,已经不再以消息处理为工作焦点了,而是作为视图,工具栏以及其他用户界面对象的容器。
利用MFC体系结构的好处是简化了开发过程,主结构提供了处理常规杂务的程序代码。
现在程序开发者对于使用MDI并不积极,这是由于SDI模型改善了以文档为中心的用户界面。
如果用户想同时编辑两个文档,Microsoft 更加愿意每个文档都在分开的应用程序实例中显示。
因此要以单文档为重点。
框架窗口是应用程序的顶层窗口,通常是WS_OVERLAPPEDWINDOW样式的窗口,带有可缩放边框,带有标题栏,系统菜单和最小,大化按钮和关闭按钮。
视图是子窗口,实际中作为框架窗口的客户区。
应用程序对象提供消息循环给框架窗口和视图提取消息。
视图对象将鼠标和键盘输入转换为处理保存在文档中的数据的命令,文档对象提供了视图所需要的用来输出的数据。
文档/视图应用程序从来不会为框架窗口获取客户区设备描述表并在其中绘制输出,相反它绘制输出到视图中。
看上去好像在框架窗口中绘制,实际上所有输出都输出到视图中。
如果愿意,可以给框架窗口绘制内容,但是您看不到任何结果,因为SDI框架窗口的客户区完全被视图遮盖了。
SDI文档模板CSingleDocTemplate是SDIDoc/View中最重要的部分。
RUNTIME_CLASS宏对于所指定的类返回指向了CRuntimeClass结构的指针,这就使得主结构可以在运行时创建这些类的对象了。
深入浅出MFC“文档/视图”架构(1)基本概念作者:宋宝华 e-mail:21cnbao@1.引言MFC引入了“文档/视图”结构的概念,理解这个结构是编写基于MFC编写复杂Visual C++程序的关键。
“文档/视图”中主要涉及到四种类:(1)文档模板:class CDocTemplate; // template for document creationclass CSingleDocTemplate; // SDI supportclass CMultiDocTemplate; // MDI support(2)文档:class CDocument; // main document abstraction(3)视图:// views on a documentclass CView; // a view on a documentclass CScrollView; // a scrolling view(4)框架窗口:// frame windowsclass CFrameWnd; // standard SDI frameclass CMDIFrameWnd; // standard MDI frameclass CMDIChildWnd; // standard MDI childclass CMiniFrameWnd; // half-height caption frame wnd理解了这4个类各自的意义及它们纵横交错的关系也就理解了“文档/视图”结构的基本概念,在此基础上,我们还需要进一步研究“文档/视图”结构的MFC程序消息流动的方向,这样就完全彻底明白了基于“文档/视图”结构MFC程序的“生死因果”。
出于以上考虑,本文这样组织了各次连载的内容:第1次连载进行基本概念的介绍,第2~5次连载分别讲述文档模板、文档、视图和框架窗口四个类的功能和主要函数,连载6则综合阐述四个类之间的关系,接着以连载7讲解消息流动的方向,最后的连载8则以实例剖析连载1~7所讲述的所有内容。
文档视图结构窗口全屏显示1)在CMainFrame类中,增加如下三个成员变量。
private:WINDOWPLACEMENT m_OldWndPlacement; //用来保存原窗口位置BOOL m_bFullScreen; //全屏显示标志初始状态为FALSECRect m_FullScreenRect; //表示全屏显示时的窗口位置2)响应全屏显示菜单函数void CMainFrame::OnFullScreen(){GetWindowPlacement(&m_OldWndPlacement);CRect WindowRect;GetWindowRect(&WindowRect);CRect ClientRect;RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery, &C lientRect);ClientToScreen(&ClientRect);// 获取屏幕的分辨率int nFullWidth=GetSystemMetrics(SM_CXSCREEN);int nFullHeight=GetSystemMetrics(SM_CYSCREEN);// 将除控制条外的客户区全屏显示到从(0,0)到(nFullWidth, nFullHeight)区域, 将(0,0)和(nFullWidth, nFullHeight)两个点外扩充原窗口和除控制条之外的客户区位置间的差值, 就得到全屏显示的窗口位置m_FullScreenRect.left=WindowRect.left-ClientRect.left;m_FullScreenRect.top=WindowRect.top-ClientRect.top;m_FullScreenRect.right=WindowRect.right-ClientRect.right+nFu llWidth;m_FullScreenRect.bottom=WindowRect.bottom-ClientRect.bottom+nFullHeight;m_bFullScreen=TRUE; // 设置全屏显示标志为 TRUE// 进入全屏显示状态WINDOWPLACEMENT wndpl;wndpl.length=sizeof(WINDOWPLACEMENT);wndpl.flags=0;wndpl.showCmd=SW_SHOWNORMAL;wndpl.rcNormalPosition=m_FullScreenRect;SetWindowPlacement(&wndpl);}3)重载CMainFrame类的OnGetMinMaxInfo函数,在全屏显示时提供全屏显示的位置信息。
第2章文档/视图结构应用程序2.0 知识要点1. 文档/视图结构的思想是将数据的管理与显示分离,其中文档用于管理应用程序的数据,而视图是用户界面,用于显示、打印文档中的数据,并管理与用户的交互。
2. SDI具有文档/视图结构的应用程序框架,该框架包括应用程序类、窗口框架类、文档类和视图类,编程的任务是在文档类和视图类中添加适当的代码。
其中文档类中一个重要的成员函数是OnNewDocument(),用户在此添加代码完成对数据的初始化;而视图类中最重要的成员函数是OnDraw(),通过在该函数中添加代码实现窗口内容的输出。
3. 通过介绍几种SDI结构的典型应用程序来了解其结构及设计方法,典型应用包括:•利用画笔、画刷等工具及位图处理的方法实现文字和图形的输出。
•利用定时器控件制作动画程序。
•对鼠标和键盘进行编程的基本方法。
•文件、字体、颜色等几种通用对话框的使用方法及自定义对话框的设计、调用方法。
•菜单的设计方法。
2.1 文档/视图结构SDI 应用程序由 AppWizard 创建好后,即使没有编写一行代码,仍然可以运行,并且具有一个标准 Windows应用程序所需要的组成成份,程序员的工作就是往这个框架添加必要的代码。
以下通过一个简单实例说明文档/视图结构应用程序的创建过程。
【例2-1】创建一个如图所示的应用程序,在窗口中显示一个矩形框,框中显示“同舟共济自强不息”。
假定本例的工程名为TEST,程序创建过程如下:(1)利用 AppWizard 创建一个 SDI 应用程序框架。
(2)文档类是存放数据的主要地方,本例在其中说明一个存放矩形框数据的 CRect 类对象 r 和一个存放字符串的 CString 对象s,方法为:在工作区的“ ClassView ”中,双击 CTESTDoc 类,在该类代码中添加如下代码:public:CRect r;CString s;说明:CRect 是 MFC 定义的一个类,有 4 个数据成员: left 、 top 、 right 和bottom 。