MFC程序设计谷风详析

上传人:夏** 文档编号:569506996 上传时间:2024-07-30 格式:PPT 页数:153 大小:3.01MB
返回 下载 相关 举报
MFC程序设计谷风详析_第1页
第1页 / 共153页
MFC程序设计谷风详析_第2页
第2页 / 共153页
MFC程序设计谷风详析_第3页
第3页 / 共153页
MFC程序设计谷风详析_第4页
第4页 / 共153页
MFC程序设计谷风详析_第5页
第5页 / 共153页
点击查看更多>>
资源描述

《MFC程序设计谷风详析》由会员分享,可在线阅读,更多相关《MFC程序设计谷风详析(153页珍藏版)》请在金锄头文库上搜索。

1、第三章第三章 MFCMFC程序设计程序设计本本章章的的内内容容,简简洁洁而而不不失失完完整整性性:由由应应用用程程序序向向导导建建立立程程序序框框架架,由由资资源源编编辑辑器器建建立立用用户户界界面面,由由类类向向导导建建立立成成员员变变量量、消消息息映映射射和和处处理理函函数数,加加上文档序列化和注册上文档序列化和注册 MFC包包含含了了所所有有与与系系统统相相关关的的类类(包包括括图图形形用用户户界界面面相相关关的的类类),其其中中封封装装了了大大多多数数的的API函函数数,提提供供了了应应用用程程序序框框架架和和开开发发应应用用程程序序的的工工具具如如应应用用程程序序向向导导、类类向向导

2、导、可可视视化化资资源源设设计计等等高高效效工工具具,用用消消息息映映射射处处理理消消息息响响应应,大大大大简简化化了了Windows应应用用程程序序的的开开发发工工作作,使使程程序序员员可可以以从从繁繁重的编程工作中解脱,提高工作效率。重的编程工作中解脱,提高工作效率。1特制分析3.1.3.1.MFCMFC程序设计简介程序设计简介3.2.3.2.MFC MFC 程序设计程序设计3.3.3.3.用户界面资源的应用用户界面资源的应用3.4.3.4.对话框的应用对话框的应用3.5.3.5.基于对话框的应用程序设计实例基于对话框的应用程序设计实例3.6.3.6.文本和图形输出文本和图形输出3.7.3

3、.7.文档的保存文档的保存3.8.3.8. MDI MDI应用程序设计应用程序设计目录目录2特制分析3.1MFC程序设计简介程序设计简介 MFC类库类库 基础类基础类 (已在第二章中介绍)(已在第二章中介绍) 宏、全局变量及全局函数宏、全局变量及全局函数应用程序框架应用程序框架3.1.1MFC定义的宏、全局函数及全局变量定义的宏、全局函数及全局变量类库类库1. MFC1. MFC提供的主要宏:提供的主要宏:消息映射宏:声明消息映射表宏声明消息映射表宏DECLARE_MESSAGE_MAPDECLARE_MESSAGE_MAP、消、消息映射定义宏息映射定义宏BEGIN_MESSAGE_MAPBE

4、GIN_MESSAGE_MAP和和END_MESSAGE_MAPEND_MESSAGE_MAP消息映射消息映射表入口宏表入口宏ON_ON_消息名。消息名。( (本章只介绍消息映射宏本章只介绍消息映射宏) )3特制分析3.1.1MFC定义的宏、全局函数及全局变量定义的宏、全局函数及全局变量 动态动态MFCMFC对象宏对象宏 DECLARE_DYNAMIC和和IMPLEMENT_DYNAMIC动态创建对象宏动态创建对象宏 DECLARE_DYNCREATE和和IMPLEMENT_DYNCREATE运行时类宏:运行时类宏:RUNTIME_CLASS序列化宏:序列化宏:DECLARE_SERIAL和和

5、IMPLEMENT_SERIAL诊断服务宏:诊断服务宏: ASSERT、VERIFY跟踪服务宏:跟踪服务宏: TRACE异常处理宏:异常处理宏: THROW4特制分析3.1.1MFC定义的宏、全局函数及全局变量定义的宏、全局函数及全局变量MFCMFC提供一些不属于任何类的全局函数,函数名以提供一些不属于任何类的全局函数,函数名以AfxAfx开开头,可以被应用程序中的所有类和函数所调用。如:头,可以被应用程序中的所有类和函数所调用。如:AfxAbortAfxAbort()(),无条件终止一个应用程序的执行;,无条件终止一个应用程序的执行;AfxGetAppName()AfxGetAppName(

6、),返回指向应用程序名的字符串指针;,返回指向应用程序名的字符串指针;AfxWinInit()AfxWinInit(), ,由由WinMainWinMain()()调用,对调用,对MFCMFC应用程序进行图形用户界面应用程序进行图形用户界面(GUI)(GUI)的初始的初始化等等。化等等。3. 3. 全局变量全局变量 全局变量名以afx开头,如afxTraceFlag、afxDumpafxDump等,主要与异常处理有关。2. 2. 全局函数全局函数5特制分析3.1.2MFC命名规则命名规则 匈牙利命名法规定匈牙利命名法规定: : 变量名以一个或多个小写字母开头作为变量名以一个或多个小写字母开头作

7、为前缀,标识变量的数据类型;前缀,标识变量的数据类型; 类型标识后是若干个单词,标识变量含义,类型标识后是若干个单词,标识变量含义,每个单词以大写字母开头,其余字母小写;每个单词以大写字母开头,其余字母小写; MFCMFC中所有类及自定义类都以中所有类及自定义类都以C C开头;开头; 类成员变量以类成员变量以m_m_为前缀,下划线后是变为前缀,下划线后是变量名等等。量名等等。6特制分析前缀数据类型例B,bBOOLbIsValidChcharChText,ChGradecclasscStringCsCStringCsNameDwDWORDDwFlagsfnfunctionfnSorthandle

8、hWnd,hPeniintiCountppointerpFrameszASCII stringszNamem_Data memberm_szName表3.1 命名规则h7特制分析 MFCMFC提供了构造提供了构造WindowsWindows应用程序的框架,它不应用程序的框架,它不仅为应用程序建立标准的结构,生成一系列起动文仅为应用程序建立标准的结构,生成一系列起动文件,还提供标准的图形用户界面如菜单、工具栏、件,还提供标准的图形用户界面如菜单、工具栏、状态条等供开发人员在程序中补充完善,开发人员状态条等供开发人员在程序中补充完善,开发人员只需要完成针对特定应用的代码。使用应用程序框只需要完成针

9、对特定应用的代码。使用应用程序框架的应用程序代码小,运行速度快,它提供的工具架的应用程序代码小,运行速度快,它提供的工具也降低了编码的难度。也降低了编码的难度。3.1.3 应用程序框架介绍应用程序框架介绍 8特制分析程序的数据储存在文档类中(作为文档类的数据成员),是程序的数据储存在文档类中(作为文档类的数据成员),是对数据的抽象表示。数据显示由视图负责,视图是程序窗对数据的抽象表示。数据显示由视图负责,视图是程序窗口的客户区,框架窗口是客户区的框架,程序数据显示在口的客户区,框架窗口是客户区的框架,程序数据显示在窗口,用户通过视图与程序交互。窗口,用户通过视图与程序交互。一个文档可以对应多个

10、不同视图;而一个视图一般只对应一一个文档可以对应多个不同视图;而一个视图一般只对应一个文档。当文档数据发生变化时,视图显示的状态也会随个文档。当文档数据发生变化时,视图显示的状态也会随之变化;对于多个视图的情况,基于同一文档的多个视图之变化;对于多个视图的情况,基于同一文档的多个视图的显示同步变化。的显示同步变化。 1.文档文档-视图结构视图结构 文档视图结构提供一种连续处理数据的方式,使文档视图结构提供一种连续处理数据的方式,使应用程序的数据与数据的显示分开处理。应用程序的数据与数据的显示分开处理。9特制分析文档、视图及框架的关系:文档、视图及框架的关系:框架窗口对象框架窗口对象文档与视图之

11、间文档与视图之间的双向数据交换的双向数据交换发送至视图发送至视图对象的消息对象的消息文档对象文档对象(保存程序保存程序数据数据)应用程应用程序对象序对象视图对象发送至框架发送至框架窗口的消息窗口的消息图图3.110特制分析2.单文档界面应用单文档界面应用 单文档界面应用程序简称单文档界面应用程序简称SDI(Single Document SDI(Single Document Interface)Interface),只允许一个框架窗口存在,每次,只允许一个框架窗口存在,每次只能创建和拥有一个文档对象,也只允许打开只能创建和拥有一个文档对象,也只允许打开一个文档。一个文档。SDISDI各类各类

12、 关系图关系图可将文档比作一个文件袋,专门用于保存文件可将文档比作一个文件袋,专门用于保存文件数据,需要看时需从文件袋数据,需要看时需从文件袋(文档文档)中取出来,中取出来,放到桌面放到桌面(视图视图)上看。上看。11特制分析表表3.2 3.2 基于文档基于文档/ /视图关系的视图关系的SDISDI应用中的类应用中的类DocumentDocument文档类文档类储存与应用程序相关的数据储存与应用程序相关的数据View View 视图类视图类决定文档数据的显示方式,提供用户界面决定文档数据的显示方式,提供用户界面Frame windowFrame window框架窗口框架窗口派生自派生自CFra

13、meWndCFrameWnd,为为CWinAppCWinApp类的类的m_pMainWnd成员赋值成员赋值Document Document templatetemplate文文档模板档模板CSingelDocTemplateCSingelDocTemplate类对象,用构造函数类对象,用构造函数将文档、视图、框架窗口及用户界面资将文档、视图、框架窗口及用户界面资源联系在一起,创建并管理文档源联系在一起,创建并管理文档ApplicationApplication应用程序类应用程序类代表应用程序,代表应用程序,拥有指向文档管理类的指拥有指向文档管理类的指针,管理应用程序中所有文档模板,针,管理应

14、用程序中所有文档模板,负负责初始化和退出清理工作责初始化和退出清理工作返回返回12特制分析应用程序类应用程序类框架类框架类( 窗口框架窗口框架)资源资源(决定用户决定用户界面的显示界面的显示)视图类视图类(显示数据并显示数据并与用户交互与用户交互)文档类文档类(保存数据保存数据)单文档模板单文档模板返回返回13特制分析应用程序类应用程序类CDocManager* m_pDocManager框架类框架类( 窗口框架窗口框架)资源资源(决定用户决定用户界面的显示界面的显示)m_pDocument视图类视图类(显示数据显示数据并与用户交互并与用户交互)文档类文档类(保存数据保存数据)m_pDocTe

15、mplatem_viewList返回返回单文档模板单文档模板CRuntimeClass*m_pDocClassCRuntimeClass*m_pFrameClassCRuntimeClass*m_pViewClassUINT m_nIDResource14特制分析多文档界面应用简称多文档界面应用简称MDI(Multiple Document MDI(Multiple Document Interface)Interface),允许有多个文档类、视图类和多个文,允许有多个文档类、视图类和多个文档模板档模板CMultiDocTemplate(CMultiDocTemplate(建立多种文档建立多种

16、文档- -视图视图- -子子框架关系框架关系) )存在,运行时允许打开多个存在,运行时允许打开多个MDIMDI子框架窗子框架窗口,拥有各自的文档和视图对象。口,拥有各自的文档和视图对象。示例示例 关系图关系图在在打打开开的的多多个个子子窗窗口口中中,只只有有一一个个活活动动窗窗口口,应应用用程程序序菜菜单单和和工工具具栏栏的的所所有有的的命命令令都都是是针针对对活活动窗口的。动窗口的。3.3.多文档界面应用多文档界面应用15特制分析子框架子框架 资源资源2视图类视图类2文档类文档类2文档模板文档模板2子框架子框架 资源资源1视图类视图类1文档类文档类1文档模板文档模板1主主框框架架其它文档模板

17、其它文档模板返回返回CDocManager应用程序类应用程序类CDocManager*m_pDocManager16特制分析文档文档/视图结构视图结构可以充分发挥应用程序框架和可以充分发挥应用程序框架和MFCMFC的优势,是的优势,是MFCMFC应用程序的核心,但使用它也要付应用程序的核心,但使用它也要付出运行效率和代码增大的代价。出运行效率和代码增大的代价。 文档文档/视图结构对应用程序来说并不是必不可少视图结构对应用程序来说并不是必不可少的,有两种常见的非文档的,有两种常见的非文档/视图结构应用。视图结构应用。4.非文档非文档/视图结构应用视图结构应用17特制分析常见非文档常见非文档/ /

18、视图结构应用:视图结构应用:(1).(1).基于对话框的应用,它包含一个基于对话框的应用,它包含一个CWinAppCWinApp对对象和一个模态对话框,对话框负责数据的存储象和一个模态对话框,对话框负责数据的存储和显示和显示 。关系图(2).(2).SDISDI或或MDIMDI应用,都可以不包含文档对象,应用,都可以不包含文档对象,SDISDI包含一个包含一个CWinAppCWinApp对象,一个框架窗口对对象,一个框架窗口对象和一个从象和一个从CWndCWnd派生的派生的CChildViewCChildView视图对象,视图对象,视图对象负责数据的显示,视图对象负责数据的显示,MDIMDI应

19、用还包括一应用还包括一个子框架窗口。个子框架窗口。 18特制分析对话框类对话框类作为应用程序主窗口作为应用程序主窗口负责保存和显示数据负责保存和显示数据应用程序类应用程序类返回返回Dialog-based Application19特制分析主框架,应用程序主窗口主框架,应用程序主窗口CChildView视图类视图类负责保存和显示数据负责保存和显示数据应用程序类应用程序类SDI Application, None Doc/View 返回返回20特制分析子框架,子框架,视图框架窗口视图框架窗口CChildView视图类视图类应用程序类应用程序类子框架,子框架,视图框架窗口视图框架窗口CChildV

20、iew视图类视图类主框架,应用程序主框架窗口主框架,应用程序主框架窗口MDI Application, None Doc/View 返回返回21特制分析图图3.2 MFC应用程序开发过程应用程序开发过程 类向导类向导集成开发环境集成开发环境应用程序向导应用程序向导资源编辑器资源编辑器Create.def.cpp.h.dsw.dsp.ico.rc.bmp源文件源文件资源文件资源文件编译编译.objBuild资源编译资源编译.res应用程序应用程序5.MFC应用程序创建应用程序创建 22特制分析6.最简单的最简单的MFC应用程序示例应用程序示例 对于一个对于一个MFCMFC应用程序来说,只有应用程

21、序来说,只有CWinAppCWinApp的派生对的派生对象是必不可少的,其它类均可视情况进行取舍。象是必不可少的,其它类均可视情况进行取舍。下例是一个最简单的下例是一个最简单的MFCMFC应用程序。应用程序。例:显示一个消息框。例:显示一个消息框。 (1).(1).创建工程,工程类型选择创建工程,工程类型选择Win32 ApplicationWin32 Application,工程名,工程名为为Ex3_0Ex3_0; (2).(2).创建创建C+C+源文件,文件名源文件,文件名Ex3_0.cppEx3_0.cpp,内容如下,内容如下: : 23特制分析#include class CEx3_0

22、App: public CWinApp /CWinApp/CWinApp派生类派生类 public: virtual BOOL InitInstance() MessageBox(NULL,”SimplistMFC Application.”, ”Ex3_0”,MB_OK); return TRUE; ; CEx3_0App theApp; /全局变量,代表应用程序本身全局变量,代表应用程序本身 CWinApp:InitInstance()CWinApp:InitInstance()虚函数完成应用程序的初始化工作,派生的虚函数完成应用程序的初始化工作,派生的应用程序类都要重载此函数进行初始化,

23、如完成主框架窗口的构造,应用程序类都要重载此函数进行初始化,如完成主框架窗口的构造,窗口定义显示等工作。窗口定义显示等工作。 24特制分析(3).(3).设置使用设置使用MFCMFC。 选择选择Project|SettingsProject|Settings菜单项,选择菜单项,选择GeneralGeneral页面,在页面,在Microsoft Foundation ClassesMicrosoft Foundation Classes组合框中选择组合框中选择Use MFC in a shared DLLUse MFC in a shared DLL。(4).(4).编译生成并运行此工程,结果显

24、示一个消息框编译生成并运行此工程,结果显示一个消息框, ,如下如下图图: : 图图3.3 3.3 最简单最简单MFCMFC应用示例应用示例25特制分析3.2.MFC 3.2.MFC 程序设计程序设计 MFCMFC应用程序的执行过程应用程序的执行过程( (参见图参见图3.4):):1.1.构造全局对象构造全局对象CWinAppCWinApp派生类对象;派生类对象; 2.2.运行由应用程序框架提供的运行由应用程序框架提供的WinMainWinMain函数;函数; 26特制分析图图3.4 MFC3.4 MFC应用程序的执行过程应用程序的执行过程27特制分析3.在在WinMain中,通过中,通过afx

25、GetApp()获得全局对象的指针获得全局对象的指针pApp,调用全局函数,调用全局函数AfxWinInit() ,为,为CWinApp的成员的成员变量变量m_hInstance, m_hPrevInstance, m_lpCmdLine,m_nCmdShow赋初值;赋初值; 然后调用然后调用pApp-InitApplication() ,这是,这是CWinApp的的虚函数,一般不需要改写;虚函数,一般不需要改写; 调用调用 pApp-InitInstance() ,每个程序都必需改写这,每个程序都必需改写这个函数,进行应用程序初始化;个函数,进行应用程序初始化; 4.在在InitInstan

26、ce()函数中,先用函数中,先用new构造一个构造一个CFrameWnd派生类对象,其构造函数又调用派生类对象,其构造函数又调用Create(),创建主窗口,创建主窗口,MFC依此自动为应用程序注册窗口类;依此自动为应用程序注册窗口类;调用调用ShowWindow()显示窗口,调用显示窗口,调用UpdateWindow(),发出发出WM_PAINT消息;消息;28特制分析5.5.回到回到WinMainWinMain中,调用中,调用pApp-Run,进入消息循环,通过,进入消息循环,通过APIAPI函数函数GetMessage()获得消息,获得消息,TranslateMessage()处理消处理

27、消息,息,DispatchMessage()派送消息到派送消息到CWnd:DefWindowProc() ,DefWindowProc()按照消息按照消息映射表的定义将消息分发到各相应消息处理函数;映射表的定义将消息分发到各相应消息处理函数;如消息队列为空,则如消息队列为空,则RunRun调用调用CWinApp:OnIdle()进行空闲处理进行空闲处理,重载,重载OnIdle()可以去处理后台程序可以去处理后台程序( (低优先级低优先级);); 6.6.若用户选择菜单若用户选择菜单File/CloseFile/Close,则程序收到,则程序收到WM_COLSEWM_COLSE消息,消息,调用调

28、用:DestroyWindow()发出发出WM_DESTROY消息,然后调消息,然后调PostQuitMessage(),发出,发出WM_QUIT消息,此时消息,此时Run会结会结束其内部消息循环,调用束其内部消息循环,调用ExitInstance();7.最后,返回最后,返回WinMain(),执行,执行WinTerm(),结束程序运行。,结束程序运行。 29特制分析几点解释:几点解释:(1).(1).每个每个MFCMFC应用都有应用都有stdafx.hstdafx.h头文件,由应用程序向导自动头文件,由应用程序向导自动生成;生成; (2).(2).每个每个MFCMFC应用都应包含头文件应用

29、都应包含头文件afxwin.hafxwin.h,其内部又包,其内部又包含了其他头文件。含了其他头文件。(3).(3).每一个每一个MFCMFC应用程序都包含唯一的应用程序都包含唯一的CWinAppCWinApp派生类派生类对象对象, ,代表应用程序本身。代表应用程序本身。(4).MFC(4).MFC应用程序中看不到应用程序中看不到WinMain()WinMain()入口函数,它被入口函数,它被封装在应用程序框架里,运行时自动调用;封装在应用程序框架里,运行时自动调用;30特制分析3.2.2.MFC3.2.2.MFC消息映射消息映射 消息映射消息映射(Message Map)(Message M

30、ap)机制机制: :消息映射机制规定每个要响应消息的类定义自消息映射机制规定每个要响应消息的类定义自己的消息映射表,将消息与处理消息的函数己的消息映射表,将消息与处理消息的函数联系在一起;当事件发生产生消息时,在程联系在一起;当事件发生产生消息时,在程序中各个类的消息映射表中查找,当找到消序中各个类的消息映射表中查找,当找到消息处理函数时,便将消息送至对应的消息处息处理函数时,便将消息送至对应的消息处理函数进行处理。每个从理函数进行处理。每个从CCmdTargetCCmdTarget所派生所派生的类都可以接收消息,都可以定义自己的消的类都可以接收消息,都可以定义自己的消息映射表息映射表Mess

31、age MapMessage Map。 31特制分析消息映射表:消息映射表:1.消息消息消息是消息是WindowsWindows用来通知用来通知MFCMFC应用程序事件发生的应用程序事件发生的主要方式,应用程序的行为取决于对消息的响主要方式,应用程序的行为取决于对消息的响应方式。应方式。 MFCMFC把消息分为三大类把消息分为三大类: : (1). (1).标准标准WindowsWindows消息消息(WM_XXX)(WM_XXX), (2).(2).命令消息命令消息(WM_COMMAND), (WM_COMMAND), (3). (3).控件通知消息。控件通知消息。 32特制分析2.消息映射

32、消息映射 消息映射将消息与应用程序提供的处理该消息消息映射将消息与应用程序提供的处理该消息的成员函数联系在一起,一组消息映射构成的成员函数联系在一起,一组消息映射构成消息映射表。消息映射表。消息映射表由消息映射表由BEGIN_MESSAGE_MAPBEGIN_MESSAGE_MAP和和END_MESSAGE_MAPEND_MESSAGE_MAP 这一对宏作开始和结束,这一对宏作开始和结束,中间是若干消息映射入口中间是若干消息映射入口每一个入口由特定的消息宏每一个入口由特定的消息宏ON_XXXON_XXX组成,将一组成,将一个消息与与之对应的处理函数联系在一起。个消息与与之对应的处理函数联系在一

33、起。 33特制分析定义和使用消息映射表的步骤:定义和使用消息映射表的步骤: 在头文件的类声明中添加在头文件的类声明中添加DECLARE_MESSAGE_MAP宏声明消息映射宏声明消息映射;例如例如 在类的定义文件在类的定义文件(.cpp)定义消息映射表,方法是定义消息映射表,方法是在在 文件的开始处添加文件的开始处添加BEIGN_MESSAGE_MAP和和END_MESSAGE_MAP 这一对宏,在它们之间放置这一对宏,在它们之间放置消息映射宏,定义并初始化消息映射表,在消息与处消息映射宏,定义并初始化消息映射表,在消息与处理消息的函数之间建立联系;理消息的函数之间建立联系;例如例如 在类的定

34、义文件在类的定义文件(.cpp)中添加消息处理函数。中添加消息处理函数。例如例如34特制分析消息宏:消息宏:(1).对标准Windows消息的响应 消息宏消息宏ON_WM_XXX定义对标准定义对标准Windows消息消息WM_XXX的响应,所有派生自的响应,所有派生自CWnd的类均可响应这类消息,系统默认的类均可响应这类消息,系统默认的响应函数为的响应函数为OnXxx,对应关系见下面的表,对应关系见下面的表3.3:宏名宏名消息消息默认处理函数默认处理函数ON_WM_CHARWM_CHAROnCharON_WM_ CLOSEWM_ CLOSEOnCloseON_WM_CREATEWM_ CREA

35、TEOnCreateON_WM_LBUTTONDOWNWM_ LBUTTONDOWNOnLButtonDownON_WM_LBUTTONUPWM_ LBUTTONUPOnLButtonUpON_ WM_MOUSEMOVEWM_ MOUSEMOVEOnMouseMove由于有系统默认的消息和处理函数,在消息映射表中只写宏名,如:由于有系统默认的消息和处理函数,在消息映射表中只写宏名,如:ON_WM_CREATE()35特制分析(2).对命令消息的的响应对命令消息的的响应 。 ON_COMMAND宏定义对命令消息的响应,格式为宏定义对命令消息的响应,格式为ON_COMMAND(命令命令ID,响应函

36、数响应函数)举例如下:举例如下: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_)等

37、产生,在消息名前加上等产生,在消息名前加上ON_即构成宏名,即构成宏名,举例如下:举例如下: ON_BN_CLICKED (按钮按钮ID,响应函数响应函数) ON_CBN_DBCLK (组合框组合框ID,响应函数响应函数) ON_EN_SETFOCUS (组合框组合框ID,响应函数响应函数) ON_LBN_DBCLK (列表框列表框ID,响应函数响应函数) 分别表示选择各个控件后,产生的消息由其后面定义分别表示选择各个控件后,产生的消息由其后面定义的函数进行处理。的函数进行处理。37特制分析3.消息处理消息处理消息一般由应用程序中对象的成员函数来响应。当某个事件消息一般由应用程序中对象的成员函

38、数来响应。当某个事件发生后,系统向应用程序消息队列放入一个消息,发生后,系统向应用程序消息队列放入一个消息,CWinAppCWinApp对象取得消息并按照消息映射表的定义将消息派对象取得消息并按照消息映射表的定义将消息派送到某个类的相应的消息处理函数进行处理。送到某个类的相应的消息处理函数进行处理。使用使用ClassWizard(ClassWizard(见第五章菜单中见第五章菜单中ViewView菜单介绍菜单介绍) )定义消息定义消息映射关系,添加消息处理函数,系统会自动生成函数原型映射关系,添加消息处理函数,系统会自动生成函数原型和函数框架,开发人员只要添加函数体代码,可以避免一和函数框架,

39、开发人员只要添加函数体代码,可以避免一些常见错误的产生。些常见错误的产生。38特制分析程序中类响应程序中类响应windowswindows消息的优先顺序:消息的优先顺序:取决于消息传递的顺序。取决于消息传递的顺序。对对于于一一般般的的WindowsWindows消消息息,由由产产生生这这些些消消息息的的对对象象响响应应,如如窗窗口口的的创创建建WM_CREATE,WM_CREATE,窗窗口口的的移移动动WM_MOVEWM_MOVE,由由产产生生消消息息的的窗窗口口类类响响应应,如如果果找找不不到到相相应应的的处处理理函函数数,则则将将消消息息传递到其父类,一般情况都有缺省的响应函数;传递到其父

40、类,一般情况都有缺省的响应函数;对于命令消息对于命令消息WM_COMMANDWM_COMMAND,可由拥有菜单资源的所有类来,可由拥有菜单资源的所有类来处理,传递的顺序是视图类、文档类、文档模板类、框处理,传递的顺序是视图类、文档类、文档模板类、框架类、应用程序类,即这些类处理命令消息的优先顺序。架类、应用程序类,即这些类处理命令消息的优先顺序。详见第详见第2章。章。39特制分析视图类的定义文件视图类的定义文件(.cpp)中必须有中必须有消息映射消息映射定义:定义:BEIGN_MESSAGE_MAP(CMyView,CView)/消息映射表定义消息映射表定义ON_WM_LBUTTONDOWN(

41、)/函数名为函数名为OnLButtonDown/其它消息映射入口其它消息映射入口END_MESSAGE_MAP()以及对应的消息响应函数定义:以及对应的消息响应函数定义:voidCMyView:OnLButtonDown(UINTnFlags,CPointpoint)/处理消息的操作代码,程序中具体实现处理消息的操作代码,程序中具体实现返回返回将将CMyView的基的基类类CView也包含进也包含进去,当在派生类中去,当在派生类中没找到处理函数时,没找到处理函数时,允许在基类中继续允许在基类中继续查找。查找。注注40特制分析例例如如,当当用用户户在在视视图图窗窗口口中中按按下下鼠鼠标标左左键键

42、时时,WindowsWindows发发送送WM_LBUTTONDOWNWM_LBUTTONDOWN消消息息到到应应用用程程序序,假假设设视视图图类类需需要要响响应应这这些些消息,在类的头文件消息,在类的头文件(.h)(.h)中有中有函数函数声明和声明和消息映射表消息映射表的声明:的声明:Class CMyView: public CView afx_msg void OnLButtonDown(UINT nFlags,CPoint point); /函数原型声明函数原型声明DECLARE_MESSAGE_MAP() /消息映射表声明消息映射表声明 返回返回afx_msg标识消息映射函数,标识消

43、息映射函数,所有由所有由ClassWizard生成的消生成的消息处理函数原型说明前都有这息处理函数原型说明前都有这一标识。一标识。注注41特制分析3.2.3.3.2.3.文档文档/ /视图结构视图结构 1.1.文档类文档类 在基于文档在基于文档/ /视图结构的应用程序中,视图结构的应用程序中,CDocumentCDocument的派生对象负责读入、保存和管理的派生对象负责读入、保存和管理应用程序的数据。每个文档类可能与多个视图应用程序的数据。每个文档类可能与多个视图类关联,而每个视图包含一个指向与其相关的类关联,而每个视图包含一个指向与其相关的文档的指针。文档的指针。 文文档档类类允允许许向向

44、其其中中增增加加数数据据成成员员,应应用用程程序序的的数数据据可可以以是是任任何何类类型型的的,或或者者是是任任何何自自定定义的数据结构,如结构体,类或链表等。义的数据结构,如结构体,类或链表等。 42特制分析3.2.3.3.2.3.文档文档/ /视图结构视图结构 文档类的常用成员函数文档类的常用成员函数( (带带的表示是可重定义函数的表示是可重定义函数) ) 成员函数成员函数说明说明GetFirstViewPositionGetFirstViewPosition返回一个第一个视图的位置值返回一个第一个视图的位置值GetNextViewGetNextView返回指向相关视图队列中下一个视图的指

45、返回指向相关视图队列中下一个视图的指针针GetPathNameGetPathName取得文档的文件名和路径,若文档未命名取得文档的文件名和路径,若文档未命名则返回空串则返回空串GetTitleGetTitle取得文档的标题,若文档未命名则返回空取得文档的标题,若文档未命名则返回空串串IsModifiedIsModified若文档包含未保存数据,则返回非若文档包含未保存数据,则返回非0 0,否则,否则返回返回0 0SetModifiedFlagSetModifiedFlag设置或清除文档的修改标志设置或清除文档的修改标志表表3.43.443特制分析成员函数成员函数说明说明UpdateAllVie

46、wsUpdateAllViews文档对应多个视图时,更新所有视图,它是通文档对应多个视图时,更新所有视图,它是通过调用每个视图类的过调用每个视图类的OnUpdateOnUpdate函数来更新所有函数来更新所有与本文档关联的视图与本文档关联的视图OnNewDocumentOnNewDocument当创建一个新文档时由应用程序框架调用。重当创建一个新文档时由应用程序框架调用。重定义这个函数实现在新文档创建之前初始化文定义这个函数实现在新文档创建之前初始化文档对象,如为指针申请内存空间档对象,如为指针申请内存空间OnOpenDocumentOnOpenDocument当从磁盘读入文档时由应用程序框架

47、调用。重当从磁盘读入文档时由应用程序框架调用。重定义这个函数实现在新文档读入之前初始化文定义这个函数实现在新文档读入之前初始化文档的其它非序列化数据成员档的其它非序列化数据成员DeleteContentsDeleteContents由应用程序框架调用,以删除文档内容。重定由应用程序框架调用,以删除文档内容。重定义这个函数在文档关闭之前释放文档所占用的义这个函数在文档关闭之前释放文档所占用的内存和资源内存和资源SerializeSerialize由应用程序框架调用对文档进行序列化,重定由应用程序框架调用对文档进行序列化,重定义这个函数实现特定文档的序列化,以保存或义这个函数实现特定文档的序列化,

48、以保存或读入文档数据读入文档数据44特制分析2.2.视图类视图类 视视图图类类对对象象代代表表了了应应用用程程序序的的窗窗口口客客户户区区,是是文文档档信信息息的的一一个个显显示示窗窗口口( (视视口口) ),它它同同时时也也是是用用户户与与程程序序之之间间信信息息交交互互的的桥桥梁梁,用用户户对对数数据据的的编编辑辑和和修修改改需需要要通通过过键键盘盘或或鼠鼠标标进进行行,这这些些消消息都由视图类接受后再反映到文档类。息都由视图类接受后再反映到文档类。45特制分析视图类的派生关系:视图类的派生关系: CWndCViewCCtrlViewCListViewCEditViewCRichEditV

49、iewCTreeViewCScrollViewCFormViewCDaoRecordViewCDaoRecordView图图3.546特制分析 CViewCView类提供了向视图或打印机进行输出的基本框类提供了向视图或打印机进行输出的基本框架,决定了视图的基本特性,派生的视图类可以重架,决定了视图的基本特性,派生的视图类可以重载基类的函数,或增加新的函数以决定特定视图的载基类的函数,或增加新的函数以决定特定视图的特性。特性。CViewCView的派生类可以多种方式显示文档类的信息,每的派生类可以多种方式显示文档类的信息,每个视图类根据显示的方式各自定义其显示代码。个视图类根据显示的方式各自定义

50、其显示代码。 MFC提供了一系列这样的类,如提供了一系列这样的类,如CTreeView 树型视图树型视图CListView 列表型视图列表型视图CFormView 显示基于对话框模板的视图显示基于对话框模板的视图CScrollView 带滚动条的视图。带滚动条的视图。 47特制分析1)1)视图类实现特定视图的特性的虚函数视图类实现特定视图的特性的虚函数GetDocument返回指向相关联文档对象的指针返回指向相关联文档对象的指针OnDraw支持打印、打印预览和在屏幕上显示,支持打印、打印预览和在屏幕上显示,由由OnPaint(重画重画),OnPrint(打印打印)调调用用OnInitialUp

51、date当视图第一次与文档关联时被调用,重当视图第一次与文档关联时被调用,重定义这个函数对重新读入或新创建文定义这个函数对重新读入或新创建文档的视图进行初始化档的视图进行初始化OnUpdate当文档内容发生变化,视图需要更新时当文档内容发生变化,视图需要更新时被调用,更新整个视图。重定义这个被调用,更新整个视图。重定义这个函数可以实现只更新无效区域函数可以实现只更新无效区域表表3.548特制分析CEx3_1Doc* pDoc = GetDocument();CEx3_1Doc* pDoc = GetDocument();CEx3_1Doc* pDoc = GetDocument();CEx3_

52、1Doc* pDoc = GetDocument();通过通过GetDocumentGetDocument获得与视图关联的文档类指针,通过指针获得与视图关联的文档类指针,通过指针pDocpDoc访问文档类的数据成员和函数成员,在视图(窗口)访问文档类的数据成员和函数成员,在视图(窗口)中显示文档对象,当用户通过视图改变文档数据时,可中显示文档对象,当用户通过视图改变文档数据时,可设置自动更新文档内容。设置自动更新文档内容。文文档档/ /视视图图结结构构已已经经把把应应用用程程序序所所需需要要的的数数据据处处理理与与显显示示( (虚虚函函数数) )的的框框架架构构造造好好,程程序序设设计计人人员

53、员只只需需要要将将具具体体应应用用的的数数据据添添加加到到文文档档类类,并并根根据据数数据据类类型型在在视视图图类类的的虚虚函数函数OnDraw()OnDraw()中完成数据的显示。中完成数据的显示。 2) 2) 视图类的成员函数访问与其关联的文档类的方式视图类的成员函数访问与其关联的文档类的方式 49特制分析3.3.文档模板类文档模板类 CDocTemplateCDocTemplate类将框架、视图、文档对象及应用类将框架、视图、文档对象及应用 程程序的资源捆绑在一起。应用程序每打开一个文件,序的资源捆绑在一起。应用程序每打开一个文件,至少创建一个文档对象、一个视图对象和一个框架至少创建一个

54、文档对象、一个视图对象和一个框架窗口,而文档模板对象负责管理所有这些对象,并窗口,而文档模板对象负责管理所有这些对象,并将各种相关资源与之联系在一起。将各种相关资源与之联系在一起。在大多数情况下,程序不需要对这个类进行修改。在大多数情况下,程序不需要对这个类进行修改。对于对于SDISDI应用,使用应用,使用CSingleDocTemplateCSingleDocTemplate文档模板。文档模板。对于对于MDIMDI应用,使用应用,使用CMultiDocTemplateCMultiDocTemplate文档模板。文档模板。MDIMDI允许允许有多个文档模板,将不同文档有多个文档模板,将不同文档

55、- -视图类联系在一起,实现不视图类联系在一起,实现不同文档视图显示关系。同文档视图显示关系。50特制分析4.4.应用程序创建过程应用程序创建过程1)使用使用AppWzard,根据实际需要,选择创建合适,根据实际需要,选择创建合适的应用程序框架的应用程序框架(是否使用文档是否使用文档/视图结构,使用视图结构,使用SDI或或MDI等等)2)在文档类中添加程序所处理的数据,作为文档类在文档类中添加程序所处理的数据,作为文档类数据成员;数据成员;3)在视图类中取得文档数据,以合适的方式在窗口在视图类中取得文档数据,以合适的方式在窗口中显示出来中显示出来51特制分析5.应用实例应用实例 例例3_13_

56、1: :创建一个包含文档创建一个包含文档/ /视图结构单文档视图结构单文档界面应用的实例,为文档类添加一个字符界面应用的实例,为文档类添加一个字符串数据,在视图窗口显示出来。串数据,在视图窗口显示出来。步骤如下:步骤如下:(1).(1).在在FileFile菜单中选择菜单中选择NewNew,如图,如图3.3.,在,在ProjectProject页面选择页面选择MFC AppWizard(exe),MFC AppWizard(exe),在在Project nameProject name中输入中输入Ex3_1,Ex3_1,并选择合适的并选择合适的路径按路径按OKOK按钮。按钮。 52特制分析(2

57、).(2).在在AppWizard Step 1AppWizard Step 1中,如图中,如图3.3.,选择选择Single DocumentSingle Document单单 选按钮,并选中选按钮,并选中Document/ View architechure SupportDocument/ View architechure Support复选框,复选框, 表示使用文档表示使用文档/ /视图结构,按视图结构,按FinishFinish按钮。显示按钮。显示New Project New Project InformationInformation信息框,显示新创建的工程信息框,显示新创建的

58、工程的有关信息按的有关信息按OKOK按钮,这样工程创建完毕。按钮,这样工程创建完毕。53特制分析图图3.3. New ProjectNew Project对话框对话框54特制分析图图3.3. AppWizard Step1AppWizard Step1 55特制分析在在VCVC集集成成开开发发环环境境中中看看到到,新新工工程程生生成成了了五五个个类类,如如图图3.3.在在class viewclass view页面上可看到这些类。页面上可看到这些类。 CAboutDlgCAboutDlg 派生自派生自CDialogCDialog,一个,一个AboutAbout对话框。对话框。 CEx3_1Ap

59、p CEx3_1App 派生自派生自CWinAppCWinApp,其全局对象,其全局对象theApptheApp 代表应用程序本身。代表应用程序本身。 CEx3_1DocCEx3_1Doc 派生自派生自CDocumentCDocument,文档类。,文档类。 CEx3_1ViewCEx3_1View 派生自派生自CViewCView,视图类。,视图类。 CMainFrameCMainFrame 派生自派生自 CFrameWndCFrameWnd,程序框架类。,程序框架类。56特制分析文档、视图及应用程序类名都以工程名开文档、视图及应用程序类名都以工程名开头,后接对应的类型名,这有助于在程序头,

60、后接对应的类型名,这有助于在程序中有多个文档视图类时区分主视图与其它中有多个文档视图类时区分主视图与其它视图,区分主文档与其它文档类。视图,区分主文档与其它文档类。应用程序向导应用程序向导AppWizardAppWizard为每个类生成了一为每个类生成了一个头文件和一个个头文件和一个.cpp.cpp文件,还自动生成了文件,还自动生成了stdafx.hstdafx.h和和stdafx.cppstdafx.cpp,图图3.3.,AppWizardAppWizard还生成了缺省的用户界面资源还生成了缺省的用户界面资源文件,在文件,在Resource viewResource view页面显示。页面显

61、示。57特制分析图图3.3. ClassViewClassView图图3.3.FileViewFileView 58特制分析(3).(3).为文档类增加数据成员。在编辑窗口打为文档类增加数据成员。在编辑窗口打开文档类的头文件开文档类的头文件Ex3_1Doc.hEx3_1Doc.h,手工添加手工添加一个字符数组成员一个字符数组成员m_StrNamem_StrName;或或在在WorkspaceWorkspace的的ClassViewClassView页面,右击页面,右击 CEx3_1DocCEx3_1Doc类,在弹出式菜单中类,在弹出式菜单中选择选择Add Add Member Variable

62、sMember Variables,在对话框中输入变量,在对话框中输入变量类型和名称。类型和名称。在文档类构造函数中对新增加的变量进行初在文档类构造函数中对新增加的变量进行初始化始化。(4).(4).显示字符串显示字符串. .在在CEx3_1ViewCEx3_1View的的OnDraw()OnDraw()函函数显示字符串。数显示字符串。 59特制分析图图3.10 3.10 例例3.13.1第一步主界面第一步主界面60特制分析3.3.用户界面资源的应用用户界面资源的应用 资资源源是是windowswindows应应用用程程序序的的一一种种特特殊殊数数据据,包包括括菜菜单单、加加速速键键、光光标标

63、、位位图图、图图标标、对对话话框框、字字符符串串、 工工具具栏栏、状状态态栏栏等等,资源一般放在资源一般放在exeexe或或DLLDLL文件中。文件中。当当windowswindows将将程程序序装装入入内内存存时时,一一般般不不将将资资源源同同时时装装入入,而而是是当需要某个资源时才将相应资源装入。当需要某个资源时才将相应资源装入。 资资源源定定义义在在资资源源脚脚本本(resource resource scirptscirpt)文文件件中中。 以以.rc.rc为为文件扩展名,文件名与工程名相同。文件扩展名,文件名与工程名相同。资资源源脚脚本本文文件件中中定定义义了了各各种种资资源源的的相

64、相关关数数据据,WindowsWindows通通过过使使用用不不同同的的资资源源标标识识符符前前缀缀来来区区分分不不同同资资源源类类型型( (如如表表3.3.所所示示),这这样样做做虽虽然然不不是是必必须须的的,但但遵遵循循这这样样的的规规则则 有有利利于提高程序的通用性和可读性。于提高程序的通用性和可读性。61特制分析表表3.3. 资源类型及其标示资源类型及其标示 资源标识前缀资源标识前缀IDM_ID_IDI_IDB_IDD_IDR_IDC_IDS_资源类型资源类型菜单项菜单项IDID菜单命令菜单命令IDID图标图标IDID位图位图IDID对话框对话框IDID菜单栏、工具栏、加速键菜单栏、工

65、具栏、加速键控件控件IDID字符串字符串返回返回62特制分析VisualC+6.0中提供了资源编辑器,对资源中提供了资源编辑器,对资源进行可视化编辑,并自动生成进行可视化编辑,并自动生成资源脚本文件资源脚本文件;脚本文件可用文本编辑器进行编辑,但其可脚本文件可用文本编辑器进行编辑,但其可读性较差,容易出错,一般情况下尽量不要读性较差,容易出错,一般情况下尽量不要进行编辑。进行编辑。用户定义的资源标识符号常量定义在用户定义的资源标识符号常量定义在resource.h文件中。文件中。3.3.3.3.用户界面资源的应用用户界面资源的应用 63特制分析3.3.1.3.3.1.菜单菜单 分类分类: :

66、顶层菜单顶层菜单 : : 一般位于应用程序主窗口或顶层窗口一般位于应用程序主窗口或顶层窗口 弹出式菜单弹出式菜单: : 选择某个菜单项后弹出的子菜单选择某个菜单项后弹出的子菜单 1.菜单的编辑菜单的编辑 如果是如果是AppWizardAppWizard产生的程序,系统已为框架创产生的程序,系统已为框架创建了一个标准的主菜单,包括文件、编辑、视图、建了一个标准的主菜单,包括文件、编辑、视图、窗口帮助等标准菜单,定义了各菜单项的窗口帮助等标准菜单,定义了各菜单项的IDID及相及相应的命令处理函数。在应的命令处理函数。在Resource ViewResource View页面,打开页面,打开工程资源

67、,选择工程资源,选择MenuMenu,然后双击主菜单资源,然后双击主菜单资源IDR_MAINFRAMEIDR_MAINFRAME标示,可打开菜单编辑器。标示,可打开菜单编辑器。 64特制分析添加新的菜单资源添加新的菜单资源选择选择Insert ResourceInsert Resource菜单项,在菜单项,在Insert ResourceInsert Resource对话框中对话框中,选择,选择MenuMenu资源类型,单击资源类型,单击NewNew按钮,缺省新菜单名为按钮,缺省新菜单名为IDR_MENU1IDR_MENU1。a)增加一个顶层菜单增加一个顶层菜单 在菜单属性对话框中,选中在菜单

68、属性对话框中,选中Pop-upPop-up选项,可以定义一选项,可以定义一个顶层菜单,在个顶层菜单,在CaptionCaption编辑框中输入菜单名,菜单名即显编辑框中输入菜单名,菜单名即显示在菜单上。若在菜单名的某个字符前加一个示在菜单上。若在菜单名的某个字符前加一个& &符号,则菜符号,则菜单名该字符下显示一个下画线,可用单名该字符下显示一个下画线,可用AltAlt加该字符作为选择加该字符作为选择菜单的快捷方式。菜单的快捷方式。对中文菜单对中文菜单“文件文件”,如希望用,如希望用Alt-FAlt-F作作为键盘操作方式,可写成为键盘操作方式,可写成“文件文件(&F)(&F)”。 在定义好的菜

69、单后面,仍预留了一个空白菜单,可拖动在定义好的菜单后面,仍预留了一个空白菜单,可拖动该空白菜单到任意位置增加新的菜单。该空白菜单到任意位置增加新的菜单。 65特制分析b)增加一个子菜单增加一个子菜单 若在定义菜单项时选中若在定义菜单项时选中Pop-upPop-up选项,则在该菜单项右边选项,则在该菜单项右边出现一个三角形符号,同时右边出现一个新的菜单,出现一个三角形符号,同时右边出现一个新的菜单,再定义这个菜单。再定义这个菜单。c) 定义菜单项定义菜单项 双击空白菜单项,打开菜单项属性对话框双击空白菜单项,打开菜单项属性对话框, ,如图如图3.13.1,在在GeneralGeneral页面上输

70、入页面上输入CaptionCaption菜单项名称及其菜单项名称及其IDID值,在值,在PromptPrompt编辑框中的字符串是选择该菜单项时状态栏上显示的编辑框中的字符串是选择该菜单项时状态栏上显示的内容,在内容,在nn后面的内容为当光标移至工具栏上与其后面的内容为当光标移至工具栏上与其IDID值相同值相同的图标上时状态栏显示的内容。的图标上时状态栏显示的内容。 在空白菜单项被定义后,该菜单的最下面又出现一个空在空白菜单项被定义后,该菜单的最下面又出现一个空白菜单项,拖动该空白菜单项可在已定义的菜单内任何位置白菜单项,拖动该空白菜单项可在已定义的菜单内任何位置插入新菜单项或新子菜单。插入新

71、菜单项或新子菜单。 66特制分析d)创建菜单加速键创建菜单加速键a.a.在在CaptionCaption编辑框中,在菜单项名后,在字符编辑框中,在菜单项名后,在字符tt后,加上快后,加上快捷键组合,如图捷键组合,如图3.13.1所示,所示,Ctrl+OCtrl+O表示打开文件操,快捷表示打开文件操,快捷键组合会出现在菜单项名右端,键组合会出现在菜单项名右端,目的是给用户一个提示;目的是给用户一个提示; b.b.在在WorkspaceWorkspace的的ResourceViewResourceView页面上,找到加速键页面上,找到加速键AcceleratorAccelerator资源,资源,A

72、ppWizardAppWizard生成的缺省加速键资源名为生成的缺省加速键资源名为IDR_MAINFRAMEIDR_MAINFRAME。双击它打开加速键表,在已有加速键表后。双击它打开加速键表,在已有加速键表后面,有一个空白行,双击它打开加速键属性对话框,如面,有一个空白行,双击它打开加速键属性对话框,如图图3.13.1,选择某个菜单项,选择某个菜单项IDID,在,在KeyKey列表框选择某个虚拟键作列表框选择某个虚拟键作为菜单命令的快捷方式,或选择为菜单命令的快捷方式,或选择Next Key TypedNext Key Typed按钮,此后按钮,此后键盘输入的按键组合即为菜单命令加速键。键盘

73、输入的按键组合即为菜单命令加速键。这一步才是快捷这一步才是快捷键的定义过程。键的定义过程。 67特制分析图图3.13.1 菜单项设置菜单项设置 返回返回 定义菜单项定义菜单项返回创建菜单加速键返回创建菜单加速键选项选项含义含义ID表示该菜单项的表示该菜单项的IDID值值Caption表示该菜单项显示的文本表示该菜单项显示的文本Separator表示该菜单项是一条分隔线表示该菜单项是一条分隔线Checked表示该菜单项被选中显示一个标志表示该菜单项被选中显示一个标志Pop-up选择该菜单项显示一个子菜单选择该菜单项显示一个子菜单选项选项含义含义Grayed该菜单项变灰显示,被禁止该菜单项变灰显示

74、,被禁止Inactive该菜单项不被激活该菜单项不被激活HelpHelpHelp菜单,通常放在菜单的最右端菜单,通常放在菜单的最右端Break选中该菜单项后就退出其所在菜单选中该菜单项后就退出其所在菜单Prompt光标移至该菜单项状态栏显示的文本光标移至该菜单项状态栏显示的文本68特制分析定义定义Ctrl+OCtrl+O为为ID_FILE_OPENID_FILE_OPEN的快捷方式,在的快捷方式,在IDID编辑框中输编辑框中输入入ID_FILE_OPENID_FILE_OPEN,在,在KeyKey中键入中键入O, O, 然后选中然后选中CtrlCtrl复选框复选框即可定义了菜单项的快捷方式。即

75、可定义了菜单项的快捷方式。 图图3.13.1 快捷键设置快捷键设置 注意注意 : :(1).不要对不同菜单命令使用相同的加速键组合,以免产生二意性;不要对不同菜单命令使用相同的加速键组合,以免产生二意性;(2).加速键命令必须有菜单命令与之对应,加速键不应该是某个命令唯加速键命令必须有菜单命令与之对应,加速键不应该是某个命令唯一启动方式。一启动方式。69特制分析MFC程序可以处理两种菜单消息程序可以处理两种菜单消息2.菜单消息菜单消息WM_COMMAND为菜单命令消息为菜单命令消息,当选择菜单项、工具,当选择菜单项、工具栏按钮或加速键之一会发出菜单命令消息,栏按钮或加速键之一会发出菜单命令消息

76、,MFC依据一依据一定的消息传递途径将消息传递给相应的处理函数进行处定的消息传递途径将消息传递给相应的处理函数进行处理,如果在消息传递途径的消息映射表中找不到相应的理,如果在消息传递途径的消息映射表中找不到相应的处理函数,该菜单项或按钮会被禁止使用。处理函数,该菜单项或按钮会被禁止使用。 70特制分析UPDATE_COMMAND_UI是菜单更新消息是菜单更新消息,处理菜单状态,处理菜单状态的动态变化。如希望根据程序的执行状态,激活或禁用的动态变化。如希望根据程序的执行状态,激活或禁用某些菜单项,设置选中标记,或更改菜单项文字等,就某些菜单项,设置选中标记,或更改菜单项文字等,就要定义这一消息处

77、理函数。要定义这一消息处理函数。这一消息在这一消息在Message MapMessage Map中定义如下:中定义如下:ON_UPDATE_COMMAND_UI(ON_UPDATE_COMMAND_UI(,)例如:例如:ON_UPDATE_COMMAND_UI(ID_EDIT_COPY,OnUpdateEditCopy)ON_UPDATE_COMMAND_UI(ID_EDIT_COPY,OnUpdateEditCopy)在在某某个个菜菜单单显显示示前前,框框架架将将发发送送菜菜单单内内所所有有菜菜单单项项的的更更新新命命令令,有有更更新新处处理理函函数数的的菜菜单单项项,调调用用其其处处理理函

78、函数数更更新新菜菜单显示方式;单显示方式;没没有有更更新新处处理理函函数数的的菜菜单单项项,查查找找其其命命令令处处理理函函数数,若若仍仍然然没有,则将菜单项禁用。没有,则将菜单项禁用。71特制分析3.菜单消息的处理菜单消息的处理 定义好菜单项及其定义好菜单项及其IDID后,为菜单命令添加响应函数,实现方法后,为菜单命令添加响应函数,实现方法是借助是借助ClassWizardClassWizard,在需要响应菜单命令的类的消息映射,在需要响应菜单命令的类的消息映射表中增加一个入口,即定义一个命令消息表中增加一个入口,即定义一个命令消息ON_COMMANDON_COMMAND宏。宏。选择选择Vi

79、ew|ClassWizard,打开,打开ClassWizard对话框,在对话框,在MessageMap页面,页面,图图3.14。在。在ClassName列表框中选择列表框中选择要响应菜单命令的类名,在要响应菜单命令的类名,在ObjectIDs列表框中选择菜单列表框中选择菜单ID,在,在Message列表框中选择列表框中选择COMMAND或或UPDATE_COMMAND_UI,然后按,然后按AddFunction按钮,弹按钮,弹出出AddMemberFunction对话框,可以修改函数名或接受缺对话框,可以修改函数名或接受缺省函数名,按省函数名,按OK结束这个对话框,然后在结束这个对话框,然后在

80、ClassWizard对话对话框中按框中按EditCode按钮,直接跳至新增函数的定义处。按钮,直接跳至新增函数的定义处。72特制分析图图3.14 ClassWizard 添加消息映射关系添加消息映射关系 73特制分析3.3.2 3.3.2 工具栏工具栏 工具栏是一个包含一个或多个命令按钮的窗口,一般情工具栏是一个包含一个或多个命令按钮的窗口,一般情况下附着在窗口客户区上方菜单栏下面,也可作为一况下附着在窗口客户区上方菜单栏下面,也可作为一个浮动的小窗口。工具栏为菜单命令提供可视化的快个浮动的小窗口。工具栏为菜单命令提供可视化的快捷操作方式,模拟大部分的菜单行为。捷操作方式,模拟大部分的菜单行

81、为。1 1编辑工具栏编辑工具栏在在WorkspaceWorkspace的的ResourceViewResourceView页面,点击页面,点击ToolbarToolbar前的号可前的号可以看到缺省的工具栏资源以看到缺省的工具栏资源IDR_MAINFRAMEIDR_MAINFRAME,双击它打开可视化工具栏编辑器。,双击它打开可视化工具栏编辑器。工具栏资源由一组按钮组成,每个按钮是一个工具栏资源由一组按钮组成,每个按钮是一个1616色位图图标,色位图图标,工具栏编辑器提供一个简单的位图编辑器工具栏编辑器提供一个简单的位图编辑器, ,点击某个图标点击某个图标即可编辑它。即可编辑它。用鼠标拖动图标:

82、改变它在工具栏中的位置用鼠标拖动图标:改变它在工具栏中的位置用鼠标拖出工具栏外:删除图标用鼠标拖出工具栏外:删除图标74特制分析双击位图打开双击位图打开Toolbar Button PropertiesToolbar Button Properties对话框对话框, ,图图3.15,3.15,在在IDID列表框中输入命令列表框中输入命令IDID。列表框中列出了当前工程中已。列表框中列出了当前工程中已存在的存在的IDID,可为已有命令提供可视化的快捷操作方式。,可为已有命令提供可视化的快捷操作方式。 图图3.153.15工具栏图标编辑工具栏图标编辑 75特制分析2. 2. 工具栏命令处理工具栏命

83、令处理 如如果果工工具具栏栏按按钮钮与与某某个个菜菜单单项项有有相相同同的的IDID,则则它它们们共共享享一一个个命命令令响响应应函函数数,不不需需要要另另外外定定义义命命令令响响应应函函数数。具具有有相相同同IDID的的菜菜单单项项和和工工具具栏栏按按钮钮还还共共享享提提示示字字符符串串,它它们们的的显显示示状状态态也也同同步步变化。变化。如如果果与与工工具具栏栏按按钮钮对对应应的的菜菜单单项项定定义义了了更更新新函函数数,工具栏按钮也会同步实现状态的动态变化。工具栏按钮也会同步实现状态的动态变化。 76特制分析3.3.3 3.3.3 状态栏状态栏 状态栏是出现在应用程序窗口底部的显示程序运

84、行状态栏是出现在应用程序窗口底部的显示程序运行状况的窗口,当用户选择了菜单项或某个工具栏状况的窗口,当用户选择了菜单项或某个工具栏按钮时,状态栏显示它们的提示字符串。按钮时,状态栏显示它们的提示字符串。AppWizardAppWizard为应用程序添加缺省的状态栏,为为应用程序添加缺省的状态栏,为CMainFrameCMainFrame类类增加增加CStatusBarCStatusBar类的数据成员类的数据成员m_wndStatusBarm_wndStatusBar,在,在MainFrame.cppMainFrame.cpp文件中添加提示符数组,作为状态栏创建时文件中添加提示符数组,作为状态栏

85、创建时的参数。的参数。static UINT indicators = ID_SEPARATOR, /状态栏指示器ID_INDICATOR_CAPS, /显示Caps Lock键状态ID_INDICATOR_NUM, /显示Num Lock键状态ID_INDICATOR_SCRL, /显示Scroll Lock键状态; /可以向数组中增加ID以增加状态栏上显示栏。77特制分析3.3.3 3.3.3 状态栏状态栏 图图3.16 3.16 例例3.13.1主界面主界面 78特制分析3.4.3.4.对话框的应用对话框的应用 3.4.1 3.4.1 对话框的工作方式、种类和创建方法对话框的工作方式、种

86、类和创建方法 1. 1. 对话框在应用程序中的工作方式对话框在应用程序中的工作方式 对话框是一个读入或写出数据的图形界面对象,由集对话框是一个读入或写出数据的图形界面对象,由集成开发环境中的对话框模板提供,可以向模板添加各种控成开发环境中的对话框模板提供,可以向模板添加各种控件件( (如按钮,编辑框,单选复选按钮等如按钮,编辑框,单选复选按钮等) ),构成程序的对话,构成程序的对话框资源;框资源; 应用程序要使用对话框还需定义一个应用程序要使用对话框还需定义一个CDialogCDialog派生类派生类的对话框类与资源相连接,并在这个对话框类中定义一些的对话框类与资源相连接,并在这个对话框类中定

87、义一些成员变量与对话框中的控件相对应,提供对话框控件的缺成员变量与对话框中的控件相对应,提供对话框控件的缺省数据值;省数据值; 79特制分析 程序运行时需要用到对话框时依据对话框资源程序运行时需要用到对话框时依据对话框资源激活对话框,接收用户输入后通过成员函数更新文激活对话框,接收用户输入后通过成员函数更新文档类数据成员,如图档类数据成员,如图3.173.17示。示。 图图3.173.17对话框与文档的数据交换对话框与文档的数据交换 构造对话构造对话框并更新框并更新文档数据文档数据 数据数据交换交换对对话话框框模模板板 controlspublic:data members文档类:文档类:ap

88、plication datas对话框对话框类对象类对象80特制分析2. 2. 对话框的种类对话框的种类 WindowsWindows有两种对话框,模态对话框和非模态对话框,有两种对话框,模态对话框和非模态对话框,构造两种对话框的大多数工作都相同,只是两者构造两种对话框的大多数工作都相同,只是两者的显示和数据处理有些不同。的显示和数据处理有些不同。模态对话框模态对话框(Modal Dialog Boxes)(Modal Dialog Boxes)工作时使其父类窗口无效,工作时使其父类窗口无效,直到对话框结束。也就是说,该对话框打开后直到对话框结束。也就是说,该对话框打开后, , 程序等待用程序等

89、待用户输入,在关闭对话框后才执行其它任务。户输入,在关闭对话框后才执行其它任务。 非模态对话框非模态对话框( Modeless Dialog Boxes)( Modeless Dialog Boxes)在打开期间,允许在打开期间,允许用户切换到程序其它部分,不一定要关闭对话框。用户切换到程序其它部分,不一定要关闭对话框。WinWordWinWord中的中的Find and ReplaceFind and Replace对话框是一个典型的非模态对话框。对话框是一个典型的非模态对话框。 81特制分析3. 3. 对话框的创建与编辑对话框的创建与编辑 a)a)对话框的创建对话框的创建 选择选择Inse

90、rt|Resource.Insert|Resource.,在,在Insert Insert ResourceResource对话框中选择对话框中选择DialogDialog类型,按类型,按NewNew按钮,按钮,打开对话框编辑器,缺省情况下,对话框模板提打开对话框编辑器,缺省情况下,对话框模板提供了供了OKOK和和CancelCancel两个按钮,同时打开了对话框工两个按钮,同时打开了对话框工具栏和控件工具栏,如下图。具栏和控件工具栏,如下图。82特制分析图3.18对话框模板及编辑工具83特制分析在对话框模板内右击鼠标,在弹出的菜单中选择在对话框模板内右击鼠标,在弹出的菜单中选择Propert

91、iesProperties,打开,打开Dialog PropertyDialog Property对话框。对话框。图3.19对话框属性对话框84特制分析b)b)控件属性控件属性 将控件工具栏中的任一种控件拖至对话框模板中,将控件工具栏中的任一种控件拖至对话框模板中,在控件上右击鼠标,选择在控件上右击鼠标,选择PropertiesProperties打开控件属打开控件属性对话框,如性对话框,如图图3.203.20。各种控件属性对话框基本相似,在各种控件属性对话框基本相似,在IDID框中输入标识框中输入标识控件的唯一控件的唯一IDID值,在值,在CaptionCaption中输入控件上显示的中输入

92、控件上显示的字符字符(Edit(Edit控件没有这一属性控件没有这一属性) ),VisibleVisible表示该控表示该控件在对话框创建时是否显示,件在对话框创建时是否显示,GroupGroup用来控制控件用来控制控件分组,分组,DisabledDisabled使控件不可用,使控件不可用,Tab stopTab stop表示是表示是否用否用TabTab键选择控件。键选择控件。 85特制分析图3.20 控件属性设置对话框86特制分析c)c)控制控制TabTab顺序顺序 当当打打开开对对话话框框编编辑辑器器后后,集集成成开开发发环环境境的的菜菜单单上上多多了了一一个个LayoutLayout菜菜

93、单单,其其中中主主要要是是对对话话框框工工具具栏栏上上显显示示的的一一些些命命令令,其其中中有有一一个个命命令令Tab Tab OrderOrder,定定义义当当用用户户用用TabTab键键移移动动输输入入焦焦点点时时各各控控件件接接受焦点的顺序。如受焦点的顺序。如图图3.213.21所示。所示。d)d)分组控制分组控制 VCVC提供了根据控件功能将控件进行分组的工提供了根据控件功能将控件进行分组的工具,使用户更易于理解对话框的结构。在分组框具,使用户更易于理解对话框的结构。在分组框中使用最多的是单选按钮中使用最多的是单选按钮(radio buttons)(radio buttons),一,一

94、组单选按钮允许用户在组内多个相互排他的选项组单选按钮允许用户在组内多个相互排他的选项内选择一项。内选择一项。87特制分析图3.21设置Tab Order88特制分析e)e)组合框组合框Combo BoxCombo Box 将将组组合合框框拖拖至至对对话话框框中中后后,按按向向下下箭箭头头,显显示示运运行行时时下下拉拉组组合合框框的的大大小小,调调整整到到合合适适大大小小。组组合合框框的的属属性性对对话话框框比比其其它它控控件件多多一一个个DataData页页面面,用用于于输输入入组组合合框框中中的的数数据据项项,每每一一行行是是一一项项,输输完完一一项按项按Ctrl+EnterCtrl+Ent

95、er键换行。键换行。 f)f)列表框列表框List BoxList Box 在对话框编辑器中只能设置列表框大小、位置和在对话框编辑器中只能设置列表框大小、位置和IDID,数据的初始化需要通过编程实现。一般在拥有列表框数据的初始化需要通过编程实现。一般在拥有列表框控件的对话框的控件的对话框的OnInitDialogOnInitDialog函数中,调用函数中,调用CListBox:AddString(CListBox:AddString(无序无序) )或或CListBox:InsertString(CListBox:InsertString(有序有序) )插入字符串。插入字符串。 89特制分析g)

96、g)测试对话框测试对话框 当所有控件都布置好并定义属性后,当所有控件都布置好并定义属性后,可以选择对话框工具栏上的测试按钮,可以选择对话框工具栏上的测试按钮,测试对话框工作情况,必要的话做适当测试对话框工作情况,必要的话做适当调整。调整。 90特制分析3.4.2 3.4.2 将对话框与程序连结将对话框与程序连结 1.1.对话框类及数据成员的定义对话框类及数据成员的定义 a)a)创建对话框类创建对话框类 对话框资源建立好后,在对话框中右击鼠标,对话框资源建立好后,在对话框中右击鼠标,选择选择ClassWizardClassWizard菜单项,会出现提示框,说明菜单项,会出现提示框,说明新建的对话

97、框资源是新资源,是否需要建立一新建的对话框资源是新资源,是否需要建立一个新类或选择一个已存在的类。个新类或选择一个已存在的类。若选择新类,出现图3.23示的New class对话框 。 选定后,在WorkSpace中可看到新增加的类,自动生成的StudentDlg.h头文件和StudentDlg.cpp源文件。91特制分析图3.23新建类对话框 92特制分析b)b)增加数据成员增加数据成员 要使对话框能与程序通讯,还需给对话框类增加数据成员,以保存各控件的初始值,并从控件读取数据。与控件对应的数据成员可以是变量或控件类型,如表3.9所示。分类变量成员控件成员用途 用于控件初始化或保存控件值,成

98、员变量可以是任何数据类型,如编辑框的值可以是整型或字符串,复选框的值是BOOL类型控件成员变量是相应控件类的对象,可以调用控件类的成员函数,如列表框,定义一个CListBox类型变量,可以通过控件使用类的成员函数以初始化列表框说明一个控件可以定义其中一种也可定义两种表3.9对话框与控件对应的变量或控件数据成员93特制分析在在ClassWizardClassWizard的的Member Member VariablesVariables页页面面,选选择择对对话话框框类类,在在Control Control IDsIDs中中列列出出了了对对话话框框中中所所有有控控件件IDID,如如图图3.243.

99、24,选选择择某某个个IDID,按按Add Add VariableVariable按按钮钮,弹弹出出Add Add Member Member VariableVariable对对话话框框,可可输输入入成成员员名名,在在CategoryCategory中中选选择择值值(value)(value)变变量量或或控控件件(controls)(controls)类类型型,在在Variable Variable typetype列列表表框框中中,若若是是ValueValue类类,选选择择变变量量数数据据类类型型,若若是是ControlsControls,选选择择控控件件类类,按按OKOK,成员添加成功

100、。成员添加成功。设计不同的菜单命令响应函数,可以用对话框成员变量更新文档数设计不同的菜单命令响应函数,可以用对话框成员变量更新文档数据;也可以用文档数据为对话框数据成员赋值,再显示对话框据;也可以用文档数据为对话框数据成员赋值,再显示对话框94特制分析图图3.243.24为对话框添加数据成员为对话框添加数据成员 95特制分析2.对话框的显示对话框的显示 模态对话框模态对话框 调用其调用其DoModal()DoModal()函数显示,函数显示, 按按OKOK或或CancelCancel按钮关闭对话框按钮关闭对话框非模态对话框非模态对话框 调用调用Create()Create()函数创建并显示对话

101、框函数创建并显示对话框 用用DestroyWindowDestroyWindow关闭对话框。关闭对话框。3.为控件添加或修改消息响应函数为控件添加或修改消息响应函数 打开打开ClassWizardClassWizard,在,在Message MapMessage Map页面,可页面,可以为控件添加响应函数。如以为控件添加响应函数。如图图3.263.26。 96特制分析图图3.263.26为控件添加响应函数为控件添加响应函数 97特制分析图图3.27 3.27 例例3.1 3.1 新主界面新主界面98特制分析3.5.3.5.基于对话框的应用程序设计基于对话框的应用程序设计 AppWizardAp

102、pWizard提提供供了了基基于于对对话话框框(Dialog (Dialog based)based)的的应应用用程程序序框框架架, ,程程序序可可以以简简单单到到只只有有CWinAppCWinApp派派生生类类和和一一个个对对话话框框类类,对对话话框框就就是是程程序序框框架架,负负责责数数据据输输入入输输出出和和存存储储,以以及及消消息息处处理理;对对话话框框可可以以有最小化按钮,甚至可以连接一个菜单。有最小化按钮,甚至可以连接一个菜单。 基于对话框的应用程序结构简单,只要正确选基于对话框的应用程序结构简单,只要正确选择控件及定义成员变量,设计正确的算法。择控件及定义成员变量,设计正确的算法

103、。适合开发数据不多,功能简单的程序。适合开发数据不多,功能简单的程序。 99特制分析3.6.3.6.文本和图形输出文本和图形输出 WindowsWindows设备描述表设备描述表DC(device contexts)DC(device contexts),是对各种不,是对各种不同设备的抽象,应用程序只要向同设备的抽象,应用程序只要向DCDC输出,由输出,由DCDC负责处理不同负责处理不同设备的差异。设备的差异。 DCDC是一个数据结构,描述了图形设备接口是一个数据结构,描述了图形设备接口GDIGDI进行输出进行输出所需要的信息,包括颜色,填充方式,画笔宽度等。所需要的信息,包括颜色,填充方式,

104、画笔宽度等。在在WindowsWindows中,中,DCDC允许应用程序使用输出设备,允许应用程序使用输出设备,DCDC在应在应用程序、设备驱动程序、与输出设备之间建立联系,用程序、设备驱动程序、与输出设备之间建立联系,并提供绘图信息。并提供绘图信息。 在在MFCMFC中,中,CDCCDC类封装了设备描述表类封装了设备描述表DCDC,该类的核心是,该类的核心是 m_hDCm_hDC,代表一个指向窗口,代表一个指向窗口DCDC的句柄。的句柄。 100特制分析1.CDC类及其派生类类及其派生类 CDCCDC类派生自类派生自CObjectCObject,它具有,它具有CObjectCObject类的

105、共同特性,如类的共同特性,如可以动态创建,可进行序列化操作。可以动态创建,可进行序列化操作。CDC派生类派生类说明说明CClientDC代表窗口客户区代表窗口客户区CPaintDC代表客户区的无效区域代表客户区的无效区域(需要重画的区域需要重画的区域),如被对话框遮挡的部分,如被对话框遮挡的部分CWindowsDC 窗口区窗口区(包括客户区和非客户区包括客户区和非客户区)CMetafileDC面向备忘文件的面向备忘文件的DC,为重绘图记录一系,为重绘图记录一系列绘图命令列绘图命令101特制分析(a).设置颜色设置颜色 windowswindows使用一个使用一个3232位无符号整型值来表示图形

106、和文本的颜色,位无符号整型值来表示图形和文本的颜色,其数据类型为其数据类型为COLORREFCOLORREF,它包含,它包含4 4个字节,第一字节未使个字节,第一字节未使用,不要改变其值;后面三个字节分别表示红、绿、蓝三用,不要改变其值;后面三个字节分别表示红、绿、蓝三种基本色的成分,每一种颜色用一个种基本色的成分,每一种颜色用一个0-2550-255之间的数字表之间的数字表示。示。COLORREFunusedBlue GreenRed设备描述表最常见的使用是在视图类的设备描述表最常见的使用是在视图类的OnDraw函数中进函数中进行图形和文本输出行图形和文本输出2.CDC类的使用类的使用102

107、特制分析宏RGB定义颜色值宏宏RGB定义一个颜色的三种基本色成分,返回定义一个颜色的三种基本色成分,返回COLORREF值值GetRValue返回一个返回一个COLORREF中红色分量中红色分量GetGValue返回一个返回一个COLORREF中绿色分量中绿色分量GetBValue返回一个返回一个COLORREF中蓝色分量中蓝色分量例:例:COLORREFcolor=RGB(125,125,125);CBrushbrush(color);TRACE(“TheRedcomponentofthebrushis%dn”,GetRValue(color);103特制分析CDCCDC的像素操作函数的像素

108、操作函数SetPixel()SetPixel()和和GetPixel()GetPixel(),使图形设置精确到像素使图形设置精确到像素(b).像素操作像素操作voidCExView:OnDraw(CDC*pDC)pDC-SetPixel(CPoint(100,100),RGB(255,0,0);typedefstructtagPOINTLONGx;LONGy;POINT;CPoint是是MFC中表示点的类,派生自中表示点的类,派生自POINT结构,封装了对结构,封装了对CPoint和和POINT进行操作的函数,主要是一些运算符函数。进行操作的函数,主要是一些运算符函数。 104特制分析(c).

109、绘制直线及其它图形绘制直线及其它图形CDCCDC用于图形操作的成员函数用于图形操作的成员函数MoveTo MoveTo 从当前点移至参数点从当前点移至参数点LineTo LineTo 从当前点画直线至参数点从当前点画直线至参数点Polyline Polyline 用用CPointCPoint对象的数组作参数,对象的数组作参数, 将数组中各点依次连直线,将数组中各点依次连直线,Rectangle Rectangle 画长方形画长方形Ellipse Ellipse 以长方形为界,画一个椭圆以长方形为界,画一个椭圆Polygon Polygon 以数组中点为顶点,画一个以数组中点为顶点,画一个 多边

110、形多边形105特制分析(d).文本输出文本输出 文本输出包含两部分工作,分别用两组函数实现。文本输出包含两部分工作,分别用两组函数实现。设置文本特性设置文本特性 如字体,颜色,对齐方式等如字体,颜色,对齐方式等输出文本输出文本SetTextColorGetTextColor控制输出文本的颜色控制输出文本的颜色SetBkModeGetBkMode控制文本是否透明显示,如果是不透明方式,控制文本是否透明显示,如果是不透明方式,文本周围用背景色填充文本周围用背景色填充SetBkColorGetBkColor控制文本背景颜色,当文本是不透明显示时控制文本背景颜色,当文本是不透明显示时才填充背景才填充背

111、景SetTextAlignGetTextAlign控制对齐方式控制对齐方式 TextOut用当前选定的字体、颜色和对齐方式,在参用当前选定的字体、颜色和对齐方式,在参数指定位置显示字符串数指定位置显示字符串DrawText在一个指定矩形区域内显示格式化字符串在一个指定矩形区域内显示格式化字符串106特制分析3.使用使用GDI对象对象 GDIGDI对象类对象类CGdiObjectCGdiObject派生派生CObjectCObject,是画笔、画刷、字体、,是画笔、画刷、字体、位图等位图等GDIGDI对象的基类,其派生类封装了各种绘图工具。对象的基类,其派生类封装了各种绘图工具。GDI对象对象用

112、途用途默认值默认值Cpen画笔类,画直线、曲线和各种图形边框,画笔类,画直线、曲线和各种图形边框,可改变颜色,线型,线宽可改变颜色,线型,线宽黑实线,宽一个像黑实线,宽一个像素素CBrush画刷类,填充各种图形的内部,可改变画刷类,填充各种图形的内部,可改变颜色和填充图案颜色和填充图案白色画刷白色画刷CFont字体类,改变字体的属性字体类,改变字体的属性系统字体系统字体CBitmap位图类,嵌入或操作位图位图类,嵌入或操作位图无无CRgn区域类,操作由椭圆或矩形组合的各种区域类,操作由椭圆或矩形组合的各种区域,常与区域,常与CDC的剪切函数配合使用的剪切函数配合使用无无CPalette调色板类

113、,封装了调色板类,封装了Windows调色板,允调色板,允许创建调色板对象,修改其属性许创建调色板对象,修改其属性无无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操作的成员函数,可以修改相关属性,如SetT

114、extColor();也可选择自定义的GDI对象。108特制分析Windows预定义了标准预定义了标准GDI对象,供系统和程序使用,称对象,供系统和程序使用,称为为备用备用GDI对象对象,可为多个程序同时使用。备用对象包括可为多个程序同时使用。备用对象包括最常用的字体、画笔、画刷等最常用的字体、画笔、画刷等,用函数用函数CDC:SelectStockObject选择备用对象,并返回原值。选择备用对象,并返回原值。CPenpen1;/自定义画笔自定义画笔pen1.CreatePen(PS_SOLID,0,RGB(255,0,0);CPen*poldPen=pDC-SelectObject(&pe

115、n1);/选择新画笔,返回并保存原值选择新画笔,返回并保存原值CBrush*poldBrush=pDC-SelectStockObject(NULL_BRUSH);/选择备用空画刷选择备用空画刷CRectrect1(0,0,400,400);/定义矩形定义矩形pDC-Rectangle(&rect1);/画出空心矩形画出空心矩形pDC-SelectObject(poldBrush);/恢复原值恢复原值109特制分析表表3.15备用备用GDI对象对象GDI对象预定义值字体ANSI_FIXED_FONT ANSI_VAR_FONT DEVICE_DEFAULT_FONT OEM_FIXED_FON

116、T SYSTEM_FONT画笔BLACK_PEN WHITE_PEN NULL_PEN画刷BLACK_BRUSH DKGRAY_BRUSH GRAY_BRUSHHOLLOW_BRUSH LTGRAY_BRUSH WHITE_BRUSHNULL_BRUSH(透明画刷) 110特制分析c)画笔画笔CPen使用使用 画笔有线型、线宽、颜色三种属性,在构造画笔有线型、线宽、颜色三种属性,在构造画笔时需画笔时需 提供它们的信息。提供它们的信息。 线型有七种,分别为:线型有七种,分别为:实线实线PS_SOLIDPS_SOLID点线点线PS_DOTPS_DOT虚线虚线PS_DASHPS_DASH点画线点画线

117、PS_DASHDOTPS_DASHDOT双点画线双点画线PS_DASHDOTDOTPS_DASHDOTDOT空空画笔画笔PS_NULLPS_NULL画图形内框画图形内框PS_INSIDEFRAMEPS_INSIDEFRAME111特制分析d)画刷画刷CBrush使用使用 画刷用于填充区域,有三类画刷。根据画刷类型画刷用于填充区域,有三类画刷。根据画刷类型不同,不同,CBrushCBrush有多个构造函数。有多个构造函数。画刷画刷参数参数创建画刷方法创建画刷方法实心实心画刷画刷COLORREF值值CBrush brush;Brush.CreateSolidBrush(RGB(dd,dd,dd)阴

118、影阴影填充填充画刷画刷HS_HORIZONTALHS_VERTICALHS_FDIAGONALHS_BDIAGONALHS_CROSSHS_DIAGCROSSCBrush brush;Brush.CreateHatchBrush(HS_CROSS,RGB(dd,dd,dd)位图位图画刷画刷CBitmap指针指针CBitmap bitmap;bitmap.LoadBitmap(IDB_BITMAP1);CBrush brush;Brush.CreatePatternBrush(&bitmap)112特制分析e)区域使用区域使用 CRgnCRgn类封装了窗口的类封装了窗口的GDIGDI区域,该区域

119、可以是由一区域,该区域可以是由一个或多个椭圆形或多边形合成的,通常将个或多个椭圆形或多边形合成的,通常将CRgnCRgn的成员函数与的成员函数与CDCCDC的剪切成员函数结合使用,实的剪切成员函数结合使用,实现多种图形显示方式。现多种图形显示方式。 113特制分析 面向对象技术有一个术语面向对象技术有一个术语永久保存永久保存(Persistence),(Persistence),即保存应用程序的各种信息。即保存应用程序的各种信息。MFCMFC支支持两种永久保存:序列化和应用程序状态保存。持两种永久保存:序列化和应用程序状态保存。 序列化序列化(Serialization)是指程序的数据保存到是

120、指程序的数据保存到文件或从文件读出。应用程序框架提供了完成序列文件或从文件读出。应用程序框架提供了完成序列化的大多数结构,程序开发人员只需要完成针对特化的大多数结构,程序开发人员只需要完成针对特定应用的数据序列化代码。定应用的数据序列化代码。 应用程序运行状态保存通过注册表完成。应用程序运行状态保存通过注册表完成。3.7.文档的保存文档的保存114特制分析3.7.1.3.7.1.文档序列化文档序列化 1.序列化序列化 序列化是将数据从应用程序写入数据文件或从数据序列化是将数据从应用程序写入数据文件或从数据文件读入应用程序的过程。序列化在文档文件读入应用程序的过程。序列化在文档/视图结视图结构中

121、完成,当用户要保存或读出数据时发生序列化构中完成,当用户要保存或读出数据时发生序列化过程,当文档数据发生变化时,序列化会提示用户过程,当文档数据发生变化时,序列化会提示用户保存数据。保存数据。序列化过程从文档类对象序列化开始,文档类可直序列化过程从文档类对象序列化开始,文档类可直接序列化普通数据,或序列化对象成员。成员对象接序列化普通数据,或序列化对象成员。成员对象各自的类完成自身数据序列化操作。各自的类完成自身数据序列化操作。 115特制分析(3)CArchive(3)CArchive为序列化提供一个上下文。为序列化提供一个上下文。 (1)CObject(1)CObject类是所有可序列化类

122、的基类,它提供了类是所有可序列化类的基类,它提供了序列化的协议和功能,只有派生自序列化的协议和功能,只有派生自CObjectCObject的类才能序的类才能序列化。列化。 (2)CDocument(2)CDocument类存储应用程序的数据类存储应用程序的数据( (数据成员和对数据成员和对象成员象成员) ) MFC中与序列化相关的类中与序列化相关的类 (4)CFile (4)CFile代表存储在磁盘介质上的文件,直接支持非代表存储在磁盘介质上的文件,直接支持非缓冲文件和二进制文件读写,其派生类支持文本文件缓冲文件和二进制文件读写,其派生类支持文本文件和内存文件。和内存文件。116特制分析读写过

123、程如下图读写过程如下图: :Serialize117特制分析2.运行时类型信息运行时类型信息从从文文件件读读入入对对象象时时,程程序序根根据据运运行行时时类类型型信信息息(Run-time (Run-time class class informationinformation即即RTTI)RTTI)来来判判断断要要读读入入的的对对象象类类型型,从从而而动动态态地地构构造造( (重重构构) )恰恰当当的的对象。对象。每创建一个新的对象,都记录必要的类型信息,每创建一个新的对象,都记录必要的类型信息,产生一个类型信息结构,构成运行时类型信息表产生一个类型信息结构,构成运行时类型信息表(链表链表)

124、,以便运行时进行类型检查。类型信息由,以便运行时进行类型检查。类型信息由CRuntimeClass结构结构记录。记录。118特制分析structCRuntimeClassLPCSTRm_lpszClassName;/类名类名intm_nObjectSize;UINTm_wSchema;/版本号版本号CObject*(PASCAL*m_pfnCreateObject)();/函数指针,指向该类的缺省构造函数函数指针,指向该类的缺省构造函数CRuntimeClass*m_pBaseClass;/指向基类的运行时信息结构指向基类的运行时信息结构staticCRuntimeClass*pFirstCl

125、ass;/链表头指针链表头指针,静态成员,只有一个,静态成员,只有一个 CRuntimeClass*m_pNextClass;/指向链表下一对象指向链表下一对象;CRuntimeClass119特制分析作作为为可可序序列列化化类类的的公公共共基基类类,CObject定定义义中中包包含含下下面面的的代码:代码: classCObjectpublic:virtualCRuntimeClass*GetRuntimeClass()const; /返回当前类的运行时信息结构指针返回当前类的运行时信息结构指针staticCRuntimeClassclassObject;/静静态数据成数据成员,新创建类的信

126、息存储在此新创建类的信息存储在此;CRuntimeClass*CObject:GetRuntimeClass()constreturn&CObject:classObject;CRuntimeClass*CRuntimeCalss:pFirstClass=NULL;/初始化存放运行时信息的链表为空初始化存放运行时信息的链表为空 120特制分析说明:说明:CObject派生类在构造对象时,类型信息被记录在派生类在构造对象时,类型信息被记录在其其classobject结构成员中,程序中构造的全部对结构成员中,程序中构造的全部对象通过结构体的象通过结构体的m_pNextClass指针构成一个类指针构

127、成一个类型信息表链表相互关联。型信息表链表相互关联。将程序将程序(文档文档)数据保存至文件时,运行时类型信息数据保存至文件时,运行时类型信息也被写入文件;从文件读入对象时,程序根据运也被写入文件;从文件读入对象时,程序根据运行时类型信息表中的记录判断要读入的对象类型,行时类型信息表中的记录判断要读入的对象类型,调用其缺省构造函数,动态地重构对象。调用其缺省构造函数,动态地重构对象。121特制分析3.与序列化相关的命令与序列化相关的命令选项选项响应方式响应方式调用的虚函数调用的虚函数SDIMDIFile|New1.检查当前文档是否检查当前文档是否被修改,若是,提示被修改,若是,提示用户保存当前文

128、档用户保存当前文档2.清空旧文档清空旧文档3.创建新文档创建新文档CDocument:OnNewDocument重定义这个函数进行文档初始化,重定义这个函数进行文档初始化,如动态申请对象如动态申请对象CDocument:DeleteContents重定重定义这个函数删除动态分配的对象义这个函数删除动态分配的对象创建新文档及视图创建新文档及视图CDocument:OnNewDocumentCDocument:DeleteContentsFile|Open1.检查当前文档是否检查当前文档是否被修改,若是,提示被修改,若是,提示用户保存当前文档用户保存当前文档2.显示打开文件对话显示打开文件对话框,

129、接受用户输入框,接受用户输入3. 清空旧文档,反序清空旧文档,反序列化读入新文档列化读入新文档CDocument:OnOpenDocument在这个函数中进行文档初始化在这个函数中进行文档初始化CDocument:DeleteContents重定重定义这个函数删除动态分配的对象义这个函数删除动态分配的对象CDocument:Serialize读入文档读入文档数据数据创建新文档及视图创建新文档及视图CDocument:OnNewDocumentCDocument:OnOpenDocumentCDocument:Serial-ize读入读入文档数据文档数据File|Save保存文档数据和对象保存文

130、档数据和对象CDocument:Serialize保存数据保存数据CDocument:SerializeFile|Colse1.检查当前文档是否检查当前文档是否被修改,若是,提示被修改,若是,提示用户保存当前文档用户保存当前文档2.清空文档内容清空文档内容因为因为SDI有且只有一个文档,无有且只有一个文档,无此命令此命令CDocument:IsModifiedCDocument:DeleteContents文档类的析构函数清除文档文档类的析构函数清除文档对象对象122特制分析4.文档类的序列化文档类的序列化 如果创建的应用程序如果创建的应用程序不使用数据库不使用数据库,AppWizardApp

131、Wizard为文档类自为文档类自动生成动生成SerializeSerialize函数的框架,由开发人员完成具体的序函数的框架,由开发人员完成具体的序列化代码。列化代码。 void CMyDoc:Serialize ( CArchive & ar) if(ar.IsStoring( )/TODO: add storing code here else /TODO: add loading code here 123特制分析a)将类的基类定义为将类的基类定义为CObject或其派生类;或其派生类;b)在类的声明中定义一个缺省构造函数在类的声明中定义一个缺省构造函数(不带任何参数不带任何参数);5.

132、 5. 创建一个可序列化类创建一个可序列化类d)在类的定义文件在类的定义文件(cpp文件文件)中,添加中,添加IMPLEMENT_SERIAL宏,它需要三个参数,分别是需要序列化的类名,其基类宏,它需要三个参数,分别是需要序列化的类名,其基类名及版本号名及版本号;e)重定义重定义Serialize函数,其参数是一个函数,其参数是一个CArchive对象的引用。对象的引用。 c)在类的声明中,添加在类的声明中,添加DECLARE_SERIAL宏,以类名为宏,以类名为唯唯一参数;一参数;只有派生自只有派生自CObjectCObject且重载了且重载了SerializeSerialize函数的类才能

133、函数的类才能实现序列化,实现序列化,MFCMFC定义了两个宏支持序列化,它们是定义了两个宏支持序列化,它们是DECLARE_SERIALDECLARE_SERIAL和和IMPLEMENT_SERIALIMPLEMENT_SERIAL124特制分析6.类的序列化类的序列化当数据为文档类的对象成员时当数据为文档类的对象成员时/Ex3_1Doc.hclassCEx3_1Doc:publicCDocumentCStudentm_Student;/对象成员对象成员;/Ex3_1Doc.cppvoidCEx3_1Doc:Serialize(CArchive&ar) m_Student.Serialize(

134、ar);/调用对象的序列化函数调用对象的序列化函数有了可序列化类,就可作为文档的数据参与序列化有了可序列化类,就可作为文档的数据参与序列化. .若数据是指向对象的指针,参看若数据是指向对象的指针,参看下例下例。125特制分析classCEx3_1Doc:publicCDocumentCStudent*m_pStudent;CEx3_1Doc:CEx3_1Doc():m_pStudent(0)/对象指针初始化为对象指针初始化为0voidCEx3_1Doc:Serialize(CArchive&ar)if(ar.IsStoring()arm_pStudent;当然还要修改文档类的当然还要修改文档类

135、的 OnNewDocment 和和DeleteContents函数。函数。126特制分析BOOLCEx3_1Doc:OnNewDocument()if(!CDocument:OnNewDocument()returnFALSE;m_pStudent=newCStudent;/构造对象构造对象returnTRUE;voidCEx3_1Doc:DeleteContents()deletem_pStudent;/删除对象删除对象m_pStudent=0;CDocument:DeleteContents();调用基类的同调用基类的同名函数完成其名函数完成其它功能它功能返回返回注注127特制分析7.文件

136、对话框中文件类型确定文件对话框中文件类型确定 在在WordWord字处理软件中,打开文件对话框,会显示字处理软件中,打开文件对话框,会显示缺省的文件类型缺省的文件类型.doc.doc。使用。使用MFCMFC开发的应用程序,可以开发的应用程序,可以确定其缺省文件类型,通过编辑字符串资源实现。确定其缺省文件类型,通过编辑字符串资源实现。 在在WorkSpace中选择中选择ResourceView,打开,打开StringTable资源,选择资源,选择ID为为IDR_MAINFRAME的字符串,双的字符串,双击它,打开击它,打开StringProperties对话框,在对话框,在Caption编辑编辑

137、框中显示下列信息:框中显示下列信息:Ex3_1nnEx3_1nnnEx31.DocumentnEx3_1Document每个字符串由每个字符串由n分隔,分隔,n后无字符表示字符串为空。后无字符表示字符串为空。七个字符串的含义七个字符串的含义128特制分析七个字符串含义顺序如下:Ex3_1 应用程序主窗口标题栏显示内容,仅SDI需要n NULL 文档名,作为新建文档的缺省名,如Ex3_11,后一个1为产生的序列号。此串为空,使新文档窗口标题栏显示”无标题”nEx3_1 只与MDI有关,有多个文档模板时的文档模板名n NULL 显示在文件对话框文件类型列表框中的信息如” 学生信息文件(*.stu)

138、”n NULL 缺省的文件后缀,如“*.stu”,上两项现在未定义nEx31.Document 注册表中使用的文件类型子项名nEx3_1 Document 注册表中使用的文件类型名 其中第四、五个字符串与文件类型有关。例Ex3_1中对字符串资源修改为行尾的字符串后,打开文件对话框会自动显示文件类型*.stu。 返回返回129特制分析3.7.2.3.7.2.注册表注册表 1. 注册表数据库的组织注册表数据库的组织 注册表数据库是一个有关配置信息的层状数注册表数据库是一个有关配置信息的层状数据库,层状结构的根部是预定义的原始项据库,层状结构的根部是预定义的原始项(Predefined Key)(P

139、redefined Key),提供注册表的入口,提供注册表的入口(Entry)(Entry),这些原始项包含项,这些原始项包含项(Key)(Key)和子项和子项(Subkeys)(Subkeys),子项还可包含子项或值,子项还可包含子项或值(Value)(Value)。 程序的运行状态永久保存在注册表中。(这部分内容作程序的运行状态永久保存在注册表中。(这部分内容作为自学,不作为课堂内容。)为自学,不作为课堂内容。)130特制分析2.注册表编辑器注册表编辑器 注注册册表表编编辑辑器器提提供供一一个个查查看看和和编编辑辑注注册册表表的的可可视视化化界界面面。运行运行RegEdit.exe,Reg

140、Edit.exe,打开注册表编辑器。打开注册表编辑器。警告警告: :错误地编辑注册表可能会严重损坏系统错误地编辑注册表可能会严重损坏系统, ,备份数据备份数据. .131特制分析3.注册表入口文件注册表入口文件注册表入口文件是包含注册表数据库数据的文本文件,当编辑注册表时,注册表编辑器使用注册表入口文件中的信息增加或更新注册表,但不能用来从数据库删除信息。4. 在程序中更新注册表在程序中更新注册表 在程序中更新注册表可以记录诸如窗口大小和位置及用户选项等信息,一般通过CWinApp的成员函数完成。在CWinApp派生类的InitInstance函数中包含对SetRegistryKey函数的调用

141、。132特制分析3.8. MDI3.8. MDI应用程序开发应用程序开发MDIMDI允许在程序框架窗口内打开多个文档子窗口,拥有允许在程序框架窗口内打开多个文档子窗口,拥有一个一个WindowWindow菜单,提供子窗口切换、菜单,提供子窗口切换、tiletile、cascadecascade等功能。等功能。 MDI应用包含下列类应用包含下列类CMainFrame MDI应用的主框架窗口类应用的主框架窗口类CChildFrame MDI子窗口的框架子窗口的框架CExp3_3App 派生自派生自CWinApp,代表应用程序本身,代表应用程序本身CExp3_3Doc 派生自派生自CDocumant

142、,文档类,文档类CExp3_3View 派生自派生自CScrollView,视图类,视图类CFrameWndCMainFrameCMDIChildWndCMDIFrameWndCChildFrame133特制分析1. 窗口拆分窗口拆分 窗口可以实现动态拆分和静态拆分窗口可以实现动态拆分和静态拆分动态拆分动态拆分: :是对一个视图进行分隔,各个分隔窗是对一个视图进行分隔,各个分隔窗口内容相同,但各自独立控制视野范围。口内容相同,但各自独立控制视野范围。AppWizardAppWizard支持动态拆分。支持动态拆分。参看例参看例Ex3_3动态部分动态部分.静态拆分静态拆分: 窗口个数是固定的,各窗

143、口可以显示窗口个数是固定的,各窗口可以显示不同的视图对象,每个窗口的活动完全独立,有不同的视图对象,每个窗口的活动完全独立,有属于自己的水平和垂直滚动条属于自己的水平和垂直滚动条.静态拆分可修改动态拆分代码实现。参看例静态拆分可修改动态拆分代码实现。参看例Ex3_3静态静态部分部分134特制分析2.多文档模板应用多文档模板应用 a)a)在在New ProjectNew Project页面上,选择页面上,选择MFC AppWizard(exe)MFC AppWizard(exe)类型,类型,工程名为工程名为Ex3_3Ex3_3; b) b) 在在AppWizard-Step 1AppWizard

144、-Step 1,选择,选择Multiple DocumentsMultiple Documents应用应用类型,并选中类型,并选中Document/View architecture support Document/View architecture support 复选复选框;框;Step 2, 3Step 2, 3接受缺省值,在接受缺省值,在Step 4Step 4中,按中,按AdvancedAdvanced按钮,按钮,打开打开Advanced OptionsAdvanced Options对话框,填写如对话框,填写如图图3.343.34示的示的Document template str

145、ingsDocument template strings页面,并在页面,并在Window StylesWindow Styles页面页面图图3.353.35,选中,选中Use Split WindowUse Split Window复选框,关闭复选框,关闭AdvancedAdvanced对话对话框;框;例例Ex3_3 Ex3_3 MDIMDI应用,使其支持窗口动态拆分。应用,使其支持窗口动态拆分。135特制分析图图3.343.34决定文件类型窗口决定文件类型窗口 136特制分析图图3.353.35使用拆分窗口选项使用拆分窗口选项 137特制分析c) Step 5c) Step 5接受缺省值,

146、接受缺省值,Step 6Step 6中,确定各类基类时将中,确定各类基类时将CEx3_3ViewCEx3_3View的基类改为的基类改为CScrollViewCScrollView,当文档内容超出视图,当文档内容超出视图范围时自动实现滚动;按范围时自动实现滚动;按FinishFinish按钮,结束按钮,结束AppWizardAppWizard。MDI中每个子窗口都应是可拆分的,子框架包含中每个子窗口都应是可拆分的,子框架包含拆分窗口拆分窗口类对象成员类对象成员及拆分窗口的操作。及拆分窗口的操作。为了在视图窗口显示内容,在视图的为了在视图窗口显示内容,在视图的OnDraw函数中添函数中添加一个画

147、图操作:加一个画图操作:void CEx3_3View:OnDraw(CDC* pDC) CEx3_3Doc* pDoc = GetDocument();ASSERT_VALID(pDoc);pDC-Ellipse(0,0,200,100); 138特制分析classCChildFrame:publicCMDIChildWnd.protected:CSplitterWndm_wndSplitter;/拆分窗口类对象拆分窗口类对象public:virtualBOOLOnCreateClient(LPCREATESTRUCTlpcs,CCreateContext*pContext);BOOLCCh

148、ildFrame:OnCreateClient(LPCREATESTRUCT/*lpcs*/,CCreateContext*pContext)/将窗口拆分为两行两列的子窗口将窗口拆分为两行两列的子窗口returnm_wndSplitter.Create(this,2,2,CSize(10,10),pContext);返回返回139特制分析3. 多个文档模板应用多个文档模板应用 MDIMDI允许多个文档模板存在,在不同窗口显示不同文档内容允许多个文档模板存在,在不同窗口显示不同文档内容。例例Ex3_4Ex3_4在文档类存储一个数组,三个视图分别以文本、条形在文档类存储一个数组,三个视图分别以文本

149、、条形图和曲线三种形式显示文档内容。图和曲线三种形式显示文档内容。 a)与与例例Ex3_3相相同同的的方方式式创创建建工工程程,在在Step4的的Advanced对对话话框框中中,不不选选中中UseSplitWindow,不不使使用用拆拆分分窗窗口,文件类型相应修改为口,文件类型相应修改为Ex3_4。b)为工程增加两个视图类为工程增加两个视图类,CBarViewCBarView和和CCurveViewCCurveView,对,对应应条形图和曲线,条形图和曲线,它们的基类都是它们的基类都是CViewCView;修改它们的;修改它们的OnDrawOnDraw函数。这两个函数代码见实践教材。函数。这

150、两个函数代码见实践教材。 140特制分析工程主视图显示文本,修改其工程主视图显示文本,修改其OnDraw函数,输出文本:函数,输出文本:voidCEx3_4View:OnDraw(CDC*pDC)CEx3_4Doc*pDoc=GetDocument();/取文档指针取文档指针ASSERT_VALID(pDoc);TEXTMETRICtm;/ 存储字体信息的结构体存储字体信息的结构体 intx,y,cy,i;charsz20;pDC-GetTextMetrics(&tm);/ 获取当前字体信息获取当前字体信息 cy=tm.tmHeight;pDC-SetTextColor(RGB(255,0,0

151、);/redtextfor(x=5,y=5,i=0;iarri);/格式化输出格式化输出pDC-TextOut(x,y,sz,lstrlen(sz);141特制分析 d)为新文档模板创建资源为新文档模板创建资源,可以为新窗口的定义菜,可以为新窗口的定义菜单和字符串资源,其中字符串资源尤为重要,因单和字符串资源,其中字符串资源尤为重要,因为在新建文档时要选择文档类型,必须为新文档为在新建文档时要选择文档类型,必须为新文档命名。命名。 详细信息详细信息c) 添加文档模板添加文档模板。在。在theApp.InitInstance()中中AppWizard产生主视图文档模板,再添加两产生主视图文档模板

152、,再添加两个新文档模板,在个新文档模板,在Ex3_3.cpp中包含两个新增中包含两个新增视图类的头文件。视图类的头文件。代码代码142特制分析BOOL CEx3_4App:InitInstance() CMultiDocTemplate* pDocTemplate;pDocTemplate = new CMultiDocTemplate(IDR_EX3_4TYPE,RUNTIME_CLASS(CEx3_4Doc),RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CEx3_4View);AddDocTemplate( pDocTemplate);pDocTem

153、plate = new CMultiDocTemplate(IDR_BAR_TYPE, /要创建新资源要创建新资源RUNTIME_CLASS(CEx3_4Doc),RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CBarView);AddDocTemplate( pDocTemplate); 返回返回143特制分析 打开字符串编辑器,在字符串表中右击鼠标,在打开字符串编辑器,在字符串表中右击鼠标,在弹出式菜单中选择弹出式菜单中选择New StringNew String命令,编辑如下两个命令,编辑如下两个字符串资源:字符串资源:IDR_BAR_TYPEIDR

154、_BAR_TYPEnBarnBarnBarnBarnEx3_4 nEx3_4 文件文件(*.ex4)(*.ex4)n.ex4n.ex4nEx34.DocumentnEx3_4 DocumentnEx34.DocumentnEx3_4 DocumentIDR_CURVE_TYPEIDR_CURVE_TYPEnCurvenCurvenCurvenCurvenEx3_4 nEx3_4 文件文件(*.ex4)(*.ex4)n.ex4n.ex4nEx34.DocumentnEx3_4 DocumentnEx34.DocumentnEx3_4 Document文档模板名文档模板名文件后缀文件后缀返回返回注

155、注144特制分析 4. 多文档模板应用分类多文档模板应用分类 例例Ex3_3Ex3_3只有一个文档模板,只有一个文档模板,但在静态拆分窗口中可显示不同视图,但在静态拆分窗口中可显示不同视图,图示图示。在动态拆。在动态拆分窗口中可显示同一文档的不同部分,分窗口中可显示同一文档的不同部分,图示图示例例Ex3_4Ex3_4中多个文档模板使用的同一文档类,以不同方中多个文档模板使用的同一文档类,以不同方式显示文档内容;式显示文档内容;图示图示程序中也可有多个文档类,建立多个文档模板。程序中也可有多个文档类,建立多个文档模板。图示图示总之,总之,MDIMDI应用的方式非常灵活,可根据需要选择合适应用的方

156、式非常灵活,可根据需要选择合适的应用程序框架。对比的应用程序框架。对比SDISDI则相对单一:则相对单一:图示图示 e) 运行程序运行程序,由于,由于CWinApp:OnFileNew首先被调用,首先被调用,因此出现新建对话框,由用户选择文档类型,如因此出现新建对话框,由用户选择文档类型,如图图3.38,以后每次新建文档都会出现此对话框。三种文,以后每次新建文档都会出现此对话框。三种文档各打开一个的运行情况如档各打开一个的运行情况如图图3.39,每种文档打开新,每种文档打开新文档时自动生成序列号,如文档时自动生成序列号,如Bar1,Bar2,等。等。145特制分析Summary我们已经学习了我

157、们已经学习了MFC程序设计的最基本概念,包程序设计的最基本概念,包括:括:vMFC主要类主要类v应用程序框架及文档视图结构应用程序框架及文档视图结构v用户界面及对话框编程用户界面及对话框编程v图形和文本输出图形和文本输出v文档序列化文档序列化这是这是MFC的主要内容,但仅仅是一个起步,的主要内容,但仅仅是一个起步,MFC还有很多重要内容无法在短时间内涉及,有待还有很多重要内容无法在短时间内涉及,有待今后进一步的学习。有了核心内容,今后的学今后进一步的学习。有了核心内容,今后的学习就是作锦上添花的工作了。习就是作锦上添花的工作了。146特制分析图图3.383.38多文档模板应用多文档模板应用新建

158、文档提示窗口新建文档提示窗口返回返回147特制分析图图3.393.39返回返回3.1节节148特制分析在子框架内的拆分窗口中显示不同视图在子框架内的拆分窗口中显示不同视图返回返回149特制分析在子框架内的拆分窗口中显示不同在子框架内的拆分窗口中显示不同部分部分返回返回150特制分析子框架子框架文档类文档类文档文档模板模板1文档文档模板模板3视图视图1视图视图2视图视图3资源资源3资源资源2资源资源1文档模板文档模板2 MDI一个文档对多一个文档对多 视图应用说明视图应用说明151特制分析子框架子框架文档文档2视图视图1视图视图2视图视图3资源资源3资源资源2资源资源1文档模板文档模板2 文档模板文档模板3 文档模板文档模板1 文档文档3文档文档1MDI 多文档多视图多文档多视图152特制分析单文档应用单文档应用SDI框架框架(窗口框架窗口框架)资源资源(决定用户决定用户界面的显示界面的显示)文档类文档类(保存数据保存数据)视图类视图类(显示数据并显示数据并与用户交流与用户交流)单文档模板单文档模板返回返回153特制分析

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 资格认证/考试 > 自考

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号