第八章文档视图结构的高级形式.ppt
《第八章文档视图结构的高级形式.ppt》由会员分享,可在线阅读,更多相关《第八章文档视图结构的高级形式.ppt(131页珍藏版)》请在三一办公上搜索。
1、第八章 文档视图结构的高级形式,在具有文档视图结构的应用程序中,文档数据的初始化、更新、保存等一般由文档类对象完成;视图类对象则提供表示文档数据的人机界面。文档类与视图类对各自任务完成的这种相对独立性与 MFC 应用程序框架带给它们的关联性,造就了文档视图组合形式的多样性,这给应用程序带来了丰富的特性。本章将介绍 SDI、MDI 应用程序文档视图组合的多种形式。,8.1 文档视图结构组合的多种形式8.1.1 MDI 与 SDI 程序的区别 比较 MDI 与 SDI 应用程序的文档视图结构,MDI 应用程序有以下几个特点:可以同时打开多个文档,每个文档有各自的子框架窗口;主窗口的菜单可以随着当前
2、激活的文档类型发生变化;子框架窗口可以进行布局方式(层叠、平铺)等各项操作;子框架窗口可以在 MDI 主窗口区域内定位、改变大小、最大 化和最小化等放置操作,当最大化子框架窗口时,它将占满 MDI 主窗口的全部客户区;,MDI 不仅可以同时打开多个文档,还可以为每个文档同时建 立多个视图。如果在主框架窗口的 Window 子菜单中选择 New 菜单项功能,就为激活的视图窗口复制一个视图窗口。其中,文档的子框架窗口在 MDI 主框架窗口客户区中的定位、改变大小、最大化、最小化和 Window-New 功能都已经成为MDI 应用程序的标准功能,均在主框架窗口类的基类中已经实现,因此,用户一般无需再
3、增加新的操作。每个 MDI 应用程序的主框架窗口是 CMDIFrameWnd 类或其派生类的实例。CMDIFrameWnd 的基类是 CFrameWnd,它除了拥有CFrameWnd 框架窗口类的全部特性外,还具有下列与 MDI 相关的特性:,主框架窗口,文档窗口,客户窗口,主框架窗口并不直接与一个文档和视图相关联。但它拥有一 个子帧窗口(又称为 MDI 客户窗口),当主框架窗口的控制栏(包括工具栏、状态栏以及其他控制栏甚至菜单)显示或隐藏 时,该子帧窗口将重新定位,这一点与 SDI 框架窗口不同。MDI 主框架的客户窗口是 MDI 子框架窗口的直接父窗口,它 负责管理主框架窗口的客户区以及创
4、建子框架窗口。每个 MDI 主框架窗口都有且只有一个 MDI 客户窗口。MDI 子框架 窗口是 CMDIChildWnd 派生类的实例,CMDIChildWnd 的基类也 是 CFrameWnd,作为视图的框架窗口,相当于 SDI 的主框架 窗口。,每打开一个文档,框架就自动为文档创建一个子框架窗口,MDI 应用程序负责动态地创建和删除这些子框架窗口;在任何时刻,最多只有一个子框架窗口是激活的,MDI 主框 架窗口始终与当前激活子框架窗口相关联,命令消息在传给 MDI 主框架窗口之前首先传送给当前激活的子框架窗口。在没有任何激活的子窗口时,主框架窗口使用与主框架窗口 关联的菜单,当有激活子窗口
5、时,主框架窗口的菜单会自动 被与子框架窗口相关联的菜单所替代。主框架窗口的基类为子框架窗口的层叠或平铺排列和新建子 框架窗口等一些标准窗口管理操作提供了菜单命令的响应操 作,因此一般不需要重新定义这类消息的响应函数。,MDI 小结:1.文档视图模板的基本概念 文档模板对象是由子框架窗口类、视图窗口类和文档类的运 行时信息,以及相应的资源 ID 组合而成的;一个应用程序中可以有多个同类或不同类文档模板对象;一个子框架窗口中可以包含一个或多个视图窗口;一个视图对象必须与一个且只与一个文档对象关联;一个文档对象可以与多个不同的视图对象关联;2.文档视图模板实例中各个对象的检索关系 在应用程序类对象中
6、可以检索特定的文档模板对象;在文档模板对象中可以检索特定的文档对象;在主框架窗口对象中可以检索所有显示的子框架窗口对象;在文档对象中可以检索所关联的所有视图对象;,8.1.2 文档视图的多种组合形式 在 SDI 和 MDI 两种应用程序结构中,文档和视图的组合形式可以有多种。这取决于以什么形式、方式把文档展示出来。其中切分窗口和切换视图是以多种视图形式展示文档内容的常用方式。应用程序中的切分窗口具有以下特点:切分窗口一般是定义在 SDI 的主框架窗口或 MDI 的子框架窗 口中,它占据了框架窗口的客户区区域;切分窗口将框架窗口客户区划分为若干窗格,每个窗格定义 为一个视图框架,这些窗格中的视图
7、可以是同一视图类的实 例,也可以是不同视图类的实例;窗格的划分个数和布局由窗口切分种类和窗格的初始化代码 确定,并可以通过鼠标拖动切分隔离条动态调整;,切分窗口是由 MFC 的 CSplitterWnd 类对象实现的。切分窗口 的创建是在框架窗口创建之后,视图窗口创建之前完成的;切分窗口不是应用程序框架的基本类,一般不参加命令消息 传递过程(即一般不安排消息映射和消息处理),而切分窗 口各窗格中的视图类却是命令消息传递过程中的一部分;切分窗口中窗格的一次划分是有限定的,静态切分窗口的窗 格不超过 16X16,而动态切分窗口的窗格不超过 2X2。切换视图就是在不使用切分窗口的情况下,在框架窗口的
8、客 户区轮换显示一个文档的多个视图,从而在同一位置以不同 形式显示文档内容。,综合两种同一文档多视图的显示方式,常见的文档视图的组合形式有:SDI 动态切分窗口应用程序;MDI 动态切分窗口应用程序;SDI 静态切分窗口应用程序;MDI 静态切分窗口应用程序;无切分窗口的 SDI 多视图切换应用程序;无切分窗口的 MDI 多视图切换应用程序本章将通过不同的实例分别叙述各类文档视图的组合形式。,8.2 实例1:动态切分窗口的 SDI 应用程序1 生成新项目 使用AppWizard 生成一个名为“Prog1”的 SDI 应用程序项目。在生成过程中除了进行窗口切分设置(如 所述),其他 各步都可选择
9、默认设置。使用 Visual C+6.0 可在 step 4 of 6 中单击 Advanced 按钮,显 示 Advanced Option 对话框。在 Window Style 属性页中,选中 Use split window 复选框,其他设置保持原有默认选择,这将导 致 AppWizard 在主框架窗口类的定义中添加一个 CSplitterWnd 类对象,并增加创建切分窗口的相应代码。,使用 Visual C+.NET,在项目创建过程中实现上述操作的方法 如下:,2 查看与切分窗口相关的代码 在 CMainFrame 类定义中自动增加了 CSplitterWnd 对象成员,并重新定义了基
10、类的虚函数 OnCreateClient:class CMainFrame:public CFrameWnd protected:CSplitterWnd m_wndSplitter;public:virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs,CCreateContext*pContext);,在虚函数 OnCreateClient 中实现主框架窗口的切分 该函数在主框架窗口创建之后,创建视图窗口之前被调用,一般在该函数中创建切分窗口和视图窗口。代码如下:BOOL CMainFrame:OnCreateClient(LPCREATESTRUCT
11、/*lpcs*/,CCreateContext*pContext)return m_wndSplitter.Create(this,2,2,/TODO:adjust the number of rows,columnsCSize(10,10),/TODO:adjust the minimum pane sizepContext);,切分窗口的创建函数原型如下:BOOL Create(CWnd*pParentWnd,/切分窗口的父窗口指针。int nMaxRows,int nMaxCols,/切分窗口的切分行和列。SIZE sizeMin,/窗格显示的最小尺寸。CCreateContext*pC
12、ontext,/创建切分窗口的场境参数。DWORD dwStyle=WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|SPLS_DYNAMIC_SPLIT,/切分窗口的风格。UINT nID=AFX_IDW_PANE_FIRST);/切分窗口的ID。该函数的功能是创建一个动态的切分窗口。,CMainFrame:OnCreateClient 函数被调用的位置如下框图所示:,创建CMainFrame窗口,在子菜单“查看”(View)中增加了菜单项“分隔”,用于发出 切分命令,其标识值为 ID_WINDOW_SPLIT。MFC 定义了一系 列默认命令,用于调用相应类
13、的标准窗口操作。详细参见 MSDN 的相关部分内容。,3 修改视图类的成员函数 OnDraw 在视图中显示文本串“Visual C+Programming”。void CProg1View:OnDraw(CDC*pDC)CProg1Doc*pDoc=GetDocument();ASSERT_VALID(pDoc);/TODO:add draw code for native data here CRect rc;GetClientRect(4 编译运行“Prog1”,8.3 实例2:动态切分窗口的 MDI 应用程序1 生成新项目 使用 AppWizard 生成一个名为“Prog2”的 MDI
14、应用程序项目。在生成过程中除了在 step 4 of 6中进行窗口切分设置(如 所述),其他各步都选择默认设置。设置子框架窗口的切分属性,方法同前。使得子框架窗口类 中添加 CSplitterWnd 类对象,并添加相应的创建切分子框架窗 口的代码。,2 查看与窗口切分相关的代码 在 CChildFrame 中添加了 CSplitterWnd 对象成员,并重新定义 了基类的虚函数 OnCreateClient:class CChildFrame:public CMDIChildWnd DECLARE_DYNCREATE(CChildFrame)protected:CSplitterWnd m_w
15、ndSplitter;public:virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs,CCreateContext*pContext);,在虚函数 OnCreateClient 中实现子框架窗口的切分 该函数在子框架窗口创建之后,创建视图窗口之前被调用,一般在该函数中创建切分窗口和视图窗口。代码如下:BOOL CChildFrame:OnCreateClient(LPCREATESTRUCT/*lpcs*/,CCreateContext*pContext)return m_wndSplitter.Create(this,2,2,/TODO:adju
16、st the number of rows,columnsCSize(10,10),/TODO:adjust the minimum pane sizepContext);,在子框架窗口菜单的“窗口”(Window)子菜单中添加了菜单项“分隔”,用于发出切分命令,其标识为 ID_WINDOW_SPLIT。,3 修改视图类成员函数 OnDraw 在视图中显示文本串“Visual C+Programming”。void CProg2View:OnDraw(CDC*pDC)CProg2Doc*pDoc=GetDocument();ASSERT_VALID(pDoc);/TODO:add draw c
17、ode for native data here CRect rc;GetClientRect(,4 编译运行“Prog2”,小结:在框架窗口类中增加一个窗口切分类CSplitterWnd的对象成员;重新定义框架窗口类(SDI的主框架窗口,MDI的子框架窗口)的 成员函数OnCreatClient;在OnCreatClient的定义中调用CSplitterWnd:Create完成对框架 窗口类对象的客户窗口的动态切分(至多22),并与文档视图 模板实例的视图对象关联。,8.4 静态切分窗口的多视图 SDI 应用程序 从前面的实例不难看出,动态切分虽然将框架窗口的客户区切分成多个窗格,但每个窗格
18、中只能共用同一视图,这就不能充分体现文档视图提供的多视图特性。这是动态切分窗口的一个特点。下面开始使用切分窗口的另一种形式 静态切分窗口,它的特点是每个窗格中的视图类可以不同。,1 生成新项目 使用 AppWizard 生成一个名为“Prog3”的 SDI 应用程序项目。设置主框架窗口的切分属性,方法同前。使得子框架窗口类 中添加 CSplitterWnd 类对象,并添加相应的创建切分主框架窗 口的代码。修改视图类的基类为 CScrollView,并将缺省的类名修改为 CDigitView,类定义文件名和实现文件名分别修改为 DigitView.h 和 DigitView.cpp。,2 增加文
19、档类数据成员和相应的数据类操作 在文档类 CProg3Doc 中增加一个数组模板类对象数据成员:CArray m_nArray,用于存放一组数据。这组数据将在文档所关联的不同视图中以不同的形式被显示。为了使用数组模板类,必须在 StdAfx.h 中加入相应的系统头 文件:#endif/_AFX_NO_AFXCMN_SUPPORT#include,在 CProg3Doc 类定义中添加数组模板类数据成员 m_nArray 的 定义:class CProg3Doc:public CDocument protected:/create from serialization only CProg3Doc
20、();DECLARE_DYNCREATE(CProg3Doc)/Attributes public:CArray m_nArray;,修改 CProg3Doc 构造函数,加入对 m_nArray 的初始化代码:CProg3Doc:CProg3Doc()/TODO:add one-time construction code here m_nArray.SetSize(10,0);/size and increase of array m_nArray0=3;m_nArray1=4;m_nArray2=8;m_nArray3=20;m_nArray4=12;m_nArray5=17;m_nArr
21、ay6=11;m_nArray7=7;m_nArray8=9;m_nArray9=6;,修改 CDigitView:OnDraw,显示 m_nArray 所保存数据:void CDigitView:OnDraw(CDC*pDC)CProg3Doc*pDoc=GetDocument();ASSERT_VALID(pDoc);/TODO:add draw code for native data here TEXTMETRIC tm;pDC-GetTextMetrics(,3 增加一个视图类 为了实现用直方图(棒图)显示文档数据的目的,需要给文档类 CProg3Doc 添加一个视图类 CBarVi
22、ew。添加一个新类 CBarView,选择它的基类为 CView。为 CBarView 类添加获取文档对象指针的函数 GetDocument,在 CBarView 的定义文件中添加:class CBarView:public CView public:CProg3Doc*GetDocument();,在 CBarView 实现文件添加:#include“Prog3Doc.h”和 GetDocument 的定义代码:CProg3Doc*CBarView:GetDocument()ASSERT(m_pDocument-IsKindOf(RUNTIME_CLASS(CProg3Doc);return
23、(CProg3Doc*)m_pDocument;其中 m_pDocument 是 CArchive 类的一个 CDocument 类型的数 据成员,当使用 菜单命令 File-Open 或 File-New 创建文档 类对象时,m_pDocument 指向新创建的文档类对象。,修改 CBarView:OnDraw,实现用直方图显示 m_nArray 数据:void CBarView:OnDraw(CDC*pDC)CProg3Doc*pDoc=GetDocument();/TODO:add draw code here CRect rc;/create a client area int cBa
24、r,cBarSpace;/bar width and space between two bars int x,y;/calculate position of bar drawing int cxGraph=100,cyGraph=20;/logical width,height GetClientRect(,cBar=cxGraph*3/4/10;cBarSpace=cBar/3;pDC-SetMapMode(MM_ANISOTROPIC);pDC-SetWindowOrg(0,0);pDC-SetViewportOrg(10,rc.bottom-10);pDC-SetWindowExt(
25、cxGraph,cyGraph);pDC-SetViewportExt(rc.right-20,-rc.bottom+20);int i;for(x=cBarSpace,y=0,i=0;im_nArray.GetSize();i+,x+=cBar+cBarSpace)pDC-Rectangle(x,y,x+cBar,y+pDoc-m_nArrayi);pDC-SelectObject(poldBr);pDC-SelectObject(poldPen);,代码中关于坐标映射和直方图的绘制可以用下图表示:4 修改框架窗口类 在 CMainFrame 类实现文件中加入:#include DigitV
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第八 文档 视图 结构 高级 形式
链接地址:https://www.31ppt.com/p-5319678.html