VC第三章MFC框架之文档与视.ppt

上传人:max****ui 文档编号:10977506 上传时间:2020-04-16 格式:PPT 页数:44 大小:429KB
返回 下载 相关 举报
VC第三章MFC框架之文档与视.ppt_第1页
第1页 / 共44页
VC第三章MFC框架之文档与视.ppt_第2页
第2页 / 共44页
VC第三章MFC框架之文档与视.ppt_第3页
第3页 / 共44页
点击查看更多>>
资源描述
第三章MFC框架之文档与视图 本章内容 MFC应用程序的开发流程AppWizard生成的文件类型ClassWizard的功能与应用初步用户工程中 文档与视图结构 菜单设计及应用鼠标消息的处理工具栏与状态栏设计文档的读写滚动视图与多视图 一 MFC应用程序的开发流程创建一个应用程序框架为新工程添加必要的资源 如菜单 对话框按程序功能要求 为其添加新类及其类成员编写类的成员函数的实现代码编译 链接 修改错误 生成EXE文件运行并测试新程序 修正设计缺陷将程序由调试版升级为正式发行版 MFC应用程序开发流程图 二 AppWizard生成的文件类型 MFC中资源标识符前缀 三 ClassWizard的功能与应用初步1 应用程序类的继承关系示意图 2 类的命名规则className C projectName classType 3 classWizard的功能创建新类把消息映射为类的成员函数新建或删除消息处理函数察看已被处理的消息并跳到消息处理代码处定义成员变量创建新类时 自动加入方法和属性处理现有的类和类库 4 classWizard的应用实例 编写一个SDI程序框架 并实现在视图区以信息对话框的形式显示用户点击鼠标左 右键和次数 为视图类添加m nLeft m nRight两个私有型变量 并在构造函数中对其初始化 利用类向导在视图类中为鼠标左右单击操作添加 消息处理函数 OnLButtonDown 和OnRButtonDown 为OnLButtonDown 函数添加功能代码 右键函数与此类似m nLeft CStringstrOutput strOutput Format 鼠标左键单击的次数为 d m nLeft MessageBox strOutput 编译 链接并运行程序 测试程序效果 2 MFC的文档 视图结构采用分离机制将数据的管理和显示分作两部分 数据管理和维护由文档负责 数据的显示和编辑由视图负责 文档 视图结构是MFC的一大特色 把数据处理类从用户界面处理类中分离出来 使每一个类专门完成指定的任务 APP向导已经设计好了两者间的相互关系 程序员只要把主要精力放在具体的数据结构设计和数据显示操作上即可 3 文档 视图的相互作用函数 1 视图类的GetDocument 函数 2 文档类的UpdateAllViews 函数 3 视图类的OnUpdate 函数 支持文档 视图相互作用的函数还有 OnInitialUpdate OnNewDocument 实际上 刷新视图的一般过程是 CDocument UpdateAllViews CView OnUpdate CView Invalidate OnPaint OnDraw 4 多文档MFC多文档应用程序与单文档程序的根本差别MDI窗口类的派生关系如下 CMDIFrameWnd CMainFrame 主框架窗口类 CMDIChildWnd CChildFrame 子框架窗口类 文档模板 描述了对应于每一种类型文档的视图和窗口的类型 由其来确立文档 视图 框架和各种资源之间的固定关系 SDI和MDI文档模板的样式 文档模板是在APP类的初始化函数InitInstance 中声明 CSingleDocTemplate pDocTemplate pDocTemplate newCSingleDocTemplate 单文档模板IDR MAINFRAME 主框架资源的IDRUNTIME CLASS CMySDIDoc SDI文档类RUNTIME CLASS CMainFrame SDI主框架窗口类RUNTIME CLASS CMySDIView SDI视图类AddDocTemplate pDocTemplate CMultiDocTemplate pDocTemplate pDocTemplate newCMultiDocTemplate IDR MYMDITYPE 子框架窗口资源IDRUNTIME CLASS CMyMDIDoc RUNTIME CLASS CChildFrame MDI子框架窗口类RUNTIME CLASS CMyMDIView AddDocTemplate pDocTemplate 五 菜单设计及应用1 建立菜单资源实例 创建一个名为DrawCoin的SDI项目 添加 画硬币 主菜单 并增加两个菜单项 增加硬币 减少硬币 编程 1 添加顶层菜单 画硬币 C 2 增加两个菜单项 MenuItem ID COIN ADD增加硬币 A tCtrl A在客户区增加一枚硬币 n增币ID COIN SUB减少硬币 S tCtrl S在客户区减少一枚硬币 n减币 2 添加菜单命令的处理函数菜单实则一系列命令的列表 当某一菜单项被点击后 一个含有该菜单项ID标识的WM COMMAND命令消息将发送给APP窗口 APP将该消息转换为一个 命令消息处理函数 的函数调用 从而响应命令 利用 类向导 Ctrl W 工具为菜单添加消息映射函数 并添加用户代码 本例中 为了实现菜单的操作功能 还必须完成如下三步 1 为文档类添加一个名为m nCoins的公有型整型变量 2 利用类向导工具为文档类添加名为 DeleteContents 的消息处理函数 并在其内对m nCoins 1初始化 该函数在用户重新使用一个文档时自动调用 3 修改视图类的OnDraw 函数 根据文档类保存的m nCoins当前值画出指定数量的硬币for inti 0 im nCoins i inty 200 10 i pDC Ellipse 200 y 300 y 30 pDC Ellipse 200 y 10 300 y 35 用两个上下偏移椭圆表示硬币 UPDATE COMMAND UI是 更新用户界面命令消息 它能够根据程序当前运行状态来动态设置菜单项的状态 可用或不可用 在程序刚运行时 将菜单项 减少硬币 置为 不可用 灰显状态 需要在其UPDATE COMMAND UI消息映射函数中 添加代码 if m nCoinsEnable FALSE 禁用菜单项 灰显 elsepCmdUI Enable TRUE 使能菜单项 正常显示 3 为菜单命令设置加速键在资源视图Accelerator中IDR MAINFRAME项的加速键列表最后一空行操作 4 为新菜单添加 弹出式快捷菜单 利用类向导为视图类添加WM CONTEXTMENU消息处理函数 并添加如下代码 CMenumenuPopup 声明菜单对象if menuPopup CreatePopupMenu 创建菜单 menuPopup AppendMenu MF STRING ID COIN ADD 增加硬币 tCtrl A 向菜单中添加菜单项menuPopup AppendMenu MF STRING ID COIN SUB 减少硬币 tCtrl M 向菜单中添加菜单项 显示弹出式菜单 并对用户选择做出响应menuPopup TrackPopupMenu TPM LEFTALIGN point x point y this 六 鼠标消息的处理1 鼠标消息的类型WM MOUSEMOVE 移动 WM LBUTTONDBLCLK 双击左键 WM LBUTTONDOWN 按下左键 WM LBUTTONUP 释放左键 WM RBUTTONDOWN 按下右键 WM RBUTTONUP 释放右键 1 客户区鼠标消息 最常见 2 非客户区鼠标消息 相对少见 2 鼠标消息的应用举例实例 编写一个SDI程序MyDraw 程序运行后 当用户在客户区内按下鼠标左键并移动时 会沿鼠标移动轨迹自动绘制出连续的线段 分析 本例属典型的 客户区鼠标消息 的应用 编程实现 具体步骤及代码详见MyDraw txt文件 七 工具栏与状态栏设计1 添加工具栏按钮的方法工具栏是由形象化的位图按钮所组成 它结合了菜单和快捷键的共同优点 具有操作直观快捷 使用方便的特点 工具栏内的按钮一般都与某一特定的菜单命令相对应 从功能上讲 它与特定菜单命令一致 在具体编程实现上 程序员应当先利用资源视图设计出新按钮图形图标 后将其ID值设置成与对应菜单项ID相同即可 实例 为前述的DrawCoins程序的工具栏添加两个对应按钮 2 添加用户自定义工具栏的方法添加用户自定义工具栏步骤 1 在工程中插入新工具条资源 并添加相关按钮 2 在CMainFrame类头文件中加入 CToolBarmy ToolBar 3 在MainFrame cpp文件的Create 函数中模仿生成标准工具栏的方法 书写生成新工具栏的语句 并在最后 停泊工具栏 的函数中加入第2个参数AFX IDW DOCKBAR LEFT 4 为工具条的各个按钮添加UPDATE COMMAND UI和COMMAND类型的消息映射 并添加实现代码 5 在 查看 菜单中为新工具条的添加控制菜单命令 在消息映射处理函数中以IsWindowVisible 函数为判断条件 以ShowWindow 函数的SW HIDE或SW SHOW参数控制 以决定其显隐 实例 为MyDraw画线程序添加 画笔选择 工具栏 该例以另一种方式实现工具栏按钮的基本功能 1 在视图类中头文件中手工添加工具条的消息映射函数的声明 afx msgvoidOnPenChioce UINTnID 2 在实现文件中加入消息映射宏 ON COMMAND RANGE ID PEN RED ID PEN WIDTH OnPenChioce 3 在实现文件中加入消息处理函数的定义 voidCMyDrawView OnPenChioce UINTnID switch nID 以下case语句分别对应于画笔工具条自左向右的各个按钮控件caseID PEN RED m colors RGB 255 0 0 break 红笔取色caseID PEN SOLID PenStyle PS SOLID break 设置画笔风格为实线caseID PEN WIDTH PenWidthDlg break 调用自定义函数获取笔粗数据default break Pen DeleteObject Pen CreatePen PenStyle PenWidth m colors 创建画笔 4 为工具条的某些按钮继续书写函数功能定义代码 如PenWidthDlg 3 定制状态栏状态栏是位于主窗口底部 用于显示当前操作提示信息和键盘状态的长条型子窗口 一般由状态信息行和状态指示器两部分组成 前者用于动态地显示APP串表资源中的字符串 后者用于显示键盘的状态信息 通常 MFC程序将状态条自左向右分成4个窗格 1 窗格显示菜单或工具栏的提示信息 2 窗格显示键盘的大小写状态 3 窗格显示数字键盘状态 4 窗格显示键盘的ScrollLock状态 在MainFrame cpp文件中 StatusBar由一个静态数组来定义 StaticUINTindicators ID SEPARATOR 定义分隔符 作为提示信息行的面板标识ID INDICATOR CAPS 大小写指示器面板标识ID INDICATOR NUM 数字指示器面板标识ID INDICATOR SCRL 滚动指示器面板标识 CStatusBar类有两个重要函数 SetPaneText 用于在指定窗格上显示字符信息 SetPaneInfo 可改变一个指示器面板的ID 风格和宽度 实例 修改前述DrawCoins程序的状态栏 使其能动态显示硬币数目 1 在 StringTable 中加入新的字符串信息 其ID为ID INDICATOR COINS Caption为 硬币数目 2 在Mainframe cpp中修改indicators 数组 StaticUINTindicators ID SEPARATOR 定义分隔符 作为提示信息行的面板标识ID INDICATOR COINS 新添加一个指示器面板标识ID INDICATOR CAPS 大小写指示器面板标识ID INDICATOR NUM 数字指示器面板标识ID INDICATOR SCRL 滚动指示器面板标识 3 在视图类的OnDraw 函数中定制状态栏新窗格的显示信息 在OnDraw 函数中添加如下代码 CStringstrCoins 声明状态栏新窗格的字符串变量CStatusBar pStatus CStatusBar AfxGetApp m pMainWnd GetDescendantWindow ID VIEW STATUS BAR 状态栏指针if pStatus strCoins Format 当前硬币个数 d pDoc m nCoins pStatus SetPaneInfo 1 1 NULL 98 指定序号窗格的宽度pStatus SetPaneText 1 strCoins 在指定窗格显示硬币个数 编译并运行 检验正误 八 文档的读写在MFC中 CFile类专门用于处理文件 使用它 需要在程序中包含afx h的头文件 而且还需要对工程进行特定设置 即Project Settings Link标签页 MFC项 UseMFCinaDllorStaticLibrary 使用该类的缺点在于打开或读写文件时可能发生异常情况 需要进行复杂的异常处理 对于二进制文件来说 MFC使用 序列化 简化了文件的读写操作 1 序列化 Serialize 持久性是指对象所具有的保存和加载其状态的能力 在程序运行结束之前通过将对象的当前状态写入永久性存储体中 在下次再运行时通过数据的读取而恢复对象的状态 在MFC所支持的APP框架程序中 对象的保存和恢复的过程就称为 序列化 在利用APP向导生成文档 视图结构的应用程序框架时 就已经为文档类提供了序列化的基本功能 即编程接口 序列化是通过文档派生类的Serialize 函数来完成 该函数由CArchive类的ar对象指针作为参数 由一个if else结构完成序列化的文档读写功能 VoidCMydoc Serialize CArchive ar if ar IsStoring TODO addstoringcodehere else TODO addstoringcodehere 多数MFC程序实现对象的持久性是通过CArchive类 归档类 对象ar的安全缓冲机制间接地使用CFile类的功能 其中的关系如下 Serialize ar对象 CFile对象 磁盘文件 当存储文档数据时 ar对象将序列化数据存放在一个缓冲区中 直到该区存满时才将数据存储到相关文件中 读取数据的过程与之相反 实例 修改前述DrawCoins程序 使其具有文档序列化功能voidCDrawCoinsdoc Serialize CArchive 2 序列化实例总结当执行APP的文件菜单下的新建 打开 保存和另存为等命令时 都会自动调用文档派生类的Serialize 成员 实现与序列化有关的操作 数据读写 例如 当执行 保存 命令时 MFC框架程序就会调用文档类的OnFileSave 该函数完成如下3项工作 由文档对象获得当前文件CFile对象的指针 创建一个CArchive对象 文档对象调用Serialize 函数 并把CArchive对象对象作为参数 Serialize 函数根据IsStoring 函数的返回值true决定执行if语句的第一个分支 从而利用ar对象将序列化数据存储至所关联的文件中 序列化的缺点 1 只能顺序读写 不能随机读写 2 只能处理二进制文件 不能处理文本文件 九 滚动视图与多视图1 滚动视图本章前述的MFC框架程序的视图均派生于CView类 其用户区的大小总是固定的 如果某些程序的实际文档尺寸大于视图窗口时 超出的部分将无法显示 为了解决这种实际问题 就必须用到滚动视图 为视图加上滚动条 从而扩大显示的范围 MFC提供了一个滚动视图类 CScrollView 它有几种常用方法 SetScrollSizes 用于设置滚动视图的总尺寸以及每一页 每一行的大小 GetTotalSize 用于获取整个视图的大小 GetScrollPosition 获取当前可见视图左上角的坐标 将原有普通APP修改为具有滚动视图功能的程序的方法是 利用代码替换命令将所有视图的基类由CView改为CScrollView 重载视图类的OnInitialUpdate 虚函数或者OnCreate 函数 根据文档大小的需要重新设置滚动视图尺寸 一般为了简洁 可将滚动视图设成一个较大的常量值 在保存文档数据时 要进行相应的坐标数据转换 因为OnDraw 函数使用逻辑坐标 而鼠标控制的客户区使用的是设备坐标 由CClientDC界定 实例 为前述MyDraw程序增加滚动视图功能 1 利用编辑菜单下的替换命令将视图派生类 h和 cpp中的CView全部替换成CScrollView 2 在工作区类视图中右键为视图类添加初始化虚函数 并在其中添加代码 CSizesizeTotal sizeTotal cx sizeTotal cy 1000 定义新视图的尺寸SetScrollSizes MM TEXT sizeTotal 设置新视图的映射模式和大小 3 在保存滚动视图区新增画线的坐标数据时 应加上原始客户区的原点坐标 在鼠标移动消息函数中新增代码如下 CPointptOrg ptStart ptEnd ptOrg GetScrollPosition 获得当前工作区原点坐标ptStart m pStart ptOrg 加上原点坐标用于修正线段坐标ptEnd point ptOrg pDoc AddLine ptStart ptEnd 存储线段 2 多视图MFC的文档 视图结构可以使一个文档与多个视图相关联 容易实现多视图的APP 同一份文档数据即可以用文字方式显示 也可以用图形方式显示 MDI就是一种自然的多视图APP 但SDI程序也可以实现多视图 实例 以一个取名为MyEditor的MDI应用程序为例 实现文本字符串的两种视图显示方式 代码详见MyEditor txt文件 十 自定义类与类的序列化1 自定义类 新建类 在VC 编程中 多数的类都是由MFC功能类直接派生的 在类向导的控制之下 管理起来比较方便 但有时 根据实际工作的不同 有些APP却需要程序员自己定义一个类 并由自己编写代码来实现类的功能 实例 现以前述MyDraw程序为例 由程序员自己创建一个CLine类 以方便数据管理 并实现程序结构的清晰化 实例MyDraw程序自定义类的实现过程详见 有彩色工具条的绘图程序 文本文件 本例的关键技术还在于对MFC 动态数组 的运用 用它来保存不定数量的多条线段数据 1 动态数组由类CObArray所支持的CObject指针数组对象动态生成 2 代码实现时 实际上是引用了CTypedPtrArry类及其对象 典型格式是 CTypedPtrArryuseDefObj例如 CTypedPtrArrays LineArray 本例中 useClass是Cline useDefObj为m LineArray 其表示m LineArray是CObArray的派生类对象 用于存放Cline对象的指针 2 自定义类的序列化在VC 编程中 只有由APP向导生成的程序框架的文档派生类才自动具有序列化功能 而由用户自定义的类必须人为通过书写代码 才可以使其支持序列化功能 自定义类支持序列化需满足4个条件 1 自定义类必须直接或间接地从CObject类派生 2 自定义类必须带有一个无参数的构造函数 3 必须人为添加MFC序列化宏 4 必须重载Serialize 成员函数 使其支持特定数据的序列化 实例 在MyDraw程序的基础上 通过对CLine类的序列化 使其具有画图的保存功能 分析 本实例先前所创建的Cline 是从CObject类派生 且已定义了一个不带参数的构造函数 符合序列化4个必须条件中的前两个 因此 本次编程要解决的是使其也满足后2个条件 1 为新类添加必须的 序列化宏 DECLARE SERIAL CLine 在类声明中加入 序列化宏 声明IMPLEMENT SERIAL CLine CObject 1 在实现文件中加入 实现宏 2 在新类中手工重载序列化函数 并定义voidCLine Serialize CArchive 读取对象的数据 3 在原文档类的 序列化 函数中修改代码voidCMyDrawDoc Serialize CArchive 课后作业 依照程序MyDraw编写一个名为MyLine的程序 类似windows的 画图 程序 在利用鼠标画一条直线时 按住左键拖拉 可以动态地画出当前直线 当释放左键后才真正画出一条所需要的直线 要求实现窗口的重绘功能 提示 直线生成过程中 外形如同 橡皮筋
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!