MFC程序设计PPT课件.ppt_第1页
MFC程序设计PPT课件.ppt_第2页
MFC程序设计PPT课件.ppt_第3页
MFC程序设计PPT课件.ppt_第4页
MFC程序设计PPT课件.ppt_第5页
已阅读5页,还剩148页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第三章MFC程序设计 本章的内容 简洁而不失完整性 由应用程序向导建立程序框架 由资源编辑器建立用户界面 由类向导建立成员变量 消息映射和处理函数 加上文档序列化和注册MFC包含了所有与系统相关的类 包括图形用户界面相关的类 其中封装了大多数的API函数 提供了应用程序框架和开发应用程序的工具如应用程序向导 类向导 可视化资源设计等高效工具 用消息映射处理消息响应 大大简化了Windows应用程序的开发工作 使程序员可以从繁重的编程工作中解脱 提高工作效率 1 3 1 MFC程序设计简介3 2 MFC程序设计3 3 用户界面资源的应用3 4 对话框的应用3 5 基于对话框的应用程序设计实例3 6 文本和图形输出3 7 文档的保存3 8 MDI应用程序设计 目录 2 3 1MFC程序设计简介 MFC类库基础类 已在第二章中介绍 宏 全局变量及全局函数应用程序框架 3 1 1MFC定义的宏 全局函数及全局变量 类库 1 MFC提供的主要宏 消息映射宏 声明消息映射表宏DECLARE MESSAGE MAP 消息映射定义宏BEGIN MESSAGE MAP和END MESSAGE MAP消息映射表入口宏ON 消息名 本章只介绍消息映射宏 3 3 1 1MFC定义的宏 全局函数及全局变量 动态MFC对象宏DECLARE DYNAMIC和IMPLEMENT DYNAMIC动态创建对象宏DECLARE DYNCREATE和IMPLEMENT DYNCREATE运行时类宏 RUNTIME CLASS序列化宏 DECLARE SERIAL和IMPLEMENT SERIAL诊断服务宏 ASSERT VERIFY跟踪服务宏 TRACE异常处理宏 THROW 4 3 1 1MFC定义的宏 全局函数及全局变量 MFC提供一些不属于任何类的全局函数 函数名以Afx开头 可以被应用程序中的所有类和函数所调用 如 AfxAbort 无条件终止一个应用程序的执行 AfxGetAppName 返回指向应用程序名的字符串指针 AfxWinInit 由WinMain 调用 对MFC应用程序进行图形用户界面 GUI 的初始化等等 3 全局变量 全局变量名以afx开头 如afxTraceFlag afxDump等 主要与异常处理有关 2 全局函数 5 3 1 2MFC命名规则 匈牙利命名法规定 变量名以一个或多个小写字母开头作为前缀 标识变量的数据类型 类型标识后是若干个单词 标识变量含义 每个单词以大写字母开头 其余字母小写 MFC中所有类及自定义类都以C开头 类成员变量以m 为前缀 下划线后是变量名等等 6 表3 1命名规则 h 7 MFC提供了构造Windows应用程序的框架 它不仅为应用程序建立标准的结构 生成一系列起动文件 还提供标准的图形用户界面如菜单 工具栏 状态条等供开发人员在程序中补充完善 开发人员只需要完成针对特定应用的代码 使用应用程序框架的应用程序代码小 运行速度快 它提供的工具也降低了编码的难度 3 1 3应用程序框架介绍 8 程序的数据储存在文档类中 作为文档类的数据成员 是对数据的抽象表示 数据显示由视图负责 视图是程序窗口的客户区 框架窗口是客户区的框架 程序数据显示在窗口 用户通过视图与程序交互 一个文档可以对应多个不同视图 而一个视图一般只对应一个文档 当文档数据发生变化时 视图显示的状态也会随之变化 对于多个视图的情况 基于同一文档的多个视图的显示同步变化 1 文档 视图结构 文档视图结构提供一种连续处理数据的方式 使应用程序的数据与数据的显示分开处理 9 文档 视图及框架的关系 图3 1 10 2 单文档界面应用 单文档界面应用程序简称SDI SingleDocumentInterface 只允许一个框架窗口存在 每次只能创建和拥有一个文档对象 也只允许打开一个文档 SDI各类关系图 可将文档比作一个文件袋 专门用于保存文件数据 需要看时需从文件袋 文档 中取出来 放到桌面 视图 上看 11 表3 2基于文档 视图关系的SDI应用中的类 返回 12 应用程序类 框架类 窗口框架 资源 决定用户界面的显示 视图类 显示数据并与用户交互 文档类 保存数据 单文档模板 返回 13 应用程序类CDocManager m pDocManager 框架类 窗口框架 资源 决定用户界面的显示 m pDocument视图类 显示数据并与用户交互 文档类 保存数据 m pDocTemplatem viewList 返回 单文档模板CRuntimeClass m pDocClassCRuntimeClass m pFrameClassCRuntimeClass m pViewClassUINTm nIDResource 14 多文档界面应用简称MDI MultipleDocumentInterface 允许有多个文档类 视图类和多个文档模板CMultiDocTemplate 建立多种文档 视图 子框架关系 存在 运行时允许打开多个MDI子框架窗口 拥有各自的文档和视图对象 示例关系图 在打开的多个子窗口中 只有一个活动窗口 应用程序菜单和工具栏的所有的命令都是针对活动窗口的 3 多文档界面应用 15 主框架 其它文档模板 返回 CDocManager 应用程序类CDocManager m pDocManager 16 文档 视图结构可以充分发挥应用程序框架和MFC的优势 是MFC应用程序的核心 但使用它也要付出运行效率和代码增大的代价 文档 视图结构对应用程序来说并不是必不可少的 有两种常见的非文档 视图结构应用 4 非文档 视图结构应用 17 常见非文档 视图结构应用 1 基于对话框的应用 它包含一个CWinApp对象和一个模态对话框 对话框负责数据的存储和显示 关系图 2 SDI或MDI应用 都可以不包含文档对象 SDI包含一个CWinApp对象 一个框架窗口对象和一个从CWnd派生的CChildView视图对象 视图对象负责数据的显示 MDI应用还包括一个子框架窗口 18 对话框类作为应用程序主窗口负责保存和显示数据 应用程序类 返回 Dialog basedApplication 19 主框架 应用程序主窗口 CChildView视图类负责保存和显示数据 应用程序类 SDIApplication NoneDoc View 返回 20 子框架 视图框架窗口 CChildView视图类 应用程序类 子框架 视图框架窗口 CChildView视图类 主框架 应用程序主框架窗口 MDIApplication NoneDoc View 返回 21 图3 2MFC应用程序开发过程 类向导 集成开发环境 应用程序向导 资源编辑器 Create def cpp h dsw dsp ico rc bmp 源文件 资源文件 编译 obj Build 资源编译 res 应用程序 5 MFC应用程序创建 22 6 最简单的MFC应用程序示例 对于一个MFC应用程序来说 只有CWinApp的派生对象是必不可少的 其它类均可视情况进行取舍 下例是一个最简单的MFC应用程序 例 显示一个消息框 1 创建工程 工程类型选择Win32Application 工程名为Ex3 0 2 创建C 源文件 文件名Ex3 0 cpp 内容如下 23 includeclassCEx3 0App publicCWinApp CWinApp派生类public virtualBOOLInitInstance MessageBox NULL SimplistMFCApplication Ex3 0 MB OK returnTRUE CEx3 0ApptheApp 全局变量 代表应用程序本身 CWinApp InitInstance 虚函数完成应用程序的初始化工作 派生的应用程序类都要重载此函数进行初始化 如完成主框架窗口的构造 窗口定义显示等工作 24 3 设置使用MFC 选择Project Settings 菜单项 选择General页面 在MicrosoftFoundationClasses组合框中选择UseMFCinasharedDLL 4 编译生成并运行此工程 结果显示一个消息框 如下图 图3 3最简单MFC应用示例 25 3 2 MFC程序设计 MFC应用程序的执行过程 参见图3 4 1 构造全局对象 CWinApp派生类对象 2 运行由应用程序框架提供的WinMain函数 26 图3 4MFC应用程序的执行过程 27 3 在WinMain中 通过afxGetApp 获得全局对象的指针pApp 调用全局函数AfxWinInit 为CWinApp的成员变量m hInstance m hPrevInstance m lpCmdLine m nCmdShow赋初值 然后调用pApp InitApplication 这是CWinApp的虚函数 一般不需要改写 调用pApp InitInstance 每个程序都必需改写这个函数 进行应用程序初始化 4 在InitInstance 函数中 先用new构造一个CFrameWnd派生类对象 其构造函数又调用Create 创建主窗口 MFC依此自动为应用程序注册窗口类 调用ShowWindow 显示窗口 调用UpdateWindow 发出WM PAINT消息 28 5 回到WinMain中 调用pApp Run 进入消息循环 通过API函数GetMessage 获得消息 TranslateMessage 处理消息 DispatchMessage 派送消息到CWnd DefWindowProc DefWindowProc 按照消息映射表的定义将消息分发到各相应消息处理函数 如消息队列为空 则Run调用CWinApp OnIdle 进行空闲处理 重载OnIdle 可以去处理后台程序 低优先级 6 若用户选择菜单File Close 则程序收到WM COLSE消息 调用 DestroyWindow 发出WM DESTROY消息 然后调PostQuitMessage 发出WM QUIT消息 此时Run会结束其内部消息循环 调用ExitInstance 7 最后 返回WinMain 执行WinTerm 结束程序运行 29 几点解释 1 每个MFC应用都有stdafx h头文件 由应用程序向导自动生成 2 每个MFC应用都应包含头文件afxwin h 其内部又包含了其他头文件 3 每一个MFC应用程序都包含唯一的CWinApp派生类对象 代表应用程序本身 4 MFC应用程序中看不到WinMain 入口函数 它被封装在应用程序框架里 运行时自动调用 30 3 2 2 MFC消息映射 消息映射 MessageMap 机制 消息映射机制规定每个要响应消息的类定义自己的消息映射表 将消息与处理消息的函数联系在一起 当事件发生产生消息时 在程序中各个类的消息映射表中查找 当找到消息处理函数时 便将消息送至对应的消息处理函数进行处理 每个从CCmdTarget所派生的类都可以接收消息 都可以定义自己的消息映射表MessageMap 31 消息映射表 1 消息消息是Windows用来通知MFC应用程序事件发生的主要方式 应用程序的行为取决于对消息的响应方式 MFC把消息分为三大类 1 标准Windows消息 WM XXX 2 命令消息 WM COMMAND 3 控件通知消息 32 2 消息映射消息映射将消息与应用程序提供的处理该消息的成员函数联系在一起 一组消息映射构成消息映射表 消息映射表由BEGIN MESSAGE MAP和END MESSAGE MAP这一对宏作开始和结束 中间是若干消息映射入口每一个入口由特定的消息宏ON XXX组成 将一个消息与与之对应的处理函数联系在一起 33 定义和使用消息映射表的步骤 在头文件的类声明中添加DECLARE MESSAGE MAP宏声明消息映射 例如 在类的定义文件 cpp 定义消息映射表 方法是在文件的开始处添加BEIGN MESSAGE MAP和END MESSAGE MAP这一对宏 在它们之间放置消息映射宏 定义并初始化消息映射表 在消息与处理消息的函数之间建立联系 例如 在类的定义文件 cpp 中添加消息处理函数 例如 34 消息宏 1 对标准Windows消息的响应 消息宏ON WM XXX定义对标准Windows消息WM XXX的响应 所有派生自CWnd的类均可响应这类消息 系统默认的响应函数为OnXxx 对应关系见下面的表3 3 由于有系统默认的消息和处理函数 在消息映射表中只写宏名 如 ON WM CREATE 35 2 对命令消息的的响应 ON COMMAND宏定义对命令消息的响应 格式为ON COMMAND 命令ID 响应函数 举例如下 ON COMMAND IDM ABOUT OnAbout 表示IDM ABOUT消息由OnAbout 响应ON COMMAND IDM FILENEW OnFileNew ON COMMAND IDM FILEOPEN OnFileOpen 所有由用户定义的命令消息也由ON COMMAND定义消息映射关系 36 3 对控件消息的响应 控件消息由按钮 BN 编辑框 EN 组合框 CBN 列表框 LBN 等产生 在消息名前加上ON 即构成宏名 举例如下 ON BN CLICKED 按钮ID 响应函数 ON CBN DBCLK 组合框ID 响应函数 ON EN SETFOCUS 组合框ID 响应函数 ON LBN DBCLK 列表框ID 响应函数 分别表示选择各个控件后 产生的消息由其后面定义的函数进行处理 37 3 消息处理消息一般由应用程序中对象的成员函数来响应 当某个事件发生后 系统向应用程序消息队列放入一个消息 CWinApp对象取得消息并按照消息映射表的定义将消息派送到某个类的相应的消息处理函数进行处理 使用ClassWizard 见第五章菜单中View菜单介绍 定义消息映射关系 添加消息处理函数 系统会自动生成函数原型和函数框架 开发人员只要添加函数体代码 可以避免一些常见错误的产生 38 程序中类响应windows消息的优先顺序 取决于消息传递的顺序 对于一般的Windows消息 由产生这些消息的对象响应 如窗口的创建WM CREATE 窗口的移动WM MOVE 由产生消息的窗口类响应 如果找不到相应的处理函数 则将消息传递到其父类 一般情况都有缺省的响应函数 对于命令消息WM COMMAND 可由拥有菜单资源的所有类来处理 传递的顺序是视图类 文档类 文档模板类 框架类 应用程序类 即这些类处理命令消息的优先顺序 详见第2章 39 视图类的定义文件 cpp 中必须有消息映射定义 BEIGN MESSAGE MAP CMyView CView 消息映射表定义ON WM LBUTTONDOWN 函数名为OnLButtonDown 其它消息映射入口END MESSAGE MAP 以及对应的消息响应函数定义 voidCMyView OnLButtonDown UINTnFlags CPointpoint 处理消息的操作代码 程序中具体实现 返回 将CMyView的基类CView也包含进去 当在派生类中没找到处理函数时 允许在基类中继续查找 注 40 例如 当用户在视图窗口中按下鼠标左键时 Windows发送WM LBUTTONDOWN消息到应用程序 假设视图类需要响应这些消息 在类的头文件 h 中有函数声明和消息映射表的声明 ClassCMyView publicCView afx msgvoidOnLButtonDown UINTnFlags CPointpoint 函数原型声明DECLARE MESSAGE MAP 消息映射表声明 返回 afx msg标识消息映射函数 所有由ClassWizard生成的消息处理函数原型说明前都有这一标识 注 41 3 2 3 文档 视图结构 1 文档类在基于文档 视图结构的应用程序中 CDocument的派生对象负责读入 保存和管理应用程序的数据 每个文档类可能与多个视图类关联 而每个视图包含一个指向与其相关的文档的指针 文档类允许向其中增加数据成员 应用程序的数据可以是任何类型的 或者是任何自定义的数据结构 如结构体 类或链表等 42 3 2 3 文档 视图结构 文档类的常用成员函数 带 的表示是可重定义函数 表3 4 43 44 2 视图类 视图类对象代表了应用程序的窗口客户区 是文档信息的一个显示窗口 视口 它同时也是用户与程序之间信息交互的桥梁 用户对数据的编辑和修改需要通过键盘或鼠标进行 这些消息都由视图类接受后再反映到文档类 45 视图类的派生关系 图3 5 46 CView类提供了向视图或打印机进行输出的基本框架 决定了视图的基本特性 派生的视图类可以重载基类的函数 或增加新的函数以决定特定视图的特性 CView的派生类可以多种方式显示文档类的信息 每个视图类根据显示的方式各自定义其显示代码 MFC提供了一系列这样的类 如CTreeView树型视图CListView列表型视图CFormView显示基于对话框模板的视图CScrollView带滚动条的视图 47 1 视图类实现特定视图的特性的虚函数 表3 5 48 CEx3 1Doc pDoc GetDocument 通过GetDocument获得与视图关联的文档类指针 通过指针pDoc访问文档类的数据成员和函数成员 在视图 窗口 中显示文档对象 当用户通过视图改变文档数据时 可设置自动更新文档内容 文档 视图结构已经把应用程序所需要的数据处理与显示 虚函数 的框架构造好 程序设计人员只需要将具体应用的数据添加到文档类 并根据数据类型在视图类的虚函数OnDraw 中完成数据的显示 2 视图类的成员函数访问与其关联的文档类的方式 49 3 文档模板类 CDocTemplate类将框架 视图 文档对象及应用程序的资源捆绑在一起 应用程序每打开一个文件 至少创建一个文档对象 一个视图对象和一个框架窗口 而文档模板对象负责管理所有这些对象 并将各种相关资源与之联系在一起 在大多数情况下 程序不需要对这个类进行修改 对于SDI应用 使用CSingleDocTemplate文档模板 对于MDI应用 使用CMultiDocTemplate文档模板 MDI允许有多个文档模板 将不同文档 视图类联系在一起 实现不同文档视图显示关系 50 4 应用程序创建过程 使用AppWzard 根据实际需要 选择创建合适的应用程序框架 是否使用文档 视图结构 使用SDI或MDI等 在文档类中添加程序所处理的数据 作为文档类数据成员 在视图类中取得文档数据 以合适的方式在窗口中显示出来 51 5 应用实例 例3 1 创建一个包含文档 视图结构单文档界面应用的实例 为文档类添加一个字符串数据 在视图窗口显示出来 步骤如下 1 在File菜单中选择New 如图3 在Project页面选择MFCAppWizard exe 在Projectname中输入Ex3 1 并选择合适的路径按OK按钮 52 2 在AppWizardStep1中 如图3 选择SingleDocument单选按钮 并选中Document ViewarchitechureSupport复选框 表示使用文档 视图结构 按Finish按钮 显示NewProjectInformation信息框 显示新创建的工程的有关信息按OK按钮 这样工程创建完毕 53 图3 NewProject对话框 54 图3 AppWizardStep1 55 在VC集成开发环境中看到 新工程生成了五个类 如图3 在classview页面上可看到这些类 CAboutDlg派生自CDialog 一个About对话框 CEx3 1App派生自CWinApp 其全局对象theApp代表应用程序本身 CEx3 1Doc派生自CDocument 文档类 CEx3 1View派生自CView 视图类 CMainFrame派生自CFrameWnd 程序框架类 56 文档 视图及应用程序类名都以工程名开头 后接对应的类型名 这有助于在程序中有多个文档视图类时区分主视图与其它视图 区分主文档与其它文档类 应用程序向导AppWizard为每个类生成了一个头文件和一个 cpp文件 还自动生成了stdafx h和stdafx cpp 图3 AppWizard还生成了缺省的用户界面资源文件 在Resourceview页面显示 57 图3 ClassView 图3 FileView 58 3 为文档类增加数据成员 在编辑窗口打开文档类的头文件Ex3 1Doc h 手工添加一个字符数组成员m StrName 或在Workspace的ClassView页面 右击CEx3 1Doc类 在弹出式菜单中选择AddMemberVariables 在对话框中输入变量类型和名称 在文档类构造函数中对新增加的变量进行初始化 4 显示字符串 在CEx3 1View的OnDraw 函数显示字符串 59 图3 10例3 1第一步主界面 60 3 3 用户界面资源的应用 资源是windows应用程序的一种特殊数据 包括菜单 加速键 光标 位图 图标 对话框 字符串 工具栏 状态栏等 资源一般放在exe或DLL文件中 当windows将程序装入内存时 一般不将资源同时装入 而是当需要某个资源时才将相应资源装入 资源定义在资源脚本 resourcescirpt 文件中 以 rc为文件扩展名 文件名与工程名相同 资源脚本文件中定义了各种资源的相关数据 Windows通过使用不同的资源标识符前缀来区分不同资源类型 如表3 所示 这样做虽然不是必须的 但遵循这样的规则有利于提高程序的通用性和可读性 61 表3 资源类型及其标示 资源标识前缀IDM ID IDI IDB IDD IDR IDC IDS 资源类型菜单项ID菜单命令ID图标ID位图ID对话框ID菜单栏 工具栏 加速键控件ID字符串 返回 62 VisualC 6 0中提供了资源编辑器 对资源进行可视化编辑 并自动生成资源脚本文件 脚本文件可用文本编辑器进行编辑 但其可读性较差 容易出错 一般情况下尽量不要进行编辑 用户定义的资源标识符号常量定义在resource h文件中 3 3 用户界面资源的应用 63 3 3 1 菜单 分类 顶层菜单 一般位于应用程序主窗口或顶层窗口弹出式菜单 选择某个菜单项后弹出的子菜单 1 菜单的编辑 如果是AppWizard产生的程序 系统已为框架创建了一个标准的主菜单 包括文件 编辑 视图 窗口帮助等标准菜单 定义了各菜单项的ID及相应的命令处理函数 在ResourceView页面 打开工程资源 选择Menu 然后双击主菜单资源IDR MAINFRAME标示 可打开菜单编辑器 64 添加新的菜单资源 选择InsertResource菜单项 在InsertResource对话框中 选择Menu资源类型 单击New按钮 缺省新菜单名为IDR MENU1 a 增加一个顶层菜单 在菜单属性对话框中 选中Pop up选项 可以定义一个顶层菜单 在Caption编辑框中输入菜单名 菜单名即显示在菜单上 若在菜单名的某个字符前加一个 符号 则菜单名该字符下显示一个下画线 可用Alt加该字符作为选择菜单的快捷方式 对中文菜单 文件 如希望用Alt F作为键盘操作方式 可写成 文件 F 在定义好的菜单后面 仍预留了一个空白菜单 可拖动该空白菜单到任意位置增加新的菜单 65 b 增加一个子菜单 若在定义菜单项时选中Pop up选项 则在该菜单项右边出现一个三角形符号 同时右边出现一个新的菜单 再定义这个菜单 c 定义菜单项 双击空白菜单项 打开菜单项属性对话框 如图3 1 在General页面上输入Caption菜单项名称及其ID值 在Prompt编辑框中的字符串是选择该菜单项时状态栏上显示的内容 在 n后面的内容为当光标移至工具栏上与其ID值相同的图标上时状态栏显示的内容 在空白菜单项被定义后 该菜单的最下面又出现一个空白菜单项 拖动该空白菜单项可在已定义的菜单内任何位置插入新菜单项或新子菜单 66 d 创建菜单加速键 a 在Caption编辑框中 在菜单项名后 在字符 t后 加上快捷键组合 如图3 1 所示 Ctrl O表示打开文件操 快捷键组合会出现在菜单项名右端 目的是给用户一个提示 b 在Workspace的ResourceView页面上 找到加速键Accelerator资源 AppWizard生成的缺省加速键资源名为IDR MAINFRAME 双击它打开加速键表 在已有加速键表后面 有一个空白行 双击它打开加速键属性对话框 如图3 1 选择某个菜单项ID 在Key列表框选择某个虚拟键作为菜单命令的快捷方式 或选择NextKeyTyped按钮 此后键盘输入的按键组合即为菜单命令加速键 这一步才是快捷键的定义过程 67 图3 1 菜单项设置 返回定义菜单项 返回创建菜单加速键 68 定义Ctrl O为ID FILE OPEN的快捷方式 在ID编辑框中输入ID FILE OPEN 在Key中键入O 然后选中Ctrl复选框即可定义了菜单项的快捷方式 图3 1 快捷键设置 注意 1 不要对不同菜单命令使用相同的加速键组合 以免产生二意性 2 加速键命令必须有菜单命令与之对应 加速键不应该是某个命令唯一启动方式 69 MFC程序可以处理两种菜单消息 2 菜单消息 WM COMMAND为菜单命令消息 当选择菜单项 工具栏按钮或加速键之一会发出菜单命令消息 MFC依据一定的消息传递途径将消息传递给相应的处理函数进行处理 如果在消息传递途径的消息映射表中找不到相应的处理函数 该菜单项或按钮会被禁止使用 70 UPDATE COMMAND UI是菜单更新消息 处理菜单状态的动态变化 如希望根据程序的执行状态 激活或禁用某些菜单项 设置选中标记 或更改菜单项文字等 就要定义这一消息处理函数 这一消息在MessageMap中定义如下 ON UPDATE COMMAND UI 例如 ON UPDATE COMMAND UI ID EDIT COPY OnUpdateEditCopy 在某个菜单显示前 框架将发送菜单内所有菜单项的更新命令 有更新处理函数的菜单项 调用其处理函数更新菜单显示方式 没有更新处理函数的菜单项 查找其命令处理函数 若仍然没有 则将菜单项禁用 71 3 菜单消息的处理 定义好菜单项及其ID后 为菜单命令添加响应函数 实现方法是借助ClassWizard 在需要响应菜单命令的类的消息映射表中增加一个入口 即定义一个命令消息ON COMMAND宏 选择View ClassWizard 打开ClassWizard对话框 在MessageMap页面 图3 14 在ClassName列表框中选择要响应菜单命令的类名 在ObjectIDs列表框中选择菜单ID 在Message列表框中选择COMMAND或UPDATE COMMAND UI 然后按AddFunction按钮 弹出AddMemberFunction对话框 可以修改函数名或接受缺省函数名 按OK结束这个对话框 然后在ClassWizard对话框中按EditCode按钮 直接跳至新增函数的定义处 72 图3 14ClassWizard添加消息映射关系 73 3 3 2工具栏 工具栏是一个包含一个或多个命令按钮的窗口 一般情况下附着在窗口客户区上方菜单栏下面 也可作为一个浮动的小窗口 工具栏为菜单命令提供可视化的快捷操作方式 模拟大部分的菜单行为 1 编辑工具栏在Workspace的ResourceView页面 点击Toolbar前的 号可以看到缺省的工具栏资源IDR MAINFRAME 双击它打开可视化工具栏编辑器 工具栏资源由一组按钮组成 每个按钮是一个16色位图图标 工具栏编辑器提供一个简单的位图编辑器 点击某个图标即可编辑它 用鼠标拖动图标 改变它在工具栏中的位置用鼠标拖出工具栏外 删除图标 74 双击位图打开ToolbarButtonProperties对话框 图3 15 在ID列表框中输入命令ID 列表框中列出了当前工程中已存在的ID 可为已有命令提供可视化的快捷操作方式 图3 15工具栏图标编辑 75 2 工具栏命令处理 如果工具栏按钮与某个菜单项有相同的ID 则它们共享一个命令响应函数 不需要另外定义命令响应函数 具有相同ID的菜单项和工具栏按钮还共享提示字符串 它们的显示状态也同步变化 如果与工具栏按钮对应的菜单项定义了更新函数 工具栏按钮也会同步实现状态的动态变化 76 3 3 3状态栏 状态栏是出现在应用程序窗口底部的显示程序运行状况的窗口 当用户选择了菜单项或某个工具栏按钮时 状态栏显示它们的提示字符串 AppWizard为应用程序添加缺省的状态栏 为CMainFrame类增加CStatusBar类的数据成员m wndStatusBar 在MainFrame cpp文件中添加提示符数组 作为状态栏创建时的参数 staticUINTindicators ID SEPARATOR 状态栏指示器ID INDICATOR CAPS 显示CapsLock键状态ID INDICATOR NUM 显示NumLock键状态ID INDICATOR SCRL 显示ScrollLock键状态 可以向数组中增加ID以增加状态栏上显示栏 77 3 3 3状态栏 图3 16例3 1主界面 78 3 4 对话框的应用 3 4 1对话框的工作方式 种类和创建方法 1 对话框在应用程序中的工作方式 对话框是一个读入或写出数据的图形界面对象 由集成开发环境中的对话框模板提供 可以向模板添加各种控件 如按钮 编辑框 单选复选按钮等 构成程序的对话框资源 应用程序要使用对话框还需定义一个CDialog派生类的对话框类与资源相连接 并在这个对话框类中定义一些成员变量与对话框中的控件相对应 提供对话框控件的缺省数据值 79 程序运行时需要用到对话框时依据对话框资源激活对话框 接收用户输入后通过成员函数更新文档类数据成员 如图3 17示 图3 17对话框与文档的数据交换 构造对话框并更新文档数据 数据交换 对话框模板controls public datamembers 文档类 applicationdatas 对话框类对象 80 2 对话框的种类 Windows有两种对话框 模态对话框和非模态对话框 构造两种对话框的大多数工作都相同 只是两者的显示和数据处理有些不同 模态对话框 ModalDialogBoxes 工作时使其父类窗口无效 直到对话框结束 也就是说 该对话框打开后 程序等待用户输入 在关闭对话框后才执行其它任务 非模态对话框 ModelessDialogBoxes 在打开期间 允许用户切换到程序其它部分 不一定要关闭对话框 WinWord中的FindandReplace对话框是一个典型的非模态对话框 81 3 对话框的创建与编辑 a 对话框的创建 选择Insert Resource 在InsertResource对话框中选择Dialog类型 按New按钮 打开对话框编辑器 缺省情况下 对话框模板提供了OK和Cancel两个按钮 同时打开了对话框工具栏和控件工具栏 如下图 82 图3 18对话框模板及编辑工具 83 在对话框模板内右击鼠标 在弹出的菜单中选择Properties 打开DialogProperty对话框 图3 19对话框属性对话框 84 b 控件属性 将控件工具栏中的任一种控件拖至对话框模板中 在控件上右击鼠标 选择Properties打开控件属性对话框 如图3 20 各种控件属性对话框基本相似 在ID框中输入标识控件的唯一ID值 在Caption中输入控件上显示的字符 Edit控件没有这一属性 Visible表示该控件在对话框创建时是否显示 Group用来控制控件分组 Disabled使控件不可用 Tabstop表示是否用Tab键选择控件 85 图3 20控件属性设置对话框 86 c 控制Tab顺序 当打开对话框编辑器后 集成开发环境的菜单上多了一个Layout菜单 其中主要是对话框工具栏上显示的一些命令 其中有一个命令TabOrder 定义当用户用Tab键移动输入焦点时各控件接受焦点的顺序 如图3 21所示 d 分组控制 VC提供了根据控件功能将控件进行分组的工具 使用户更易于理解对话框的结构 在分组框中使用最多的是单选按钮 radiobuttons 一组单选按钮允许用户在组内多个相互排他的选项内选择一项 87 图3 21设置TabOrder 88 e 组合框ComboBox 将组合框拖至对话框中后 按向下箭头 显示运行时下拉组合框的大小 调整到合适大小 组合框的属性对话框比其它控件多一个Data页面 用于输入组合框中的数据项 每一行是一项 输完一项按Ctrl Enter键换行 f 列表框ListBox 在对话框编辑器中只能设置列表框大小 位置和ID 数据的初始化需要通过编程实现 一般在拥有列表框控件的对话框的OnInitDialog函数中 调用CListBox AddString 无序 或CListBox InsertString 有序 插入字符串 89 g 测试对话框 当所有控件都布置好并定义属性后 可以选择对话框工具栏上的测试按钮 测试对话框工作情况 必要的话做适当调整 90 3 4 2将对话框与程序连结 1 对话框类及数据成员的定义 a 创建对话框类 对话框资源建立好后 在对话框中右击鼠标 选择ClassWizard菜单项 会出现提示框 说明新建的对话框资源是新资源 是否需要建立一个新类或选择一个已存在的类 若选择新类 出现图3 23示的Newclass对话框 选定后 在WorkSpace中可看到新增加的类 自动生成的 StudentDlg h 头文件和StudentDlg cpp源文件 91 图3 23新建类对话框 92 b 增加数据成员 要使对话框能与程序通讯 还需给对话框类增加数据成员 以保存各控件的初始值 并从控件读取数据 与控件对应的数据成员可以是变量或控件类型 如表3 9所示 表3 9对话框与控件对应的变量或控件数据成员 93 在ClassWizard的MemberVariables页面 选择对话框类 在ControlIDs中列出了对话框中所有控件ID 如图3 24 选择某个ID 按AddVariable 按钮 弹出AddMemberVariable对话框 可输入成员名 在Category中选择值 value 变量或控件 controls 类型 在Variabletype列表框中 若是Value类 选择变量数据类型 若是Controls 选择控件类 按OK 成员添加成功 设计不同的菜单命令响应函数 可以用对话框成员变量更新文档数据 也可以用文档数据为对话框数据成员赋值 再显示对话框 94 图3 24为对话框添加数据成员 95 2 对话框的显示 模态对话框调用其DoModal 函数显示 按OK或Cancel按钮关闭对话框非模态对话框调用Create 函数创建并显示对话框用DestroyWindow关闭对话框 3 为控件添加或修改消息响应函数 打开ClassWizard 在MessageMap页面 可以为控件添加响应函数 如图3 26 96 图3 26为控件添加响应函数 97 图3 27例3 1新主界面 98 3 5 基于对话框的应用程序设计 AppWizard提供了基于对话框 Dialogbased 的应用程序框架 程序可以简单到只有CWinApp派生类和一个对话框类 对话框就是程序框架 负责数据输入输出和存储 以及消息处理 对话框可以有最小化按钮 甚至可以连接一个菜单 基于对话框的应用程序结构简单 只要正确选择控件及定义成员变量 设计正确的算法 适合开发数据不多 功能简单的程序 99 3 6 文本和图形输出 Windows设备描述表DC devicecontexts 是对各种不同设备的抽象 应用程序只要向DC输出 由DC负责处理不同设备的差异 DC是一个数据结构 描述了图形设备接口GDI进行输出所需要的信息 包括颜色 填充方式 画笔宽度等 在Windows中 DC允许应用程序使用输出设备 DC在应用程序 设备驱动程序 与输出设备之间建立联系 并提供绘图信息 在MFC中 CDC类封装了设备描述表DC 该类的核心是m hDC 代表一个指向窗口DC的句柄 100 1 CDC类及其派生类 CDC类派生自CObject 它具有CObject类的共同特性 如可以动态创建 可进行序列化操作 101 a 设置颜色 windows使用一个32位无符号整型值来表示图形和文本的颜色 其数据类型为COLORREF 它包含4个字节 第一字节未使用 不要改变其值 后面三个字节分别表示红 绿 蓝三种基本色的成分 每一种颜色用一个0 255之间的数字表示 设备描述表最常见的使用是在视图类的OnDraw函数中进行图形和文本输出 2 CDC类的使用 102 宏RGB定义颜色值 宏RGB定义一个颜色的三种基本色成分 返回COLORREF值GetRValue返回一个COLORREF中红色分量GetGValue返回一个COLORREF中绿色分量GetBValue返回一个COLORREF中蓝色分量例 COLORREFcolor RGB 125 125 125 CBrushbrush color TRACE TheRedcomponentofthebrushis d n GetRValue color 103 CDC的像素操作函数SetPixel 和GetPixel 使图形设置精确到像素 b 像素操作 voidCExView OnDraw CDC pDC pDC SetPixel CPoint 100 100 RGB 255 0 0 typedefstructtagPOINT LONGx LONGy POINT CPoint是MFC中表示点的类 派生自POINT结构 封装了对CPoint和POINT进行操作的函数 主要是一些运算符函数 104 c 绘制直线及其它图形 CDC用于图形操作的成员函数 MoveTo从当前点移至参数点LineTo从当前点画直线至参数点Polyline用CPoint对象的数组作参数 将数组中各点依次连直线 Rectangle画长方形Ellipse以长方形为界 画一个椭圆Polygon以数组中点为顶点 画一个多边形 105 d 文本输出 文本输出包含两部分工作 分别用两组函数实现 设置文本特性如字体 颜色 对齐方式等输出文本 106 3 使用GDI对象 GDI对象类CGdiObject派生CObject 是画笔 画刷 字体 位图等GDI对象的基类 其派生类封装了各种绘图工具 107 a GDI对象的构造 调用GDI类的构造函数产生一个GDI对象CPenpen1 PS SOLID 0 RGB 0 255 0 或 CPenpen1 pen1 CreatePen PS SOLID 0 RGB 255 0 0 b CDC与GDI对象 应用程序本身不需要构造GDI对象 程序中构造一个CDC对象后 系统为其提供了默认的属性和默认的GDI对象 但CDC封装了对GDI操作的成员函数 可以修改相关属性 如SetTextColor 也可选择自定义的GDI对象 108 Windows预定义了标准GDI对象 供系统和程序使用 称为备用GDI对象 可为多个程序同时使用 备用对象包括最常用的字体 画笔 画刷等 用函数CDC SelectStockObject选择备用对象 并返回原值 CPenpen1 自定义画笔pen1 CreatePen PS SOLID 0 RGB 255 0 0 CPen poldPen pDC SelectObject 恢复原值 109 表3 15备用GDI对象 110 c 画笔CPen使用 画笔有线型 线宽 颜色三种属性 在构造画笔时需提供它们的信息 线型有七种 分别为 实线PS SOLID点线PS DOT虚线PS DASH点画线PS DASHDOT双点画线PS DASHDOTDOT空画笔PS NULL画图形内框PS INSIDEFRAME 111 d 画刷CBrush使用 画刷用于填充区域 有三类画刷 根据画刷类型不同 CBrush有多个构造函数 112 e 区域使用 CRgn类封装了窗口的GDI区域 该区域可以是由一个或多个椭圆形或多边形合成的 通常将CRgn的成员函数与CDC的剪切成员函数结合使用 实现多种图形显示方式 113 面向对象技术有一个术语 永久保存 Persistence 即保存应用程序的各种信息 MFC支持两种永久保存 序列化和应用程序状态保存 序列化 Serialization 是指程序的数据保存到文件或从文件读出 应用程序框架提供了完成序列化的大多数结构 程序开发人员只需要完成针对特定应用的数据序列化代码 应用程序运行状态保存通过注册表完成 3 7 文档的保存 114 3 7 1 文档序列化 1 序列化 序列化是将数据从应用程序写入数据文件或从数据文件读入应用程序的过程 序列化在文档 视图结构中完成 当用户要保存或读出数据时发生序列化过程 当文档数据发生变化时 序列化会提示用户保存数据 序列化过程从文档类对象序列化开始 文档类可直接序列化普通数据 或序列化对象成员 成员对象各自的类完成自身数据序列化操作 115 3 CArchive为序列化提供一个上下文 1 CObject类是所有可序列化类的基类 它提供了序列化的协议和功能 只有派生自CObject的类才能序列化 2 CDocument类存储应用程序的数据 数据成员和对象成员 MFC中与序列化相关的类 4 CFile代表存储在磁盘介质上的文件 直接支持非缓冲文件和二进制文件读写 其派生类支持文本文件和内存文件 116 读写过程如下图 Serialize 117 2 运行时类型信息 从文件读入对象时 程序根据运行时类型信息 Run timeclassinformation即RTTI 来判断要读入的对象类型 从而动态地构造 重构 恰当的对象 每创建一个新的对象 都记录必要的类型信息 产生一个类型信息结构 构成运行时类型信息表 链表 以便运行时进行类型检查 类型信息由CRuntimeClass结构记录 118 structCRuntimeClass LPCSTRm lpszClassName 类名intm nObjectSize UINTm wSchema 版本号CObject PASCAL m pfnCreateObject 函数指针 指向该类的缺省构造函数CRuntimeClass m pBaseClass 指向基类的运行时信息结构staticCRuntimeClass pFirstClass 链表头指针 静态成员 只有一个CRuntimeClass m pNextClass 指向链表下一对象 CRuntimeClass 119 作为可序列化类的公共基类 CObject定义中包含下面的代码 classCObject public virtualCRuntimeClass GetRuntimeClass const 返回当前

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论