




已阅读5页,还剩293页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1 VisualC 程序设计与应用 主编马石安魏文平 清华大学出版社 2 主要内容 第1章VisualC 开发环境第2章MFC应用程序第3章图形与文本第4章菜单 工具栏与状态栏第5章对话框第6章Windows常用控件 第7章文档与视图第8章打印编程第9章动态链接库编程第10章多线程编程第11章数据库编程第12章多媒体编程 第5章对话框5 1对话框概述5 2模式对话框5 3非模式对话框5 4属性页对话框5 5通用对话框5 6应用实例 VisualC 程序设计与应用教程 4 5 1对话框概述 5 1 1对话框的类型 主要有以下两种 模式 Model 对话框无模式 Modeless 对话框 5 5 1 2对话框的CDialog类 CDialog类从CWnd类派生而来 所以它继承了CWnd类的成员函数 具有CWnd类的基本功能 可以编写代码移动 显示或隐藏对话框 并能根据对话框的特点增加新的成员函数 扩展它的功能 6 7 8 对话框主要由以下两部分组成 1 对话框模板 对话框模板定义了对话框的特性 比如大小 位置和风格 以及对话框中每个控件的类型和位置 2 对话框类 从CDialog类派生的对话框类提供编程接口来管理对话框 5 1 3对话框的组成 9 5 2模态对话框 对于模式对话框的编程可以按以下步骤进行 1 根据要求创建对话框模板 2 使用ClassWizard创建对话框类并进行各类事件函数的代码编写 3 对视图类进行编辑 以便对话框能够被激活 10 5 2 1设计对话框模板资源打开对话框编辑器 使用菜单 Insert Resource 打开InsertResource对话框 选中Dialog后单击New按钮 使用项目的ResourceView 找到Dialog资源 右击后选择InsertDialog 对话框编辑器如下图所示 11 对话框模板 控件布局工具栏 控件工具栏 12 对话框模板 Controls工具 Dialog工具栏 调整对话框显示时的大小和位置 拖放各种类型的控件到对话框中 调整控件的位置 测试对话框的外观和行为 13 设计对话框模板资源有两个重要的内容 从Controls工具栏中选择控件 Control 功能各异的小小零组件 加到对话框中 并调整其位置和大小设置控件的Caption ID以及其他属性 14 1 增加或删除控件 增加控件 从控件工具栏中选中要增加的控件 再将此控件拖动至对话框模板中的确定位置上删除控件 先单击对话框中的控件 再按Delete键 15 2 设置控件属性 属性设置在与每个控件相对应的属性对话框中进行 打开控件属性对话框 在控件上右击鼠标 在弹出的快捷菜单中选择Properties选择控件 选择View Properties菜单项 16 控件属性对话框 17 对话框的属性也是在对话框的属性对话框中设置 在对话框任意空白处单击鼠标右键 在弹出的快捷菜单中选择Properties 18 3 测试对话框的运行效果测试对话框的方法有下面3种 选择菜单项Layout Test 单击布局工具栏上的Test按钮 按快捷键Ctrl T 19 例5 1 创建一个单文档的应用程序MyDialog 向应用程序中添加如图所示的对话框模板资源 并设置控件的Caption ID属性 20 5 2 2设计对话框类 主要包括下面几个方面 从MFC的CDialog中派生出一个类 用来负责对话框行为 利用ClassWizard把这个类和已编辑完成的对话框资源连接起来 这意味着必须声明某些函数 用以处理相应的对话框消息 并将对话框中的控件对应到类的成员变量上 这也就是所谓的对话框数据交换 DDX DialogDataeXchange 如果对这些变量内容有 确认规则 的话 ClassWizard也允许设定 这就是所谓的对话框数据验证 DDV DialogDataValidation 对话框的初始化 21 1 创建对话框类 例5 2 完善例5 1中的应用程序MyDialog 给对话框资源添加相应的对话框类 22 2 创建对话框成员变量 ClassWizard类向导的MemberVariables页面用来为对话框类添加和删除与对话框控件关联的成员变量 23 例5 3 继续完善例5 2中的应用程序 在对话框类中添加与控件相关联的成员变量 24 3 对话框的初始化 使用以下3种方法 1 在构造函数中初始化主要针对对话框的数据成员 2 WM CREATE初始化 3 WM INITDIALOG初始化 25 5 2 3运行对话框 模态对话框的运行分两个步骤 创建一个对话框对象调用CDialog DoModal 函数打开对话框DoModal 函数负责模态对话框的创建和撤消 可以根据其回值是IDOK还是IDCANCEL来判断用户关闭对话框时按的哪一个键 26 例5 4 完善例5 3中的应用程序 通过 对话框 模态对话框 菜单项 打开上述标题为 输入边长 的对话框 并根据输入的边长画一个正方形 27 5 2 4对话框数据交换和校验机制 CDialog类通过调用其成员函数DoDataExchange 实现对话框数据交换和验证 在DoDataExchange 中使用了MFC提供的CDataExchange类 该类实现对话框类的成员变量与控件之间的数据交换DDX和数据验证DDV DDX将成员变量与对话框控件相连接 完成数据在成员变量和控件之间的交换 DDV用于数据的校验 它能自动校验输入的数据 如字符串的长度或数值的范围 是否符合设计要求 28 DoDataExchange 函数由框架调用 在应用程序MyDialog中 可以找到下列函数 voidCSquare DoDataExchange CDataExchange pDX CDialog DoDataExchange pDX AFX DATA MAP CSquare DDX Text pDX IDC LENGTH m length DDV MinMaxInt pDX m length 10 200 AFX DATA MAP DDX函数调用语句 表明m length是一个Value值类别的成员变量 用于交换IDC LENGTH控件中内容 DDV函数调用语句 程序运行后 如果用户的输入数据超出10 200的范围 DDV将显示提示信息对话框 提示用户有效的输入范围 29 控件与成员变量之间的数据交换通过调用UpdateData 函数进行 UpdateData 函数只有一个BOOL类型的参数当参数为TRUE时 MFC通过调用DoDataExchange 函数将数据从控件传递到关联的成员变量当参数为FALSE时 数据从成员变量传递到关联的控件 如下图所示 30 31 5 3非模态对话框 5 3 1非模态对话框的特点 与模态对话框比较 相同 创建对话框资源 添加对话框类 添加成员变量和消息处理函数的方法不同 创建和退出对话框的方式 32 1 Visible属性模态对话框不需要设置该属性 而非模态对话框必须具有Visible风格 否则对话框是不显示的 另一种方法是调用CWnd ShowWindow SW SHOW 来显示对话框 33 2 对话框窗口的创建方式非模态对话框的创建是通过调用CWnd Create 函数来实现的 Create 函数与DoModal 函数不同之处是 Create 创建对话框后立即返回 而DoModal 函数在对话框关闭后才会返回 34 3 对话框对象的创建方式由于在Create 返回后 不能确定对话框是否已关闭 这样也就无法确定对话框对象的生存期 所以不能以局部变量的形式创建非模态对话框的对象 只能用new操作符动态创建 并且在调用对话框类的窗口类内声明一个指向对话框类的指针变量 通过该指针访问对话框对象 35 4 窗口删除函数非模态对话框必须调用CWnd DestoryWindow 来关闭对话框 模态对话框是调用CDialog EndDialog 关闭对话框 由于默认的对话框函数OnOK 和OnCancel 都是调用EndDialog 关闭对话框的 该函数使对话框不可见但不删除对话框对象 所以非模态对话框类要定义自己的OnOK 和OnCancel 函数 调用DestoryWindow 来关闭对话框 36 5 清理对话框对象的方式与创建对象的方式new操作相对应 使用delete操作删除一个非模态对话框对象 当屏幕上一个窗口被关闭后 框架会自动调用CWnd PostNcDestroy 函数 也可以编写程序代码 在这个函数中清理非模态对话框对象 37 6 必须有一个标志表明非模态对话框是否是打开的因为在非模态对话框打开的情况下 用户有可能再次选择打开该对话框 这时不能再创建一个新的非模态对话框 程序根据标志来判断是打开一个新的对话框还是激活一个已打开的对话框 通常可以用拥有者窗口中的指向对话框对象的指针作为这种标志 当对话框关闭时 给该指针赋NULL值 以表明对话框对象已不存在了 38 例5 5 创建一个单文档的MFC应用程序 以非模态对话框的形式实现应用程序MyDialog同样的功能 39 5 3 2窗口对象的自动清除 自学 40 5 4属性页对话框 属性页对话框实际上是一个包含了多个子对话框的对话框 这些子对话框通常被称为页 Page 每次只有一个页是可见的 在对话框的顶端有一行标签 用户通过单击这些标签可以切换到不同的页 为了支持属性页对话框 MFC提供了CPropertySheet类和CPropertyPage类 分别代表属性页对话框和对话框中的某一页 41 例5 6 创建一个单文档的MFC应用程序Li5 6 通过 对话框 属性页对话框 菜单项 打开如图所示的对话框 当按确定按钮后 将在消息框中输出相关信息 42 例5 6 使用CpropertySheet派生类对象来创建与例5 5同样的属性页对话框 43 5 5通用对话框 44 5 5 1CFileDialog类 用CFileDialog类提供的通用文件对话框 实现Windows标准的 打开 和 另存为 功能 45 使用CFileDialog可按以下步骤进行 构造CFileDialog类的对象 该类的构造函数为 CFileDialog BOOLbOpenFileDialog 值为TRUE 构造 打开 对话框 值为FALSE 构造 另存为 对话框LPCTSTRlpszDefExt NULL 默认的文件扩展名LPCTSTRlpszFileName NULL 出现在文件名编辑框中的初始文件名DWORDdwFlags OFN HIDEREADONLY OFN OVERWRITEPROMPT LPCTSTRlpszFilter NULL CWnd pParentWnd NULL文件过滤器 用于确定显示在文件列表中的文件类型 46 例如 以下字符串就是一个描述只在文件列表框中显示文本文件 txt 和Microsoft文件 doc 的过滤器 CFileDialogdlg TRUE bmp bmp OFN HIDEREADONLY OFN ALLOWMULTISELECT 文本文件 txt txt Word文件 doc doc 第1个参数TRUE 打开 对话框 第2个参数 bmp 如果在文件名对话框中输入文件名时未指定扩展名 则会自动附加 bmp 第3个参数 bmp 文件名对话框中的初始文件名是 bmp 第4个参数代表dwFlags 不显示隐藏文件 且可以在列表框中进行多选 第5个参数是过滤器 在文件类型下拉列表框中显示了文本文件 txt 和Word文件 doc 47 2 调用成员函数DoModal 将对话框显示在屏幕上 并让用户从中选择文件 3 如果DoModal 返回的是IDOK 那么调用下表中的成员函数获取文件信息 48 例5 7 创建一个单文档的MFC应用程序Li5 7 利用文件存取对话框取得一个文件的路径名 49 5 5 2CColorDialog类 CColorDialog类提供了可以选择颜色的对话框 使得用户可以从颜色列表中选择要用的颜色 对该类的使用可按下列步骤进行 1 在视图类相应位置构造CColorDialog对象 2 设置或修改成员变量m cc来初始化对话框 m cc的结构类型为COLORREF 3 调用成员函数DoModal 来显示对话框并让用户从中选择颜色 50 4 如果DoModal 返回的是IDOK 那么用户所做的颜色选择将保存在m cc中 通过使用该类的成员函数GetColor 即可得到选择颜色的RGB值 例5 8 创建一个单文档的MFC应用程序Li5 8 利用颜色选择对话框选择颜色 并在视图区画一个该颜色的矩形 51 5 5 3CFontDialog类 CFontDialog类封装了标准的 字体 对话框 使得用户可以从系统安装的字体列表中选择要用的字体 CFontDialog类的使用步骤与CColorDialog的使用过程是一样的 只是m cc的结构类型为LOGFONT 在选择了字体后 可通过下表中的成员函数获取所选择的字体信息 52 53 例5 9 创建一个单文档的MFC应用程序Li5 9 利用字体选择对话框选择字体的属性 并在视图区以该属性显示文本信息 54 5 5 4CPrintDialog类和CPageSetupDialog类CPrintDialog类支持打印和打印设置对话框 通过这两个对话框用户可以进行与打印有关的设置 55 5 5 5CFindReplaceDialog类CFindReplaceDialog类用于实现查找和替换对话框 这两个对话框都是非模态对话框 用于在正文中查找和替换指定的字符串 56 5 6应用实例 制作一个简单的计算器 实现加 减 乘 除 求倒数和平方根的混合运算 并能进行清屏及倒退操作 57 第7章文档与视图7 1文档 视图结构7 2简单的文档 视图结构应用程序7 3文档的读写7 4分割视图窗口7 5多文档的应用程序7 6应用实例 VisualC 程序设计与应用教程 58 7 1文档 视图结构 为了统一和简化数据处理方法 Microsoft公司在MFC中提出了文档 视图结构的概念 把数据管理和显示方法分离开来 需要考虑 程序的哪一部分拥有数据程序的哪一部分负责更新数据如何以多种方式显示数据如何让数据的更改有一致性如何储存数据 放到永久储存装置上 如何管理使用者接口 59 7 1 1概述 文档 视图结构的基本概念及创建过程 以例2 1为例 1 文档 Document 在文档 视图结构中 文档是用来管理和组织数据的 CDocument类支持文档的标准操作 为了在应用程序中处理文档 首先应该从CDocument类派生出一个属于自己的文档类 并且在类中声明一些成员变量 用来存放数据 然后完成读取和修改文档数据的成员函数 最后再至少重载专门负责文件读写操作的Serialize 函数 60 在使用MFC创建新的应用程序框架时 AppWizard准备好了文档类的空壳 下面是应用程序Li2 1中文档类的定义的部分代码 Li2 1Doc h interfaceoftheCLi2 1DocclassclassCLi2 1Doc publicCDocument 派生出一个属于自己的文档类 protected CLi2 1Doc DECLARE DYNCREATE CLi2 1Doc public virtualBOOLOnNewDocument virtualvoidSerialize CArchive 61 2 视图 View 在文档 视图结构中 视图的作用是显示和编辑文档数据 提供用户与文档数据的交互接口 视图在MFC的CView类里被实例化 在开发应用程序时 应该从CView类派生出一个属于自己的视图类 并且在类中至少改写专门负责显示数据的OnDraw 函数或OnPrint 函数 62 classCLi2 1View publicCView 派生出一个属于自己的视图类 protected createfromserializationonlyCLi2 1View DECLARE DYNCREATE CLi2 1View public CLi2 1Doc GetDocument 得到与之相关联的文档对象的指针public virtualvoidOnDraw CDC pDC 负责显示数据的OnDraw 函数virtualBOOLPreCreateWindow CREATESTRUCT 63 CView类和它的9个派生类封装了视图的各种不同的功能 它们为用户实现最新的Windows特性提供了很大的便利 这些派生视图类也可以作为用户程序中视图类的基类 而将这些视图类设置为基类的最基本的方法是在MFCAPPWizard创建SDI MDI的第6步中进行基类的选择 这些视图类如下表所示 64 65 Frame窗口负责文档与视图的界面管理 当Frame窗口关闭时 在其中的视图也被自动删除 下图说明了文档 视图 框架窗口之间的关系 3 框架 Frame 窗口 一个视图只能拥有一个文档 但一个文档可以同时拥有多个视图 66 4 文档模板 DocumentTemplate 文档模板定义了文档 视图和框架窗口这3个类的关系 MFC提供了一个文档模板类CDocTemplate支持文档模板 文档模板类是一个抽象的基类 它定义了文档模板的基本处理函数接口 由于它是一个抽象基类 因此不能直接用它来定义对象而必需用它的派生类 对一个单文档界面程序 使用CSingleDocTemplate类 而对于一个多文档界面程序 使用CMultipleDocTemplate类 67 5 文档 视图结构的产生 一般在应用程序的初始化函数InitInstance 中创建一个和多个文档模板 68 BOOLCLi2 1App InitInstance CSingleDocTemplate pDocTemplate pDocTemplate newCSingleDocTemplate IDR MAINFRAME RUNTIME CLASS CLi2 1Doc RUNTIME CLASS CMainFrame RUNTIME CLASS CLi2 1View AddDocTemplate pDocTemplate 69 文档 视图结构的创建过程如下图所示 70 7 1 2文档与视图之间的相互作用 文档与视图的交互是通过类的公有成员变量和成员函数实现的 1 视图类CView的成员函数GetDocument 一个视图对象只有一个与之相关联的文档对象 在MFC应用程序中 视图对象通过调用成员函数GetDocument 得到与之相关联的文档对象的指针 利用这个指针就可以访问文档类及其派生类的公有数据成员和成员函数 71 2 CDocument类的成员函数UpdateAllViews 一个文档对象可以有多个与之相关联的视图对象 但一个文档对象只反映当前视图的变化 当一个文档数据通过某个视图被修改后 与它关联的每一个视图都必须反映出这种修改 因此 视图在需要时必须进行重绘 即当文档数据发生改变时 必须通知所有相关联的视图对象 以便更新所显示的数据 更新与该文档有关的所有视图的方法是调用成员函数CDocument UpdateAllViews 72 3 视图类的成员函数OnUpdate 当应用程序调用CDocument UpdateAllViews 函数时 实际上是调用了所有相关视图的OnUpdate 函数 以更新相关的视图 需要时 可以直接在视图派生类的成员函数中调用该函数刷新当前视图 另外 在初始化视图成员函数CView OnInitialUpdate 中也调用了OnUpdate 函数 刷新视图时默认的函数调用过程是 Cdocument UpdateAllViews CView OnUpdate CWnd Invalidate OnPaint OnDraw 73 4 CView类的OnInitialUpdate 函数 当应用程序被启动 或用户从 文件 菜单中选择了 新建 或 打开 命令时 CView的OnInitialUpdate 函数会被调用 该函数是虚函数 还可以利用派生类的OnInitialUpdate 函数对视图对象进行初始化 当应用程序启动后 应用程序框架在调用了OnCreate 函数后 如果对OnCreate 函数进行了映射 会立即调用OnInitialUpdate 函数 OnCreate 函数只能被调用一次 而OnInitialUpdate 函数则可以被调用多次 74 7 1 3使用文档 视图结构的意义 75 文档 视图结构带来的好处主要有 首先是将数据操作和数据显示 用户界面分离开MFC在文档 视图结构上提供了许多标准操作界面 包括新建文件 打开文件 保存文件 打印等 减轻了用户的工作量支持打印预览和电子邮件发送功能 76 7 2简单的文档 视图结构应用程序 一般的 类的数据成员的初始化都是在构造函数中完成的 在构造函数调用结束时对象才真正存在 但对于文档来说却不同 文档类的数据成员初始化工作是在OnNewDocument 成员函数中完成的 7 2 1文档中数据的初始化 77 7 2 2文档中数据的清理 同文档的初始化类似 文档的清理也不是在文档的析构函数中完成 而是在文档的DeleteContents 成员函数中完成的 78 7 2 3简单的文档 视图结构应用程序 例7 1 编写一个单文档的应用程序Mydraw 程序运行后 当用户在客户区窗口按下鼠标左键时 以鼠标所在位置为圆心绘圆 79 编译 链接并运行程序 在视图窗口中单击鼠标左键 就可以鼠标所在位置为圆心绘圆 绘制的图形符合题目要求 但当改变窗口大小或将窗口最小化后再重新打开 原来的圆没有显示出来 其原因是此时调用的是视图类的刷新函数OnDraw 而在该函数中并没有实现绘圆功能 80 为了避免上述情况的发生 必须在OnDraw 函数中重绘以前单击鼠标所绘制的圆 因此需要将鼠标单击时的坐标数据保存起来 下面的例7 2在文档类中定义一个大小为100的points数组来保存圆心坐标数据 81 例7 2 完善例7 1应用程序Mydraw 在重绘窗口时能够显示已绘制的圆 82 7 2 4集合类的使用 通常使用简单的数组或链表来存储集合数据 MFC提供了相应的集合类 来实现数组 列表和映象操作 数组类类似于标准的C数组 允许使用下标访问和操作数组元素 MFC数组类还可在需要时 动态地缩减和增加数组所需的内存空间 列表类就是一个有序元素列表 提供用于在任意地方插入和删除节点 向前 向后遍历元素的功能 映象类是使用关键字进行访问的对象的集合 类似于字典的组织方式 通过使用哈希 hashing 技术来使映象值与关键字配对 能实现对项目的快速访问 83 MFC提供了两种集合类 基于模板的集合类由这些集合类可以创建任何类型的数组 列表和映象 为了使用这些类 必须在程序中包含头文件 afxteml h 非模板集合类MFC提供了许多预定义的类 分别用来实现特定类型的数组 列表和映象 84 各个模板集合类的使用方法与对应的数组类 链表类 映射类的使用方法相同 只需在定义具体的数组类对象或链表类对象 映射类对象时给模板实例化 指定一个具体的类即可 例如下面的语句定义了一个CPtrArray类对象 CStringArraym strText而下面的语句定义了一个CTypedPtrArray类对象 CTypedPtrArraym CircleArray 85 例7 3 编写一个单文档的应用程序Mycircle 利用数组类实现例7 2的功能 86 7 3文档的读写 MFC中提供了一种读写文件的简单方法 序列化 即Serialize 该函数为虚函数 序列化机制通过更高层次的接口功能向开发者提供了更利于使用和透明于字节流的文件操纵方法 序列化也叫串行化 87 7 3 1MFC文档读写机制 1 创建文档 2 打开文档 88 3 保存文档 89 4 关闭文档 当用户试图关闭文档 或退出应用程序 时 应用程序会根据用户对文档的修改与否来进一步完成下列任务 1 若文档内容已被修改 则弹出一个消息对话框 询问用户是否需要将文档保存 若用户选择 是 则应用程序执行OnFileSave 过程 2 调用CDocument OnCloseDocument 虚函数 关闭所有与该文档相关联的文档窗口及相应的视图 调用文档类CDocument的DeleteContents 清除文档数据 90 序列化的基本思想是 一个类应该能够对自己的成员变量的数据进行读写操作 对象可以通过读操作而重新创建 即对象可以将其当前状态 由其成员变量的值表示 写入永久性存储体 通常是指磁盘 中 以后可以从永久性存储体中读取 载入 对象的状态 从而重建对象 类的对象自己应该具备将状态值写入磁盘或从磁盘中读出的方法 即成员函数 这种对象的保存和恢复的过程称为序列化 7 3 2MFC文档序列化 91 MFCAppWizard向导生成的Seralize 函数由一个if else结构组成 例如应用程序Li7 1中有如下代码 voidCLi7 1Doc Serialize CArchive ar if ar IsStoring 写数据 TODO addstoringcodehere else 读数据 TODO addloadingcodehere 92 例7 4 继续完善例7 2的应用程序Mydraw 以便能将绘制好的图形保存在磁盘上 93 7 3 3自定义可序列化的类 要让用户定义的类支持序列化 必须满足以下5个条件 1 从CObject类派生 这样派生类就具有RTTI Run timetypeinformation DynamicCreation等功能 2 类的声明部分必须有DECLARE SERIAL宏 此宏需要1个参数 类名称 3 类的实现部分必须有IMPLEMENT SERIAL宏 此宏需要3个参数 一是类名称 二是基类名称 三是版本号 94 4 重新定义Serialize 虚函数 使它能够适当地把类的成员变量写入文件中 5 为此类加上一个默认构造函数 这是因为如果一个对象来自文件 MFC必须先动态地创建它 而且在没有任何参数的情况下调用构造函数 然后才从文件中读取对象数据 95 例7 5 完善例7 3的应用程序Mycircle 利用序列化来保存文件 并使自定义类支持序列化 96 7 4分割视图窗口 分割窗口分为两类 动态分割窗口和静态分割窗口 动态分割窗口是指 用户可以动态的分割和除去分割窗口 分割窗口会创建和删除相应的窗格 静态分割窗口是指 在窗口创建时 分割窗口的窗格就已经创建好了 且窗格的数量和顺序不会改变 窗格为一个分割条所分割 用户可以拖动分割条调整相应的窗格的大小 97 7 4 1CSplitterWnd类 类CSplitterWnd是MFC类库中实现分割窗口的基类 根据需要可以从该类派生自己的分割窗口类 分割窗口是含有多个窗格的窗口 每个窗格通常是应用程序特定的由CView派生类的对象 也可以是具有适当子窗口ID的任何CWnd对象 类CSplitterWnd是类CWnd的派生类 98 7 4 2分割视图窗口的实现技术 1 动态分割窗口动态分割窗口是调用create 成员函数创建的 通常用于创建和滚动同一文档的多个窗格或视图 此处窗格或视图属于同一个类的窗格或视图 99 例7 6 创建一个一行两列窗格的动态分割窗口的单文档应用程序Li7 6 100 2 静态分割窗口静态分割窗口是调用CreateStatic 成员函数创建的 通常用于创建同一文档的多个不同窗格或视图 而这里的多个窗格或视图往往是属于不同类 这些窗格在我们创建分割器时就必须各个创建 通常使用CreateView 函数创建窗格 101 例7 7 创建一个一行两列窗格的静态分割窗口的单文档应用程序Li7 7 其中左窗格是一个CFormView格式视用于选择画线 矩形 圆 右窗格是一个CView视响应这些选择用于画线 矩形 圆 如图7 10所示 102 7 5多文档的应用程序 7 5 1多文档应用程序的界面 103 7 5 2多视图的应用程序 文档与视图分离使得一个文档对象可以和多个视图相关联 这样可以更容易实现多视图的应用程序 如Excel制表程序能够对表格数据采用多种视图来显示 可以是网络状表格 也可以是条形表格 同一份文档数据可以用文字表示 也可以用图形表示 只要具备MDI性质 MFC应用程序就具备了 多视图 功能 虽然说静态分割窗口的窗口可视为完全独立的View窗口 但它们毕竟不是 它们还框在一个大窗口中 事实上 MDI不仅可以在同一时间内同时打开多个文档 还可以为同一文档打开多个视图 在Windows菜单下选择New 就为当前活动文档打开一个新的子窗口 104 例7 9 编写一个MDI应用程序Li7 9 当执行 窗口 斜体窗口 菜单命令时重新打开一个窗口 并以斜体方式显示一个文档的内容 105 7 5 3多类型的应用程序 事实上 多文档应用程序除了支持单一文件类型外 还可以支持多种文件类型 即一个应用程序可以处理多种文件格式 106 例7 10 建立一个多类型文档的应用程序Li7 10 该应用程序能显示两种类型的窗口 一种输出文本 在另一种窗口中 可以输出图形 同时根据不同的文件类型 显示不同的菜单 107 7 6应用实例 编写一个简单的文本编辑器 以此说明文档 视图结构的原理及应用 在该编辑器中 用户只能完成字符的逐行输入 通过回车键换行 为文本选择字体及颜色等简单功能 108 第8章打印编程8 1基本打印功能8 2设置打印坐标系8 3多页打印8 4高级打印 VisualC 程序设计与应用教程 109 8 1基本打印功能 在使用应用程序向导 AppWizard 生成应用程序的过程中 如果在第四步不取消对打印和打印预览的设置 那么应用程序就已经具备了简单的打印和打印预览功能 110 8 1 1打印原理 在文档 视图结构应用程序 CDocument类负责数据的生成和储存 CView类负责数据的显示和用户交互 输出到屏幕和输出到打印机都是数据的显示 实质上是一样的 因此打印功能也是由CView类来实现的 111 112 默认的函数Cview OnPrint 中只是调用成员函数OnDraw 而没有进行其他操作 在以前的程序中 并不考虑打印问题 因此我们只需考虑在OnDraw 中如何完成屏幕输出工作 但现在在OnDraw 中添加代码时 就必须小心这有可能是在进行打印 并不仅向一个窗口输出 如果这两个函数在程序中不能统一 就必须分开考虑 分开考虑时有两种方法 1 分别在OnPaint 和OnPrint 这两个函数中完成屏幕输出和打印输出工作 而不必依赖于OnDraw 函数 2 在OnDraw 函数中 调用pDC IsPrinting 或设置变量来识别目前进行的输出工作并区别对待 113 例8 1 编写一个单文档应用程序MyPrint 实现简单的打印功能 114 应用程序的 File 菜单条中自动添加 打印 打印预览 和 打印设置 3个菜单项 应用程序基本打印功能的实现主要是由消息映射宏和消息处理函数完成的 115 1 在应用程序视图类CMyPrintView的消息映射宏中包含了以下打印和打印预览命令的消息映射代码 BEGIN MESSAGE MAP CMyPrintView CScrollView StandardprintingcommandsON COMMAND ID FILE PRINT CScrollView OnFilePrint ON COMMAND ID FILE PRINT DIRECT CScrollView OnFilePrint ON COMMAND ID FILE PRINT PREVIEW CScrollView OnFilePrintPreview END MESSAGE MAP 116 2 在CMyPrintApp类的消息映射宏中包含了打印设置的以下消息映射代码 BEGIN MESSAGE MAP CMyPrintApp CWinApp StandardfilebaseddocumentcommandsON COMMAND ID FILE NEW CWinApp OnFileNew ON COMMAND ID FILE OPEN CWinApp OnFileOpen StandardprintsetupcommandON COMMAND ID FILE PRINT SETUP CWinApp OnFilePrintSetup END MESSAGE MAP 117 3 在CMyPrintView cpp文件中由系统自动生成了以下3个函数 BOOLCMyPrintView OnPreparePrinting CPrintInfo pInfo defaultpreparationreturnDoPreparePrinting pInfo voidCMyPrintView OnBeginPrinting CDC pDC CPrintInfo pInfo TODO addextrainitializationbeforeprinting voidCMyPrintView OnEndPrinting CDC pDC CPrintInfo pInfo TODO addcleanupafterprinting 118 8 1 2CPrintInfo类 CPrintInfo类保存了打印和打印预览的相关信息 当用户单击 File 菜单的 打印 或 打印预览 命令时 系统自动创建一个CPrintInfo类对象 用于保存用户打印设置的信息 当打印操作结束时 系统自动删除CPrintInfo类对象 在打印过程中 CPrintInfo类在框架窗口和CView类之间起着消息传递的作用 119 8 1 3打印过程 一个打印作业由以下几步构成 1 如果执行打印预览命令 框架窗口将调用CView OnPreparePrinting 函数 创建与当前默认打印机相关的设备描述对象 对CPrintInfo类中的一些成员变量赋值或调用类成员函数来控制打印的方式 调用DoPreparePrinting 函数 如果执行打印命令 DoPreparePrinting 函数将显示打印对话框 在对话框中 用户可以设置打印范围 选择打印机 打印份数 120 2 调用CView OnBeginPrinting 函数分配打印过程所需要的系统资源 3 调用CDC StartDoc 启动主打印循环 4 打印新页时 框架窗口首先调用CView OnPrepareDC 在打印之前根据当前打印机的设备描述表进行调整 如果事先不知道需要打印多少页 则被重载的OnPrepareDC 函数可以检测文档的结束 如果文档结束 将CPrintInfo m bContinuePrinting值设置为FALSE 跳到 6 否则 设置CPrintInfo m bContinuePrinting的值为TRUE 继续进行打印 121 5 调用CDC StartPage CView OnPrint 和CDC EndPage 进行打印 在默认情况下 OnPrint 函数首先调用OnPrepareDC 函数对坐标进行变换 然后调用OnDraw 函数往打印机里输出数据 6 当m bContinuePrinting为FALSE时 打印结束 调用CDC EndDoc 函数释放在打印过程中占用的各种资源 7 调用OnEndPrinting 函数 结束打印 122 123 8 1 4打印预览 打印预览命令的执行可以分成以下几个步骤 主框架窗口执行OnFilePreparePrint 函数 在OnFilePreparePrint 函数中 执行OnPreparePrinting CPrintlnfo pInfo 函数 检测m bPreview变量是否为TRUE 如果是 则对CPrintInfo类中的一些成员变量赋值或调用类成员函数来控制打印预览的方式 调用CView DoPreparePrinting 函数 显示打印预览界面 调用OnDraw 函数按照打印机的设备描述表往屏幕输出数据 利用屏幕来模拟显示打印结果 124 8 2设置打印坐标系 8 2 1Windows映射模式 Windows映射模式就是Windows下的坐标方式 在Windows操作系统中 存在两种类型的坐标 设备坐标和逻辑坐标 当向设备输出图形时 Windows先映射当前逻辑坐标到物理坐标 例如打印机 然后显示图形输出 125 126 8 2 2映射模式的设置 在MFC应用程序中 通过调用CDC类的SetMapMode 函数设置映射方式 如在视图类的OnDraw 函数中 可以通过以下代码设置映射方式 pDC SetMapMode n 其中 n为上表中列出的映射方式 127 例8 2 完善例8 1中的程序MyPrint 使打印输出的图形与显示器显示的图形大小基本一样 128 8 3多页打印 8 3 1默认打印存在的不足 例8 3 完善例8 2中的程序MyPrint 程序运行后 屏幕上能显示50个矩形 129 8 3 2实现多页打印功能 如果要使程序支持多页打印功能 首先在打印之前设置要打印的页数 然后设置每一页视图原点的打印坐标 1 设置要打印的页数一般在OnBeginPrinting 函数中设置要打印的页数 通过CPrintInfo类的SetMaxPage 和SetMinPage 函数实现 130 例8 4 完善例8 3中的程序MyPrint 设置要打印的页数 131 2 设置正确的视图原点 为了正确打印每一页 需要设置每页打印的内容对应于坐标的那一部分区域 第一页视图原点的打印坐标为0 第二页视图原点的打印坐标下移一个页的高度 依此类推 可以在OnPrepareDC 函数中通过调用CDC类成员函数SetViewPortOrg 设置当前页的视图原点坐标 由于这些设置在OnPrint 和OnDraw 都起作用 既影响打印又影响显示器显示 因此必须调用CDC类的成员函数IsPrinting 来判断当前状态是打印输出还是显示器显示 132 例8 5 完善例8 4中的程序MyPrint 设置正确的视图原点 133 8 4高级打印 8 4 1页眉和页脚 完整的打印和打印预览程序包括控制页边距 设计页眉 页脚 多页打印以及预览等功能 页眉和页脚可以醒目地向用户提示一些重要的信息 如文章标题 页码等 134 添加打印页眉 页脚的程序代码可以分两步进行 1 页眉和页脚将在打印纸上占用一定的空间 如果打印区域太大 有可能和正文打印区域相重叠 被正文所覆盖 因此 应在OnPrint 函数中利用CPrintInfo pInfo的成员变量m rectDraw来设置打印页上打印区域的大小 2 在m rectDraw范围之外打印页眉和页脚 135 8 4 2设置页边距 页边距是指打印的文本区域与打印纸边界之间的距离 包括左 右 上和下边距 设置页边距时可参考CPrintInfo的成员变量m rectDraw的数值 但m rectDraw的数值表示的是有效打印区域 它本身与打印纸边界有一定的边距 这个边距是打印机自身造成的 称之为物理边距 并且这些物理边距在不同大小的纸张中是不一样的 因此首先要调用全局函数GetDeviceCaps获取这些数值 136 例8 6 编写一个多文档的应用程序MyPage 设置页眉和页脚 在页眉处输出标题 在页脚处输出页码 137 第9章动态链接库9 1概述9 2创建MFCDLL9 3使用MFCDLL9 4MFC扩展DLL VisualC 程序设计与应用教程 138 在多任务环境中 为了提高系统资源的利用率和系统的整体性能 应该使每一个应用程序尽量少占用系统内存等资源 动态链接库便是这一设想的体现 允许多个应用程序同时共享动态链接库在内存中的同一份拷贝 9 1概述 139 9 1 1动态链接库的概念 动态链接库 DLL 是一种用来为其它可执行文件 包括EXE文件和其它DLL 提供共享的函数库 DLL中一般定义有两种类型的函数 导出函数和内部函数 导出函数是可以被外部程序调用的函数 内部函数只能在DLL内部使用 140 9 1 2动态链接库和静态链接库的区别 动态链接库和静态链接库的主要区别是与应用程序的链接方式不同 前者进行的是动态链接 后者进行的是静态链接 141 9 1 3使用动态链接库的优点 1 实现多个应用程序共享数据和代码的方式 2 提高应用程序的执行效率和运行速度 3 方便应用程序的升级和售后支持 4 把应用程序所使用的资源 如图标 位图 字符串和对话框等 独立出来做成DLL 为多个应用程序所共享 5 动态链接库便于建立多语言的应用程序 142 9 1 4DLL文件的存放位置 程序所需的DLL文件必须位于下面4个目录之一中 1 当前目录 2 Windows的系统的目录 如Windows system 3 Windows所在的目录 如WINNT 4 环境变量PATH中所指定的目录 143 VisualC 6 0支持多种DLL 包括 非MFCDLL一般来说 非MFCDLL的内部不使用MFC 非MFCDLL的导出函数都使用标准的C接口 因此无论应用程序是否使用了MFC 都可以调用非MFCDLL 9 1 5动态链接库的分类 144 MFC常规DLLMFC常规DLL实际上包含有两方面的含义 一方面它是 MFC的 这意味着可以在这种DLL的内部使用MFC 另一方面它是 常规的 这意味着它不同于MFC扩展DLL 在MFC规则DLL的内部虽然可以使用MFC 但是它与应用程序的接口不能是MFC 而是C函数或者C 类 因此MFC的常规DLL可以被非MFC或MFC编写的应用程序所调用 145 MFC扩展DLLMFC扩展DLL一般用来提供派生于MFC的可重用的类 以扩展已有的MFC类库的功能 MFC扩展DLL使用MFC的动态链接版本 只有使用MFC生成的可执行程序 无论是EXE还是DLL 才能访问MFC扩展DLL 146 利用MFCAppWizard dll 向导可以创建MFCDLL DLL文件与可执行文件非常相似 不同点在于DLL包含有导出表 导出表包含DLL中每个导出函数的名字 这些函数是进入DLL的入口点 只有导出表中的函数可以被外部程序调用 从MFCDLL中导出函数常用以下两种方法 使用模块定义文件 DEF 和使用关键字 declspec dllexport 9 2创建MFCDLL 147 9 2 1使用 DEF文件 DEF文件是一个包含EXE文件或DLL文件声明的文本文件 每个 DEF文件至少必须包含LIBRARY语句和EXPORTS语句 其他语句可以省 DEF文件常用的模块语句如下 第一个语句必须是LIBRARY语句 这个语句指出DLL的名字 链接器将这个名字放到DLL导入库中 DLL导入库包含了指向外部DLL的函数索引指针 148 EXPORTS语句列出被导出函数的名字 以及导出函数的数值 由 号与数字构成 序数值可以省略 编译器会为每个导出函数指定一个 但这样指定的值不如自己指定的明确 使用DESCRIPTION语句描述DLL的用途 这个语句可以省略 使用 开头的注释语句 使用AppWizard创
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 带式球团焙烧工工艺创新考核试卷及答案
- 经编机操作工岗位操作技能考核试卷及答案
- 重冶备料破碎工三级安全教育(车间级)考核试卷及答案
- 工业废气治理工三级安全教育(公司级)考核试卷及答案
- 2025年服务器配件行业研究报告及未来行业发展趋势预测
- 2025年半导体硅行业研究报告及未来行业发展趋势预测
- 味精提取工作业指导书
- 旅行社计调作业指导书
- 项目八进口贸易合同执行与税收优惠政策协议
- 儿童成长保障协议离婚后轮流抚养合同
- 外墙防水渗漏红外检测技术
- 监控系统维护方案
- 二手电车买卖合同范本
- 中介拍卖合同协议书范本
- 2025年云南红河州开发区投资建设集团有限公司招聘笔试参考题库含答案解析
- 法医物证课件法医植物学
- 第37届中国化学奥林匹克(初赛)试题及答案
- JJF 2223-2025氡子体测量仪校准规范
- 吧员礼仪礼节培训
- 2025-2030中国云游戏行业市场发展分析及前景趋势与投资研究报告
- 湖北省武汉市武昌区2024-2025学年八年级上学期期末考试数学试卷(原卷版+解析版)
评论
0/150
提交评论