1 / 68

第 3 章 文档和视图

第 3 章 文档和视图. 引言. 了解 文档与视图结构程序的工作原理 掌握 应用程序中的菜单界面设计方法 掌握 工具栏和状态栏等程序界面的设计方法 了解 文档的序列化工作原理 了解 使用不同的视图类编程. 3.1 文档与视图结构. 3.1.1 文档与视图结构概述. 在文档 — 视图结构中,文档的任务是对数据进行管理和维护。数据通常被保存在文档类的成员变量中。在 Visual C++ 2005 中,文档类通过一个称为 串行化 (serialize) 的过程将数据保存到磁盘文件或数据库中。

trory
Télécharger la présentation

第 3 章 文档和视图

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第3章 文档和视图

  2. 引言 • 了解文档与视图结构程序的工作原理 • 掌握应用程序中的菜单界面设计方法 • 掌握工具栏和状态栏等程序界面的设计方法 • 了解文档的序列化工作原理 • 了解使用不同的视图类编程

  3. 3.1 文档与视图结构

  4. 3.1.1 文档与视图结构概述 • 在文档—视图结构中,文档的任务是对数据进行管理和维护。数据通常被保存在文档类的成员变量中。在Visual C++ 2005中,文档类通过一个称为串行化(serialize)的过程将数据保存到磁盘文件或数据库中。 • MFC类库为数据的串行化提供了默认的支持,只需要在此基础上稍加修改,就可以为自定义的文档类提供串行化支持。 • 在MFC中主要有两种类型的文档视图结构,即单文档界面(SDI:Single Document Interface)应用程序和多文档界面(MDI:Multiple Document Interface)应用程序。

  5. SDI应用程序的5个基类之间的关系模型如图3.1所示。SDI应用程序的5个基类之间的关系模型如图3.1所示。 图3.1 SDI的基本类结构布局

  6. 图3.2 MDI的基本类结构布局 • MDI应用程序的6个基类之间的关系模型如图3.2所示

  7. 视图在文档和用户之间起中介作用,它只负责实现和修改文档数据,但不负责存储。 • 一个视图是一个没有边框的窗口,它位于主框架窗口区的客户区。视图是文档对外显示的窗口,但是它不能完全独立,必须依存在一个框架窗口内。 • 每一个文档可以有多个视图,但每个视图只能对应于一个确定的文档。 • 视图是文档的不同表现形式。

  8. 3.1.2 文档与视图间的相互作用 • 文档与视图的交互是通过类的共有成员变量和成员函数来实现的。表3.1给出了文档—视图结构中各类对象相互访问所采用的成员函数。 表3.1 对象访问所需函数

  9. 3.1.3 多文档应用程序 • Visual C++ 2005中的一个多文档应用程序有一个主窗口,在主窗口中可以同时打开多个子窗口,每一个子窗口对应一个不同的文档。 • 利用MFC 应用程序向导可以很方便地建立一个多文档应用程序。

  10. 1.多文档应用程序 • 【例3.1】编写一个多文档应用程序MyMdi,程序运行后在客户区窗口显示信息“这是hello world的多文档程序!”。

  11. 程序的实现过程如下: • (1)创建应用程序框架 • (2)添加代码 • 在MyMdi应用程序的CMyMdiView类的OnDraw函数中添加显示文本的代码 • pDC->TextOut(50,50, _T("欢迎学习建立多文档程序!")); • TextOut函数用于在指定的位置输出字符串。

  12. 2.文档模板 • 在文档-视图结构应用程序中,数据以文档类的对象形式存在。 • MFC提供了抽象基类CDocTemplate来实现文档模板的功能,应用程序不能直接使用,但可以把文档模板定义为CDocTemplate的派生类,在应用程序中,必须为每种类型的文档建立一个文档模板。

  13. (1)文档模板的构成 • 文档模板定义了三个类之间的关系。 • ① 文档类 • 应用程序从CDocument类派生此类,用于完成文档的新建、打开和保存等工作。 • ② 视图类 • 应用程序从CView、CScrollView、CEditView类派生而来,用于显示文档数据。 • ③ 含有该视图文档的框架窗口类 • 单文档应用程序从CFrameWnd类派生此类,多文档应用程序从CMDIChildWnd类派生而来。如果应用程序不需要定制框架窗口,则也可以直接使用CFrameWnd类和CMDIChildWnd类。

  14. MFC除了提供了CDocTemplate抽象基类之外,还提供了CDocTemplate的两个派生类:CSingleDocTemplate和CMultiDocTemplate。MFC除了提供了CDocTemplate抽象基类之外,还提供了CDocTemplate的两个派生类:CSingleDocTemplate和CMultiDocTemplate。 • CSingleDocTemplate类定义了一个实现单文档界面的文档模板。SDI应用程序使用主框架窗口来显示一个文档,每次只能打开一个文档。 • CMultiDocTemplate类定义了一个实现多文档界面的文档模板。MDI应用程序用主框架窗口作为工作空间,在其中可以打开单个或多个文档框架窗口。在每个文档窗口中显示一个文档。

  15. (2)文档模板的创建 • 在初始化应用程序时,必须首先注册文档模板,以便程序利用这个模板来完成主框架窗口、视图、文档对象的创建和资源的装入。 • 在SDI或MDI应用程序中,要注册文档模板,需通过new运算符调用文档模板类的构造函数生成一个CSingleDocTemplate或CMultiDocTemplate类对象,并调用函数AddDocTemplate注册该文档模板对象。

  16. 图3.4 应用程序中各对象之间的创建关系

  17. 图3.5 应用程序中各对象之间的访问方法

  18. 3.2 菜单设计

  19. 菜单分为两类: • 一类是依附于框架窗口的一般菜单,包括主菜单和子菜单,主菜单(菜单栏)横放在窗口的顶部,它是应用程序的最高层菜单,子菜单是从主菜单下弹出的菜单。 • 另一类是弹出式菜单,也叫快捷菜单或上下文菜单,它是点击鼠标右键后,在光标所在位置出现的浮动式自由菜单。

  20. 3.2.1 建立菜单资源 • 菜单是Windows应用程序中一个必不可少的用户界面资源,Visual C++ 2005集成开发环境提供了一个可视化菜单编辑器用于菜单的编辑和添加。 • 菜单中的每一个菜单项都由菜单项名(即Caption)和命令ID号两个基本要素组成。

  21. 创建菜单可以有好几种方法,最简单的方法是在属性窗口用菜单编辑器来进行设计。创建菜单可以有好几种方法,最简单的方法是在属性窗口用菜单编辑器来进行设计。 • 利用菜单辑器创建菜单资源的主要步骤如下: • (1)打开应用程序的菜单编辑器; • (2)添加主菜单; • (3)添加菜单项,设置菜单项的属性。

  22. 【例3.2】编写一个应用程序MyMenu,为程序添加一个“图像”主菜单和它的两个下拉子菜单项“显示”和“删除”。【例3.2】编写一个应用程序MyMenu,为程序添加一个“图像”主菜单和它的两个下拉子菜单项“显示”和“删除”。 • 程序的实现过程如下: • (1)创建应用程序,打开菜单编辑器 • (2)添加主菜单 • (3)添加菜单项,设置菜单项的属性

  23. 3.2.2 添加命令处理函数 • Windows应用程序是通过消息传递机制运作的,菜单项对命令的激发、调用是通过发送WM_COMMAND消息实现的。 • 处理的原则是:依据菜单的不同作用进行不同的映射。 • 如果该菜单用于文档的显示编辑,则最好在视图类中映射。 • 如果该菜单用于文档的打开和存储,则最好在文档类中进行映射。 • 对于通用菜单,可以在框架类中映射。

  24. 在【例3.2】中只添加了菜单资源,并没有实现菜单的功能,即没有对应的命令处理函数与菜单项对应,因此,程序运行后添加的菜单项是灰色的,即处于当前不可用状态。添加新的菜单项后,还应该为新的菜单项指定一个处理函数。 • (1)打开类视图找到相应的类。 • (2)单击其属性窗口中的“事件”按钮,此时属性窗口将列出此类可以处理的对象ID。 • (3)从“菜单命令”中选择ID_SHOWPICTURE,并单击其左侧的“+”号,就会出现可处理的命令消息。 • (4)选择适当的消息,单击其右侧的单元格,就会出现提示信息

  25. 快捷键的添加需要使用快捷键编辑器,添加快捷键的步骤如下:快捷键的添加需要使用快捷键编辑器,添加快捷键的步骤如下: • (1)打开应用程序的加速器表; • (2)添加新的快捷键; • (3)设置快捷键的属性。

  26. Visual C++ 2005的MFC提供的菜单类的对象可以用来表示各种Windows菜单,并且该类可以在程序运行时处理有关菜单的操作。 • 1. 创建菜单 • CMenu类的成员函数CreateMenu和CreatePopupMenu分别用来创建一个菜单或子菜单框架,它们的函数原型如下: • BOOL CreateMenu(); //产生一个空菜单 • BOOL CreatePopupMenu(); //产生一个空的弹出式子菜单 • 2. 装入菜单 • CMenu类的成员函数LoadMenu可用来将菜单资源装入应用程序中,它的函数原型有两种: • BOOL LoadMenu(LPCTSTR lpszResourceName); • BOOL LoadMenu(UNIT nIDResource);

  27. 3. 添加菜单项 • 当菜单创建后,可以调用CMenu类提供的成员函数AppendMenu或InsertMenu向菜单中添加一些菜单项 • 它们的函数原型如下: • BOOL AppendMenu(UNIT nFlags, UNIT nIDNewItem,const CBitmap * pBmp); • BOOL AppendMenu(UNIT nFlags, UNIT nIDNewItem=0,LPCTSTR lpszNewItem=NULL); • BOOL InsertMenu(UNIT nPosition, UNIT nFlags, UNIT nIDNewItem,const CBitmap *pBmp); • BOOL InsertMenu(UNIT nPosition, UNIT nFlags, UNIT nIDNewItem=0,LPCTSTR lpszNewItem=NULL); • BOOL InsertMenuItem(UINT uItem, LPMENUITEMINFO lpMenuItemInfo,BOOL fByPos = FALSE);

  28. 4.删除菜单项 • 当要删除指定的菜单项时,可利用CMenu类的成员函数DeleteMenu来完成,该函数的原型为: • BOOL DeleteMenu(UNIT nPosition,UNIT nFlags); • 5.获取菜单项 • 可以利用CMenu类的以下3个成员函数分别获得菜单的项数、菜单项的ID号以及弹出式子菜单的句柄。 • GetMenuItemCount()函数 • GetMenuItemID()函数 • GetSubMenu()函数

  29. 3.2.3 弹出式菜单 • 弹出式菜单是通过利用CMenu类和其成员函数,在程序运行过程中动态建立的。弹出式菜单的建立方法有两种: • (1)利用现有的菜单项进行创建。 • (2)为弹出式菜单专门建立一个菜单资源,通过调用函数CMenu::LoadMenu装入创建的菜单资源。

  30. 弹出式菜单的实现过程如下: • (1)利用成员函数CMenu::CreatePopupMenu创建一个弹出式菜单。 • (2)利用成员函数CMenu::LoadMenu装入菜单资源或利用成员函数CMenu::AppendMenu添加菜单项。 • (3)利用成员函数CMenu::TrackPopupMenu在指定位置显示弹出式菜单,并跟踪用户的菜单项选择。TrackPopupMenu成员函数的原型为: • BOOL TrackPopupMenu (UNIT nFlags, int x, int y, CWnd *pWnd, LPCRECT lpRect=0);

  31. 【例3.6】为【例3.5】的程序MyMenu的“图像”菜单添加弹出式菜单。编译运行该程序,单击鼠标右键并松开后得到如图3.12所示的结果。【例3.6】为【例3.5】的程序MyMenu的“图像”菜单添加弹出式菜单。编译运行该程序,单击鼠标右键并松开后得到如图3.12所示的结果。 图3.12 弹出式菜单

  32. 程序的实现过程如下: • (1)打开【例3.5】的例子,在Visual C++ 2005中,选择“文件”菜单中的“打开”菜单项下的“项目/解决方案”,打开上例中的“MyMenu.sln”文件。 • (2)在类视图中选择类CMyMenuView,在属性窗口单击“消息”按钮,选择WM_CONTEXTMENU,单击右侧下拉菜单中的“<添加>OnContextMenu”选项,就在视图类CMyMenuView中添加了消息WM_CONTEXTMENU的消息映射函数。

  33. 3.3 工具栏和状态栏设计

  34. 工具栏和状态栏是Windows系统中常用的两种界面元素。工具栏和状态栏是Windows系统中常用的两种界面元素。 • 一般情况下,在创建应用程序框架时,MFC自动为应用程序提供了一个标准工具栏和一个标准状态栏。

  35. 3.3.1 添加工具栏 • 工具栏是一系列工具按钮的组合,也是一种常用的命令输入方式,用户可以用鼠标单击工具栏上的工具按钮来向应用程序发出命令。 • MFC工具栏还支持工具提示(Tooltip),工具提示用于帮助用户理解单个工具栏按钮的作用。 • 工具栏也是资源,在Visual C++ 2005中创建工具栏资源 。

  36. 1.创建工具栏资源 • 创建工具栏资源的步骤如下: • (1)打开应用程序的工具栏编辑器; • (2)添加工具栏按钮; • (3)设置工具栏按钮属性。

  37. 【例3.7】为【例3.6】的程序MyMenu的“图像”菜单项添加工具栏按钮。程序运行后,工具栏的实际效果如图3.13所示,新添加的工具栏按钮位于工具栏的最后两个位置。【例3.7】为【例3.6】的程序MyMenu的“图像”菜单项添加工具栏按钮。程序运行后,工具栏的实际效果如图3.13所示,新添加的工具栏按钮位于工具栏的最后两个位置。 图3.13 MyMenu的工具栏

  38. 程序的实现过程如下: • (1)打开【例3.6】的例子,在Visual C++ 2005中,选择“文件”菜单中的“打开”菜单项下的“项目/解决方案”,打开上例中的“MyMenu.sln”文件。 • (2)在“资源视图”中展开“Toolbar”,双击其下的IDR_MAINFRAME ,打开工具栏编辑器,屏幕上同时显示工具栏设计窗口。 • (3)添加工具栏按钮。 • (4)设置工具栏按钮属性。

  39. 2.动态生成工具栏 • 动态生成工具栏的方法如下: • (1)声明一个CToolBar类对象。 • (2)调用函数CToolBar::Create或CToolBar::CreateEx生成指定风格的工具栏并与CToolBar类对象相连接。 • (3)调用函数CToolBar::LoadToolBar装入工具栏。

  40. 【例3.8】为【例3.6】的程序MyMenu动态生成工具栏,程序的实际运行效果如图3.18所示。【例3.8】为【例3.6】的程序MyMenu动态生成工具栏,程序的实际运行效果如图3.18所示。 图3.18 动态生成程序MyMenu的工具栏

  41. 程序的实现过程如下: • (1)打开【例3.6】的例子,在Visual C++ 2005中,选择“文件”菜单中的“打开”菜单项下的“项目/解决方案”,打开上例中的“MyMenu.sln”文件。 • (2)添加一个工具栏资源。 • (3)如【例3.7】的方法设置工具栏按钮的属性。 • (4)加载工具栏资源。

  42. 3.3.2 定制状态栏 • MFC提供另一种经常与输入命令相关的用户界面对象:状态栏。 • 状态栏是典型的位于应用程序主窗口底部的窗口,经常在状态栏显示文本提示信息。

  43. MFC把状态栏封装在状态栏类CStatusBar中,动态创建状态栏的过程如下:MFC把状态栏封装在状态栏类CStatusBar中,动态创建状态栏的过程如下: • (1)构造一个CStatusBar类对象。 • (2)调用Create函数创建一个状态栏窗口,并将该窗口连接到该 CStatusBar类对象 上。 • (3)调用SetIndicators函数设置指示器ID。

  44. 利用向导创建应用程序时,在CMainFrame类中定义了一个成员变量m_wndStatusBar,它是状态栏类CStatusBar的对象。在MFC应用程序框架的实现文件MainFrm.cpp中,为状态栏定义了一个静态数组indicators,如下所示:利用向导创建应用程序时,在CMainFrame类中定义了一个成员变量m_wndStatusBar,它是状态栏类CStatusBar的对象。在MFC应用程序框架的实现文件MainFrm.cpp中,为状态栏定义了一个静态数组indicators,如下所示: static UINT indicators[] = { //定义分隔符,作为提示信息行的面板标志 ID_SEPARATOR, ID_INDICATOR_CAPS, //大写指示器面板标志 ID_INDICATOR_NUM, //数字指示器面板标志 ID_INDICATOR_SCRL, //滚动指示器面板标志 };

  45. 创建状态栏资源的具体步骤如下: • (1)打开应用程序的串表编辑器; • (2)添加新的串表,设置其属性; • (3)添加指示器面板。

  46. 【例3.9】修改【例3.7】的程序MyMenu,在状态栏上显示鼠标的位置,以及当前的状态(是显示图片还是删除图片)。程序的实际运行效果如图3.19所示。【例3.9】修改【例3.7】的程序MyMenu,在状态栏上显示鼠标的位置,以及当前的状态(是显示图片还是删除图片)。程序的实际运行效果如图3.19所示。 图3.19 MyMenu的状态栏

  47. 程序的实现过程如下: • (1)打开【例3.7】的例子,在Visual C++ 2005中,选择“文件”菜单中的“打开”菜单项下的“项目/解决方案”,打开上例中的“MyMenu.sln”文件。 • (2)添加串表。 • (3)添加指示器面板。 • (4)添加消息映射函数OnMouseMove。 • (5)修改OnDraw函数,添加显示当前状态的代码。

  48. 3.4 文档的读写

  49. 用户处理的数据往往需要存盘做永久备份,在MFC应用程序中提供了数据序列化(serialize)的方式来处理文档的读写功能。用户处理的数据往往需要存盘做永久备份,在MFC应用程序中提供了数据序列化(serialize)的方式来处理文档的读写功能。 • 序列化指的是从一个持久性存储介质读出或者写入一个对象的过程。

  50. 3.4.1 序列化工作原理 • 文档类存盘的重点在于存储文档类中的成员变量,使之可以利用这些变量完成重建,而不损失任何信息。 • 同时文档还需要能够从存储的文档文件中读取信息以便重建文档类。

More Related