《MFCC++讲义教程课件.ppt》由会员分享,可在线阅读,更多相关《MFCC++讲义教程课件.ppt(69页珍藏版)》请在三一办公上搜索。
1、,MFCC+教程课件,精品,海陆位置及优越性:(1)位于( 亚)洲的东部, (太平 )洋的西岸,使我国东部广大地区( 在夏季风湿润气流的影响下, 降水 ) 丰富,有利(农业)生产;(2)海陆兼备,东部地区有利与( 海外各国友好往来 ) ;西部地区(深入亚欧大陆内部 ) ,使我国陆上交通能与(中亚、西亚、欧洲)各国直接往来,便于对外( 交往和合作 ) (3)沿海有许多优良的港湾,便于发展(海洋事业) 。 我国领土面积(960万 )平方千米,仅次于(俄罗斯)、( 加拿大),居世界第三。陆上邻国14个。逆时针依次为朝鲜、( 俄罗斯)、( 蒙古 )、哈萨克斯坦、吉尔吉斯斯坦、塔吉克斯坦、阿富汗、巴基斯
2、坦、(印度)、尼泊尔、不丹、(缅甸 )、(老挝 )、越南。陆上疆界2万多千米。隔海相望的国家6个:韩国、(日本 )、菲律宾、(马来西亚 )、文莱、(印度尼西亚 )。 2、我国的人口 人口总数:2000年( 12.95 )亿。 我国人口的突出特点:人口 基数大,人口增长快。 我国人口分布特点:人口分布(不均),以黑龙江黑河云南腾冲一线为界,( 东部 )地区人口密度大,( 西部 )地区人口密度较小。(我国西部地区人口稀少,但资源丰富,在西部大开发时,应注意什么问题?西部地区具有资源优势,但自然环境相对脆弱。在目前人、地、水、土矛盾已相当尖锐的条件下,开发西部,一定要以保护环境为前提,不能先开发后再
3、治理。) 人口国 策: 实行计划生育。 内容:控制人口数量,提高人口素质 3、我国的民族 我国共有(56 )个民族,其中人口最多的是( 汉 )族,少数民族中人口最多的是( 壮 )族。 汉族分布特点:汉族的分布遍及全国各地,以 ( 中部 )和(东部)最为集中。 少数民族分布特点:主要集中在( 东北 )、( 西北 )、(西南 )。少数民族人口最多的是(壮 )族。民族分布特点:(大杂居、小聚居)。 少数民族风情: ( 蒙古 )族的那达慕大会 ( 傣族 )族的泼水节、孔雀舞, (藏族 )族的集体舞、藏历年, (朝鲜 )族的长鼓舞等。 4、我国的地形 我国地形的特点:(地形复杂多样,山区面积广大) 山区
4、在开发和保护方面应当注意哪些问题: (1)山区地面较为崎岖,(交通)不便,(基础设施)建设的难度较大。 (2)在开发利用山区时,要特别注意(生态环境建设),预防和避免山地灾害( 如崩塌、滑坡、泥石流)的发生。 我国地势特征:( 我国地势西高东低,呈阶梯状分布)。 阶梯的分界线 海拔高度 主要地形类型 主要地形区,MFCC+教程课件MFCC+教程课件精品海陆位置及优越性:(1)位于( 亚)洲的东部, (太平 )洋的西岸,使我国东部广大地区( 在夏季风湿润气流的影响下, 降水 ) 丰富,有利(农业)生产;(2)海陆兼备,东部地区有利与( 海外各国友好往来 ) ;西部地区(深入亚欧大陆内部 ) ,使
5、我国陆上交通能与(中亚、西亚、欧洲)各国直接往来,便于对外( 交往和合作 ) (3)沿海有许多优良的港湾,便于发展(海洋事业) 。 我国领土面积(960万 )平方千米,仅次于(俄罗斯)、( 加拿大),居世界第三。陆上邻国14个。逆时针依次为朝鲜、( 俄罗斯)、( 蒙古 )、哈萨克斯坦、吉尔吉斯斯坦、塔吉克斯坦、阿富汗、巴基斯坦、(印度)、尼泊尔、不丹、(缅甸 )、(老挝 )、越南。陆上疆界2万多千米。隔海相望的国家6个:韩国、(日本 )、菲律宾、(马来西亚 )、文莱、(印度尼西亚 )。 2、我国的人口 人口总数:2000年( 12.95 )亿。 我国人口的突出特点:人口 基数大,人口增长快。
6、我国人口分布特点:人口分布(不均),以黑龙江黑河云南腾冲一线为界,( 东部 )地区人口密度大,( 西部 )地区人口密度较小。(我国西部地区人口稀少,但资源丰富,在西部大开发时,应注意什么问题?西部地区具有资源优势,但自然环境相对脆弱。在目前人、地、水、土矛盾已相当尖锐的条件下,开发西部,一定要以保护环境为前提,不能先开发后再治理。) 人口国 策: 实行计划生育。 内容:控制人口数量,提高人口素质 3、我国的民族 我国共有(56 )个民族,其中人口最多的是( 汉 )族,少数民族中人口最多的是( 壮 )族。 汉族分布特点:汉族的分布遍及全国各地,以 ( 中部 )和(东部)最为集中。 少数民族分布特
7、点:主要集中在( 东北 )、( 西北 )、(西南 )。少数民族人口最多的是(壮 )族。民族分布特点:(大杂居、小聚居)。 少数民族风情: ( 蒙古 )族的那达慕大会 ( 傣族 )族的泼水节、孔雀舞, (藏族 )族的集体舞、藏历年, (朝鲜 )族的长鼓舞等。 4、我国的地形 我国地形的特点:(地形复杂多样,山区面积广大) 山区在开发和保护方面应当注意哪些问题: (1)山区地面较为崎岖,(交通)不便,(基础设施)建设的难度较大。 (2)在开发利用山区时,要特别注意(生态环境建设),预防和避免山地灾害( 如崩塌、滑坡、泥石流)的发生。 我国地势特征:( 我国地势西高东低,呈阶梯状分布)。 阶梯的分界
8、线 海拔高度 主要地形类型 主要地形区,MFCC+教程课件精品海陆位置及优越性:(1)位于( 亚,Windows API(Application Programming Interface)是Windows操作系统与应用程序之间的标准接口,它提供了上千个标准函数、宏和数据结构的定义。在使用Visual C+、Visual Basic和Delphi编程时都可以调用Windows API函数,Windows应用程序可通过调用标准Windows API函数使用系统提供的功能。Windows API函数定义在一些DLL动态链接库中,其中最主要的DLL是User32.dll、Gdi32.dll和Kern
9、el32.dll三个库文件。,1.1 关于API和SDK,Windows API(Application Progra,传统SDK编程:程序员通过调用API函数,自己动手、按部就班地实现程序各部分的功能。SDK应用程序的结构比较清晰,但程序员必须编写所有的功能代码。利用Visual C+编写一个类SDK应用程序:首先利用Win32 Application向导建立一个Windows应用程序框架,然后根据需要可以向程序项目中添加一些头文件、实现源文件和资源文件,并编写具体的程序代码。,例 编写一个名为Hello的类SDK应用程序,当单击鼠标时通过调用API函数,以弹出一个提示信息对话框。,传统SD
10、K编程:程序员通过调用API函数,自己动手、按部就班,1执行“File|New”菜单命令,在New对话框的Project页面中选择Win32 Application项目类型,输入程序名Hello。在向导第1步选择“A typital “Hello world!” application”项,单击Finish按钮。2在窗口函数WndProc()的消息处理分支switch-case结构中添加WM_LBUTTONDOWN鼠标单击消息及其处理代码: case WM_LBUTTONDOWN: MessageBox(NULL, You pressed the left button of mouse !,
11、Message,NULL); break;,1执行“File|New”菜单命令,在New对话框的Pro,SDK应用程序结构:,一个由API函数构造的Windows程序的功能由三个部分组成:入口函数、窗口函数和Windows系统。每一个程序都有一个主函数,WinMain()函数就是Windows程序的入口主函数。该函数的主要任务是完成一些初始化工作并维护一个消息循环。当消息循环结束后,就退出了WinMain()函数,也就退出了应用程序。此外,WinMain()函数还负责完成窗口的注册、创建和显示。Windows程序以窗口的形式存在,在不同窗口之间传递消息是Windows和应用程序进行交流的主要形
12、式。程序具体功能由不同的窗口函数实现。,SDK应用程序结构:一个由API函数构造的Windows程,1.2 句柄,在Windows中,用句柄(Handle)标识应用程序中不同的对象和同类对象中不同的实例,如一个具体的窗口、按钮、输出设备、画笔和文件等。通过句柄可以获得相应的对象信息。常用的句柄类型有: HWND 、 HINSTANCE 、 HDC 、HCURSOR、HICON、HMENU等。句柄常作为Windows消息和API函数的参数,在采用API方法编写Windows应用程序时要经常使用句柄。而采用MFC方法编写Windows应用程序时,由于对应的MFC类已对句柄进行了封装,大多数情况下不
13、再需要访问句柄。,1.2 句柄 在Windows中,用句柄(Handle)标,获取MFC类对象的句柄的两种方法:,通过访问类的public属性成员变量,如类CWnd的成员变量m_hWnd就是一个窗口对象的句柄。先定义一个句柄,然后调用MFC类的成员函数Attach()将句柄与一个MFC类对象联系在一起,此时的句柄就成为该MFC类对象的句柄。在退出对象作用域之前,调用成员函数Detach()将句柄和对象进行分离。如下所示:CWnd myWnd; HWND hWnd; myWnd.Attach(hWnd); . . . . . . myWnd.Detach();,获取MFC类对象的句柄的两种方法:
14、 通过访问类的public,所谓消息就是用于描述某个事件发生的信息,而事件是对于Windows的某种操作。事件和消息密切相关,事件是因,消息是果,事件产生消息,消息对应事件。所谓消息的响应,其实质就是事件的响应。消息驱动是Windows应用程序的核心,所有的外部响应(如键盘、鼠标和计时器等)都被Windows先拦截,转换成消息后再发送到应用程序中的目标对象,应用程序根据消息的具体内容进行处理。消息不仅可由Windows发出,它也可由应用程序本身或其它程序产生。Windows为每一个应用程序都维护一个或多个消息队列,发送到每个程序窗口的消息都排成一个队列。,1.3 事件和消息,所谓消息就是用于描
15、述某个事件发生的信息,而事件是对于Wind,Windows消息分为三种类型:,标准Windows消息:以WM_前缀(但不包括WM_COMMAND)开始的消息,包括鼠标消息、键盘消息和窗口消息,如WM_MOVE 、WM_PAINT等。控件通知(Control Notification)消息:对控件操作引起的消息,是控件和子窗口向其父窗口发出的WM_COMMAND通知消息。例如,当用户修改了编辑控件中的文本后,编辑控件向其父窗口发送WM_COMMAND通知消息。命令(Command)消息:由菜单项、工具栏按钮、快捷键等用户界面对象发出的WM_COMMAND消息。命令消息与其它消息不同,它可被更广泛
16、的的对象如文档、文档模板、应用程序对象、窗口和视图等处理。,Windows消息分为三种类型:标准Windows消息:以W,typedef struct tagMSG HWND hWnd; / 目标窗口句柄 UINT message;/ 消息标识 WPARAM wParam;/ 消息参数1(附加信息,16位) LPARAM lParam;/ 消息参数2(附加信息,32位) DWORD time;/ 消息发送时间 POINT pt; / 消息发送时鼠标的屏幕坐标 MSG;,消息用MSG结构表示:,typedef struct tagMSG ,例 为程序Hello添加键盘消息处理功能,判断当前按下的
17、键是不是A或a键,并给出相应的提示。,打开程序项目Hello,在文件Hello.cpp的窗口函数WndProc()的switch消息处理分支中添加键盘消息的处理代码: case WM_KEYDOWN: / 处理键盘消息 if(wParam=0 x41) / A或a键的虚键码为0 x41HMessageBox(NULL, The key you pressed is A or a !,KEYDOWN,NULL); else MessageBox(NULL, The key you pressed is not A or a !,KEYDOWN,NULL); break;,例 为程序Hello添加
18、键盘消息处理功能,判断当前按下的键,利用Windows API开发程序的用户有这样的体会,即使开发一个简单的Windows应用程序也需要对Windows的编程原理有很深刻的认识,需要手工编写冗长的代码。由于程序的出错率是随着代码长度的增加呈几何级数增长的,而且当程序长度逐渐膨胀时,调试程序会变得越来越困难。因此,传统的Windows应用程序设计需要程序员有极大的耐心和丰富的编程经验。 Visual C+捆绑了微软的基础类MFC,编程时我们就可以利用类的可重用性和可扩充性,大大降低Windows应用程序设计的难度和工作量。,2MFC的基本原理和使用方法,利用Windows API开发程序的用户有
19、这样的体会,2节要点,2.1MFC类(对应教材的第五章全部内容)2.2MFC应用程序框架2.3MFC消息管理2.4MFC宏,2节要点2.1MFC类(对应教材的第五章全部内容),一、 MFC概述(教材1节),类库是一个可以在应用程序中使用的相互关联的C+类的集合。 MFC作为一个Windows编程类库,它包含了200多个类,封装了Windows的大部分编程对象以及与它们有关的操作。虽然程序在功能上千差万别,但从本质上看,都可以分为用户界面设计、文件操作、数据库访问及多媒体使用等几部分,这些都可以通过一些类来实现。MFC提供了一个标准化的程序结构,使开发人员不必从头设计一个Windows应用程序。
20、MFC实际上是一个庞大的文件库,它由几百个执行文件和源代码文件(如H文件)组成。,2.1MFC类(对应教材的第五章全部内容),一、 MFC概述(教材1节)类库是一个可以在应用程序中使用的,在Microsoft推出Windows3.0之后,Windows操作系统受到越来越多的人的青睐。因此当时学习Windows程序设计便成为程序员的显学。但是不久,开发人员发现撰写Windows应用程序是重复、厌烦的过程,而且效率极低。因为每一个窗口都需要在窗口函数中处理大量的消息,导致出现大量的重复代码。随着C+语言的盛行,开发人员发现利用C+语言的特性来封装Windows API和Windows应用程序的开发
21、可以明显地提高程序的开发效率。于是,人们对这种新的开发模式有了强烈的需求。在这种情况下,Microsoft和其他一些大的厂商开始从事Windows框架的设计。于是,MFC就是在这种背景下诞生了。MFC英文全称是Microsoft Fundation Class Library,即微软基础类库。从其产生至今已经发展了十几个版本,表5-1显示的MFC的发展过程。,在Microsoft推出Windows3.0之后,W,MFC中的类按照功能的不同,可以分为不同的层次。图5-1显示了MFC中的所有类及类层次。,二、 MFC类库层次(教材2节),MFC中的类按照功能的不同,可以分为不同的层次。图5,MFC
22、中的数据类型与Windows SDK开发包中的数据类型多数是一致的。但也有一些数据类型是MFC独有的。表5-2列出了MFC中使用的数据类型。,其中,表格中列出的最后两个数据类型是MFC所特有的。,三、 MFC常用数据类型(教材3节),MFC中的数据类型与Windows SDK开发包中的,在MFC类库中,除了提供实现各种功能的类外,还提供了许多全局函数。如下所示:1MFC诊断函数为了调试的方便,MFC提供了多个诊断函数,如表5-3所示。,四、 MFC全局函数(教材4节),在MFC类库中,除了提供实现各种功能的类外,还提供了,MFC全局函数,2异常抛出函数 为了使程序更具有健壮性,MFC提供了多个
23、异常抛出函数,如表5-4所示。,MFC全局函数 2异常抛出函数函数名称描述AfxTh,MFC全局函数,3字符串格式和消息框函数 MFC除了提供CString类操作字符串外,还提供了两个全局函数,如表5-5所示。,4应用程序信息和管理函数 MFC提供与应用程序有关的全局函数如表5-6所示。其中,有许多函数在开发应用程序过程中经常使用。,MFC全局函数 3字符串格式和消息框函数函数名称,MFC全局函数,MFC全局函数函数名称描述AfxFreeLibrary减少已,MFC全局函数,集合类帮助函数集合类帮助函数多用于数组操作,表5-7列出了MFC提供的集合类帮助函数。,6记录字段交换函数记录字段交换函
24、数用于记录集数据与变量的交互。表5-8列出了与记录字段相关的函数。,MFC全局函数 集合类帮助函数函数名称描述Comp,MFC全局函数,MFC全局函数函数名称描述RFX_Binary传送CByte,MFC全局函数,7OLE相关函数为了支持OLE技术,MFC对OLE进行了封装,同时提供了一些全局函数用于OLE操作,如表5-9所示。,MFC全局函数7OLE相关函数函数名称描述AfxOleIn,MFC全局函数,8Internet URL解析全局函数为了获得URL字符串相关信息,MFC提供了两个全局函数,如表5-10所示。,MFC全局函数8Internet URL解析全局函数函数名,特点:1)全局函数
25、2)都是以名为Afx开头的函数那是历史遗留下的原因:long,long ago,MFC不叫MFC(在MFC1.0以前),MS开发过一个失败的产品Afx,据说是Application Framework的意思, (x是为了读起来响亮一点(微软就喜欢这样),例如ActiveX)是从上向下设计的(针对WIN API).但没有成功. 所以,有了MFC(从下向上封装api). 就是说mfc的前身是afx.但很多mfc函数保留了以前的命名方式.,特点:,二、 MFC体系结构,MFC主要组成部分:类、宏和全局函数。类是MFC中最主要的内容。MFC类是以层次结构方式组织起来的。MFC中的类分成两部分,除了一些
26、辅助类,大多数的MFC类是直接或间接从根类CObject派生而来。几乎每一个派生层次都与一具体的Windows实例相对应,如文档类、窗口类和视图类等。MFC宏主要功能:消息映射、运行时对象类型服务、诊断服务、异常处理。 MFC约定:全局函数以“Afx”为前缀,全局变量以“afx”为前缀。,二、 MFC体系结构MFC主要组成部分:类、宏和全局函数。,首先要对Windows编程概念和API函数有一定的了解,如Windows API有哪些功能和哪些常用的数据结构等。 学会抽象地把握问题,不求甚解,不要一开始学习Visual C+就试图了解整个MFC类库。从理解和使用两个方面学习MFC,理解MFC应用
27、程序的框架结构。先大体上了解MFC的概念、组成和基本约定,从简单的类入手,结合程序设计,由浅入深,循序渐进、日积月累。 编程时如果MFC某个类能完成所需要的功能,可以直接调用已有类的方法(成员函数)。否则,可以利用面向对象技术中的“继承”方法对MFC类的行为进行扩充和修改,从MFC中已有的类派生出自己需要的类。 学习MFC,另一点就是不要过分依赖于向导(Wizard)工具。向导能做许多工作,但同时掩饰了太多的细节。,三、 学习MFC的方法,首先要对Windows编程概念和API函数有一定的了解,如W,本节介绍基于MFC的应用程序开发。步骤如下:(1)单击“File/New”菜单项,打开“New
28、”窗口,选择“Projects”选项卡,如图5-2所示。,(2)在列表中选择“MFC AppWizard(exe)”选项,在“Project name”编辑框中输入工程名称,此时“OK”按钮变为可用,单击该按钮进入“MFC应用程序向导步骤1”窗口,如图5-3所示。,五、 开发MFC应用程序(教材5节),本节介绍基于MFC的应用程序开发。步骤如下:(2)在列表中选,开发MFC应用程序,(3)在“MFC应用程序向导步骤1”窗口中选择应用程序的类型。这里共有3种类型可供选择,依此为“单文档应用程序”、“多文档应用程序”和“对话框应用程序”,这里选择“Dialog based”,即创建“基于对话框的应
29、用程序”。(4)单击“Next”按钮进入“MFC应用程序向导步骤2” 窗口,如图5-4所示。,开发MFC应用程序(3)在“MFC应用程序向导步骤1”窗口中,开发MFC应用程序,(5)保留默认的设置,单击“Next”按钮进入“MFC应用程序向导步骤3” 窗口,如图所示。,开发MFC应用程序(5)保留默认的设置,单击“Next”按钮,开发MFC应用程序,(6)单击“Next”按钮进入“MFC应用程序向导步骤4”窗口,在该窗口中列出了MFC向导创建的类,如图5-6所示。,开发MFC应用程序(6)单击“Next”按钮进入“MFC应用,开发MFC应用程序,(7)单击“Finish”按钮完成工程的创建。运
30、行程序,效果如图5-7所示。,开发MFC应用程序(7)单击“Finish”按钮完成工程的创,开发MFC应用程序,使用MFC应用程序向导,没有编写一句代码,就创建出了一个对话框,这就是MFC给开发人员带来的便利。,开发MFC应用程序使用MFC应用程序向导,没有编写一句代码,,尽管每个应用程序具体实现的功能不同,但同一类程序的基本结构是相同的。因此,通常采用MFC AppWizard创建一个MFC应用程序框架。MFC不仅仅是一个类库,它还提供了一层建立在MFC类对象封装上的附加应用程序框架。应用程序框架是为了生成一般的应用程序所必需的各种软组件的集成,是类库的一种超集。类库只是一种可以嵌入到任何程
31、序中的、提供某些特定功能的类的集合。而应用程序框架却定制了应用程序的结构和源代码,其中的类对象既相互独立、又相互作用,形成一个统一的整体。,2.2 MFC应用程序框架,尽管每个应用程序具体实现的功能不同,但同一类程序的基本结构是,MFC应用程序框架提供了构建应用程序所需要的类,在程序运行时能够生成运行时类的对象,如代表应用程序对象、文档对象、视图对象和框架窗口对象。应用程序对象theApp是一个唯一的全局变量,它的主要功能是通过调用WinMain()主函数启动程序的运行。MFC应用程序框架也有一个作为程序入口点的WinMain()主函数,但在源程序中看不见该函数,它在MFC中已定义好并同应用程
32、序相链接。,1)应用程序框架中的对象,MFC应用程序框架提供了构建应用程序所需要的类,在程序运行时,MFC应用程序对象之间的关系,MFC应用程序对象之间的关系,在MFC应用程序的CWinApp派生类对象theApp是一个全局变量,代表了应用程序运行的主线程。它在程序整个运行期间都存在,它的销毁意味着运行程序的消亡。MFC应用程序启动时,首先创建应用程序对象theApp,这时将自动调用应用程序类的构造函数初始化对象theApp,然后由应用程序框架调用MFC提供的AfxWinMain()主函数。 AfxWinMain()主函数首先通过调用全局函数AfxGetApp()获取应用程序对象theApp的
33、指针pApp,然后通过pApp调用应用程序对象的有关成员函数,完成程序的初始化和启动工作,最后调用成员函数Run(),进入消息循环。程序运行后将收到WM_PAINT消息,调用OnPaint()函数绘制客户区窗口。如果Run()收到WM_QUIT消息,则结束消息循环,然后调用函数ExitInstance(),结束程序运行。,2)MFC应用程序的生与死,在MFC应用程序的CWinApp派生类对象theApp是一个,MFC应用程序运行后各函数的调用关系,InitInstance()函数是派生类唯一需要重载的函数,它负责应用程序的初始化,如初始化数据、创建文档模板、处理命令行以及显示应用程序主窗口。,
34、MFC应用程序运行后各函数的调用关系 Ini,3)常用的MFC文件和库文件,3)常用的MFC文件和库文件 文 件 名 称说,Mfc42UD.libMFCxxUD.DLL的导入函数库(U,MFC消息管理是MFC编程的一个重要内容,也是编写MFC应用程序的基础。MFC应用程序消息处理的方式与SDK应用程序有所不同。MFC应用程序框架截取了Windows向应用程序发出的消息,再确定将消息发送给哪一个对象,可以根据需要利用函数重载对消息进行处理,但不需要处理的消息将由应用程序框架自动处理。消息管理包括消息的发送和处理。对于消息发送,MFC提供了类似于API函数功能的消息发送函数,而MFC消息处理的内部
35、机制则相对复杂一些。从编程的角度出发,我们只需了解其大致的原理。,2.3 MFC消息管理,MFC消息管理是MFC编程的一个重要内容,也是编写MFC应用,MFC采用消息映射(Message Map)机制取代C/C+语言中的switch-case结构来处理消息。MFC消息映射机制包括一组消息映射宏。一条消息映射宏把一个Windows消息和其消息处理函数联结起来。MFC应用程序框架提供了消息映射功能。在类的实现源文件中用BEGIN_MESSAGE_MAP()和END_MESSAGE_MAP()宏来定义消息映射。在类定义的结尾用DECLARE_MESSAGE_MAP()宏来声明使用消息映射。,1)MF
36、C消息映射机制,MFC采用消息映射(Message Map)机制取代C/C+,BEGIN_MESSAGE_MAP(theclass, baseclass)/AFX_MSG_MAP(theclass)ON_ . . . . . . / MFC预定义的消息映射宏ON_MESSAGE(message , memberFxn) / 用户自定义的消息映射宏. . . . . . /AFX_MSG_MAPEND_MESSAGE_MAP(),MFC应用程序MESSAGE_MAP消息映射形式:,注意:特殊注解“/AFX_MSG_MAP”是ClassWizard类向导用于维护消息映射宏的标记,用户不要删除注解轻
37、易修改注解内的代码。,BEGIN_MESSAGE_MAP(theclass, ba,启动ClassWizard,添加要求的三个消息处理函数,ClassWizard将在类的实现文件中添加三个消息映射宏和消息处理函数。消息映射宏如下: BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) /AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() / 由MFC AppWizard程序向导自动生成的消息映射 ON_WM_CLOSE() / 由ClassWizard类向导添加 ON_WM_DESTROY() ON_COMMAND(ID_EDIT_COPY
38、, OnEditCopy) /AFX_MSG_MAPEND_MESSAGE_MAP(),例 利用ClassWizard为框架类添加消息WM_CLOSE、WM_DESTROY及菜单项“Edit|Copy”的消息处理函数,分析ClassWizard完成了哪些工作。,启动ClassWizard,添加要求的三个消,class CMainFrame : CFrameWndpublic: CMainFrame();protected: /AFX_MSG(CMainFrame) / 声明消息处理函数原形 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
39、 / 由程序向导自动生成 afx_msg void OnClose(); / 由ClassWizard类向导添加 afx_msg void OnDestroy(); afx_msg void OnEditCopy(); /AFX_MSG DECLARE_MESSAGE_MAP() / 声明使用消息映射宏;,ClassWizard在类的定义中声明了消息处理函数 :,class CMainFrame : CFrameWndC,发送消息到一个窗口可以采用传送(Send)或寄送(Post)方式,这两种方式之间的主要区别是消息被接收对象收到后是否立即被处理。Windows提供了三个API函数用于消息的发
40、送。函数SendMessage()用于向一个或多个窗口传送消息,该函数将调用目标窗口的窗口函数,直到目标窗口处理完收到的消息,该函数才返回。 函数PostMessage()用于向一个或多个窗口寄送消息,它把消息放在指定窗口创建的线程的消息队列中,然后不等消息处理完就返回。,2)消息的发送,发送消息到一个窗口可以采用传送(Send)或寄送(Post),函数SendDlgItemMessage()函数用于向对话框中指定的控件发送消息,直到目标控件处理完收到的消息,该函数才返回。 MFC将这三个函数封装为CWnd窗口类的成员函数,封装了目标窗口句柄,它们将向调用它的窗口对象发送或寄送消息,如pMyV
41、iew-SendMessage()的调用形式表示向pMyView所指对象发送消息。与用户输入相关的消息(如鼠标消息和键盘消息)通常是以寄送(Post)的方式发送,以便这些用户输入可以由运行较缓慢的系统进行缓冲处理。而其它消息通常是以传送(Send)的方式发送,函数SendDlgItemMessage()函数用于向对话框,由于程序逻辑设计结构的限制或不同窗口之间数据的同步,程序员需要手工自定义一些消息。例如,如果需要在特定时间间隔内通知所有数据输出窗口重新取得数据,就必须采用定时器事件来产生特定的消息。MFC允许用户自定义消息,常量WM_USER(为0 x0400)与第一个自定义消息值相对应,用
42、户必须为自己的消息定义相对于WM_USER的偏移值,利用#define语句定义自己的消息,例如:#define WM_USER1 WM_USER+0#define WM_USER2 WM_USER+1,3)手工处理消息映射,由于程序逻辑设计结构的限制或不同窗口之间数据的同步,程序员需,必须在函数返回类型前面加上afx_msg标识,如: afx_msg LRESULT memberFxn ( WPARAM wParam , LPARAM lParam);其中,参数wParam、lParam用于传递消息的两个附加信息,自定义消息处理函数的声明:,ON_MESSAGE(message, member
43、Fxn)其中,message是消息名标识,memberFxn是对应的消息处理函数。如: ON_MESSAGE(WM_MYMESSAGE, OnMyMessage),自定义消息映射宏的定义:,必须在函数返回类型前面加上afx_msg标识,如:自定义消息,1首先利用MFC AppWizardexe向导创建一个名为Rotate的应用程序。利用ClassWizard类向导为CRotateView类生成消息WM_CREATE的消息处理函数,通过设置定时器在指定的时间间隔向窗口发送WM_TIMER消息。 SetTimer(1,200,NULL); / 启动定时器2在文件RotateView.cpp开始位置
44、定义一个用户自定义消息:#define WM_MYMESSAGE WM_USER+1 利用ClassWizard为CRotateView类生成消息WM_TIME的消息处理函数:SendMessage(WM_MYMESSAGE);,例 编写一个自定义消息应用程序,程序启动后设置一个定时器,在WM_TIMER的消息处理函数中发送一个用户自定义消息,在对应的自定义消息处理函数中以动画的形式旋转显示一行文本。,1首先利用MFC AppWizardexe向导创建一个,3在类CRotateView的定义中声明自定义消息处理函数:afx_msg LRESULT OnMyMessage(WPARAM wPar
45、am, LPARAM lParam); 在文件RotateView.cpp消息映射BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间添加自定义消息映射宏:ON_MESSAGE(WM_MYMESSAGE,OnMyMyessage) 4在类CRotateView的定义中声明一个private属性、int型的成员变量m_dEscapement,它表示文本显示角度,并在类CRotateView的构造函数中初始化:m_dEscapement=0; 在文件RotateView.cpp中手工添加自定义消息处理函数实现代码,完成以动画形式旋转显示一行文本的功能。6利用ClassWizard
46、生成消息WM_DESTROY的消息处理函数,在销毁已创建的定时器:KillTimer(1);,3在类CRotateView的定义中声明自定义消息处理函数,宏就是用预处理指令#define定义一个标识符,用它来表示一个字符串或一段源代码。MFC宏作为MFC类库的一个组成部分在MFC应用程序中经常出现。MFC宏在Afxwin.h、Afx.h及Afxmsg_.h等MFC头文件中分别进行了定义。 MFC提供的宏有很多,常用的包括消息映射宏、运行时类型识别的宏、调试宏和异常宏等,下表列出了一般MFC编程时要用到的宏。,2.4 MFC宏,宏就是用预处理指令#define定义一个标识,RUNTIME_CLA
47、SS获得运行时类的CRuntimeC,运行时类型识别RTTI(Run Time Type Information)是指在程序运行时允许确定对象的类型。MFC扩充了一般C+中运行时类型识别的功能,当一个类支持MFC的运行时类型识别时,它允许程序获取对象的信息(如类名、所占存储空间大小及版本号等)和基类信息。1. 宏RUNTIME_CLASS(class_name): 返回参数class_name所指定类的静态成员变量class#class_name的指针,该指针指向一个CRuntimeClass结构。,1)有关运行时类型识别的宏,运行时类型识别RTTI(Run Time Type,2. 动态支持
48、宏DECLARE_DYNAMIC()和IMPLEMENT_DYNAMIC(): 使用动态支持宏能够使CObject派生类的对象具有基本的类型识别机能,可以通过调用成员函数CObject:IsKindOf()测试对象与给定类的关系。3. 动态创建宏DECLARE_DYNCREATE()和IMPLEMENT_DYNCREATE(): 动态创建是动态支持的一个超集,除了基本的类型识别机能,使用动态创建宏能够使CObject的派生类具有在运行时动态创建对象的功能。4. 序列化宏DECLARE_SERIAL() 和IMPLEMENT_SERIAL(),2. 动态支持宏DECLARE_DYNAMIC()和
49、IMPL,/ 在头文件MyClass.h中class CMyClass : public CObjectDECLARE_DYNAMIC(CMyClass)public:void SomeFunction(void); ;,例 定义类MyClass,使用RUNTIME_CLASS()宏的基本对象诊断功能。,/ 在头文件MyClass.h中例 定义类MyClass,/ 在实现文件MyClass.cpp中#include MyClass.hIMPLEMENT_DYNAMIC(CMyClass, CObject)void CMyClass:SomeFunction(void) CObject* pOb
50、ject=new CMyClass; if(pObject-IsKindOf(RUNTIME_CLASS(CMyClass) CMyClass* pMyObject=(CMyClass*) pObject;AfxMessageBox(MyObject is an object of the class CMyClass); else AfxMessageBox(MyObject is not an object of the class CMyClass); delete pObject;,/ 在实现文件MyClass.cpp中,2)MFC调试宏,跟踪声明和断言在查找程序设计错误时是非常有用的