Presentation is loading. Please wait.

Presentation is loading. Please wait.

第十五讲 MFC与消息处理 MFC简介 Windows编程机制 MFC应用程序框架原理 创建应用程序框架 消息及其分类 消息映射机制

Similar presentations


Presentation on theme: "第十五讲 MFC与消息处理 MFC简介 Windows编程机制 MFC应用程序框架原理 创建应用程序框架 消息及其分类 消息映射机制"— Presentation transcript:

1 第十五讲 MFC与消息处理 MFC简介 Windows编程机制 MFC应用程序框架原理 创建应用程序框架 消息及其分类 消息映射机制
ClassWizard类向导

2 MFC简介 一个优秀的编程工具往往匹配一个功能强大的类库。
与Visual C++捆绑在一起的MFC(Microsoft Foundation Class)微软基础类库是由Microsoft公司设计,封装了大量Windows编程需要使用的类的类库。

3 MFC类库 MFC作为一个Windows编程类库,它包含了200多个类,封装了Windows的大部分编程对象以及与它们有关的操作。
MFC实际上是一个庞大的文件库,它由几百个执行文件和源代码文件(如H文件)组成。

4 采用MFC编程的优点 标准化程序代码结构 大量的工具支持,提高了编程效率 其它优势 使用标准化的程序代码结构,有利于程序员之间的交流。
利用MFC AppWizard创建MFC应用程序框架, 利用ClassWizard方便地对Windows消息进行管理。 其它优势 完全支持Windows所有的函数、控件、消息、菜单及对话框;具有良好的稳定性和可移植性,更符合微软的风格等。

5 MFC体系结构 MFC主要组成部分:类、宏和全局函数。类是MFC中最主要的内容。
MFC类是以层次结构方式组织起来的。MFC中的类分成两部分,除了一些辅助类,大多数的MFC类是直接或间接从根类CObject派生而来。 几乎每一个派生层次都与一个具体的Windows实例相对应,如文档类、窗口类和视图类等。 MFC中的类可划分为基类、应用程序结构类、窗口类、数据库类等10种,而且在其中一些类中又派生出许多子类。

6

7 CObject类 CObject类是MFC的抽象基类。MFC中的大多数类是从CObject类派生出来的。
CObject类的声明在Afx.h中

8 命令相关类CCmdTarget CCmdTarget类是CObject的子类,它是MFC所有具有消息映射属性的基类。 消息映射:
规定了当一对象接收到消息命令时,应调用哪个函数对该消息进行处理。 程序员很少需要从CCmdTarget类中直接派生出新类,往往都是从它的子类中派生出新类。 CCmdTarget类派生出的几个最主要的类: CWinThread类、CWnd类和CDocument类

9 命令相关类CCmdTarget CWinThread类 CWnd类 CDocument类
CWinThread类是MFC用来封装线程的,包括UI线程和工 作者线程。 每个MFC程序至少使用一个CWinThread派生类。 CWnd类 CWnd类提供了微软基础类库中所有窗口类的基本功能。 CDocument类 CDoument类用于管理应用程序的数据,显示文档数据并 允许读者与之交互。

10 MFC的宏和函数 MFC宏主要功能:消息映射、运行对象类型服务、诊断服务、异常处理。 #include指令 ,包含指定的文件
#define指令,预定义,通常用它来定义常量(包括无参量与带参量),它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了 #typedef指令,常用来定义一个标识符及关键字的别名它是语言编译过程的一部分,但它并不实际分配内存空间。 消息处理宏,如DECLARE_MESSAGE_MAP等。 消息映射宏:ON_COMMAND 、ON_CONTROL、ON_MESSAGE等。

11 MFC全局函数 1. MFC诊断函数 函数名称 描述 AfxCheckMemory 检查当前分配的所有内存的完整性 AfxDump
如果在调试器内调用,则转存对象的状态 AfxDumpStack 生成当前栈的一个映像,该函数通常被静态链接 AfxEnableMemoryTracking  打开或关闭内存跟踪 AfxIsMemoryBlock  检验一个内存块是否被正确的分配 AfxIsValidString 检验一个字符串指针是否有效 AfxSetAllocHook 允许在每次进行内存分配时调用一个函数 AfxDoForAllClasses 对所有从CObject继承的支持运行时检查的类执行一个特定的功能 AfxDoForAllObjects 对所有从CObject继承的用new分配内存对象执行一个指定的功能

12 MFC全局函数 2. 异常抛出函数 函数名称 描述 AfxThrowArchiveException 抛出一个档案异常
AfxThrowFileException 抛出一个文件异常 AfxThrowMemoryException 抛出一个内存异常 AfxThrowNotSupportedException 抛出一个不支持的异常 AfxThrowResourceException 抛出一个Windows未找到资源异常 AfxThrowUserException 在用户初始化的程序动作中抛出一个异常 AfxThrowOleException 抛出一个OLE异常 AfxThrowOleDispatchException 在OLE自动化函数内抛出异常 AfxThrowDaoException 从代码中抛出一个CDaoException异常 AfxThrowDBException 从代码中抛出一个CDBException异常

13 MFC全局函数 3.字符串格式和消息框函数 函数名称 描述 AfxFormatString1 用一个字符串替换给定字符串中的格式字符“%1”
用两个字符串替换给定字符串中两个格式字符“%1”和“%2” AfxMessageBox 显示一个消息框

14 第7讲 MFC与消息处理 MFC简介 Windows编程机制 MFC应用程序框架原理 创建应用程序框架 消息及其分类 消息映射机制
ClassWizard类向导

15 Windows编程机制 Windows是一个多进程的图形窗口操作系统。 Windows应用程序与DOS应用程序有很大的区别:
Windows是一个基于事件的消息(Message)驱动系统。 Windows应用程序是按照“事件→消息→处理”非顺序的机制运行。 当有某个事件(如单击鼠标、键盘输入和执行菜单命令等)发生时,Windows会根据具体的事件产生对应的消息,并发送到指定应用程序的消息队列;应用程序从消息队列中取出消息,并根据不同的消息进行不同的处理。

16 消息和事件 所谓消息就是用于描述某个事件发生的信息,而事件是对于Windows的某种操作。
事件和消息密切相关,事件是因,消息是果,事件产生消息,消息对应事件。所谓消息的响应,其实质就是对事件的响应。

17 消息驱动 消息驱动是Windows应用程序的核心,所有的外部响应(如键盘、鼠标和计时器等)都被Windows先拦截,转换成消息后再发送到应用程序中的目标对象,应用程序根据消息的具体内容进行处理。 消息不仅可由Windows发出,它也可由应用程序本身或其它程序产生。Windows为每一个应用程序都维护一个或多个消息队列,发送到每个程序窗口的消息都排成一个队列。

18 应用程序中的轮询处理

19 Windows编程特点 Windows应用程序具有的特性: 消息驱动机制 图形设备接口(GDI) 基于资源的程序设计 动态链接库 进程和线程

20 (1)消息驱动机制 在Windows操作环境中,无论是系统产生的动作或 是用户运行应用程序产生的动作,都称为事件 (Events)产生的消息(Message)。 例如,在Windows 桌面(传统风格)上,双击应用程序的快 捷图标,系统就会执行该应用程序。 在Windows的应用程序中,也是通过接收消息、分发消息、 处理消息来和用户进行交互的。这种消息驱动的机制是 Windows编程的最大特点。

21 (1)消息驱动机制 许多Windows消息都经过了严格的定义,并且适用于 所有的应用程序。
例如,当用户按下鼠标的左键时系统就会发送 WM_LBUTTONDOWN消息; 而当用户敲了一个字符键时系统就会发送WM_CHAR消息; 若用户进行菜单选择或工具按钮单击等操作时,系统又会 相应地发送WM_COMMAND消息给相应的窗口等。

22 (2)图形设备接口(GDI) 在传统的DOS环境中,想要在打印机上打印一幅图 形是一件非常复杂的事情,因为用户必须根据打印 机类型和指令规则向打印机输送数据。 Windows则提供了一个抽象的接口,称为图形设备 接口(Graphical Device Interface,简称GDI),使得用 户直接利用系统的GDI函数就能方便实现输入或输 出,而不必关心与系统相连的外部设备的类型。

23 (3)基于资源的程序设计 Windows应用程序常常包含众多图形元素,例如光 标、菜单、工具栏、位图、对话框等,在Windows 环境下,每一个这样的元素都作为一种可以装入应 用程序的资源来存放。这些资源就像C++程序中的 常量一样,可以被编辑、修改,也可以被其他应用 程序所共享。 Visual C++ 6.0中就提供这样的编辑器,可“所见即 所得”地对这些不同类型的资源进行设计、编辑等。

24 (3)基于资源的程序设计 在Windows编程中将频繁接触到一个称为句柄(HANDLE) 的概念。
当操作系统每产生一个这样的资源时,都要将它们放入相应 的内存,并为这些内存指定一个唯一的标识号。这个标识号 即是该资源的句柄。

25 句柄示意图

26 (4)动态链接库 动态链接库提供了一些特定结构的函数,能被应用程序在运行过程中装入和连接,且多个程序可以共享同一个动态链接库。
动态链接库可以大大节省内存和磁盘空间。 动态链接库可以提高程序模块的灵活性,因为它本身是可以单独设计、编译和调试的。 例如:Windows提供了应用程序可利用的丰富的函数调用,大多数用于实现其用户界面和在显示器上显示的文本和图形,都是通过动态链接库来实现的。 这些动态链接库是一些具有.DLL扩展名或者有时是.EXE扩展名的文件

27 (4)动态链接库 在Windows操作系统中,最主要的DLL有KERNEL32.DLL、 GDI32.DLL和USER32.DLL三个模块。
其中,KERNEL32用来处理存储器底层功能、任务和资源管 理等Windows核心服务; GDI32用来提供图形设备接口,管理用户界面和图形绘制, 包括Windows元文件、位图、设备描述表和字体等; USER32负责窗口的管理,包括消息、菜单、光标、计时器 以及其它与控制窗口显示相关的一些功能。

28 (5)进程与线程 基本定义: 根本区别: 进程:是执行中一段程序,即一旦程序被载入到内存中并准 备执行,它就是一个进程。
线程:单个进程中执行中每个任务就是一个线程。 根本区别: 进程:是操作系统资源分配的基本单位 线程:是任务调度和执行的基本单位。

29 (5)进程与线程 包含关系: 内存分配: 一个线程只属于一个进程,但是一个进程可拥有多个线程。
多线程处理就是允许一个进程中在同一时刻执行多个任务。 内存分配: 系统在运行的时候会为每个进程分配不同的内存空间; 系统不会为线程分配内存(线程所使用的资源来自其所属进程 的资源),线程组之间只能共享资源。

30 第7讲 MFC与消息处理 MFC简介 Windows编程机制 MFC应用程序框架原理 创建应用程序框架 消息及其分类 消息映射机制
ClassWizard类向导

31 MFC应用程序框架 尽管每个应用程序具体实现的功能不同,但同一类程序的基 本结构是相同的。因此,通常采用MFC AppWizard创建一 个MFC应用程序框架。 应用程序框架是一个集合,其可以提供一般应用程序所需的 全部面向对象软件组件。或者说,一个应用程序框架是一个 类库的超级集合。 但应用程序框架不同于单纯的类的集合,其自己定义了程序 的结构。

32 应用程序框架中的对象 MFC应用程序框架提供了构建应用程序所需要的类,在程序 运行时能够生成运行时类的对象。
如应用程序对象、文档对象、视图对象和框架窗口对象。 应用程序对象theApp是一个唯一的全局变量,它的主要功能是通过调 用WinMain()主函数启动程序的运行。 MFC应用程序框架也有一个作为程序入口点的WinMain()主 函数,但在源程序中看不见该函数,它在MFC中已定义好并 同应用程序相链接。 C:\Program Files (x86)\Microsoft Visual Studio\VC98\MFC\SRC

33 Windows应用程序的执行流程 初始化应用程序 开始执行 初始化并创建 应用程序窗口 进入消息循环 并获取一条消息 消息是否为
WM_QUIT? 终止程序 应用程序中是否 处理了此消息 处理消息 转送消息给窗口 进行默认处理

34 Windows程序实现的过程 例如,在Windows中实现创建一个窗口,并在 该窗口中相应鼠标及键盘消息,其程序实现步 骤如下:
WinMain函数的定义 创建一个窗口 进行消息循环 完成回调函数

35 第7讲 MFC与消息处理 MFC简介 Windows编程机制 MFC应用程序框架原理 创建应用程序框架 消息及其分类 消息映射机制
ClassWizard类向导

36 应用程序向导 作为可视化编程语言,Visual C++提供了向导 的功能 向导就是快速生成资源及代码的工具。
有了这些向导,可以减轻程序员手工编写代码 的工作量,使程序员能把精力放在具体代码的 编写上。

37 Visual C++中的向导类型 Visual C++功能十分强大,可以创建多种文件类型,所以其向导的类型也很多。当用户执行“File”/“New”菜单命令时,就可以看到这些应用程序向导类型的列表,如图所示。

38 Visual C++中的向导类型 Visual C++集成开发环境中向导类型及生成的程序说明:
ATL COM AppWizard:创建包含ActiveX控件的ATL(Active Template Library)。 Cluster Resource Type Wizard:创建能够在微软群服务器上模拟和管 理的项目。 Custom AppWizard:以用户定制的模板向导创建项 Datebase Project:创建数据库项目。 DevStudio Add-in Wizard:创建C++或汇编语言编写的类似于 Developer Studio形式的外接程序,特别是做各种视频插件。 Extended Stored Proc Wizard:在SQL Server上创建一个扩展存储的程 序。

39 Visual C++中的向导类型 Makefile:制作Makefile文件,订制自己项目的集成开发环境。
ISAPI Extension Wizard:利用ISAPI(Internet Server API)创建网页浏览程序。 MFC AcitveX Control Wizard:创建基于MFC的ActiveX控件。 MFC AppWizard[dll]:创建基于MFC的动态连接库。 MFC AppWizard[exe]:创建基于MFC的应用程序,这是最常使用的一个向导。 New Database Wizard:在SQL Server上创建一个SQL Server数据库。

40 Visual C++中的向导类型 Utility Project:创建自定义编译规则的项目,该项目可以作为一些子项目的主项目,它不产生LIB、DLL或EXE文件。 Win32 Application:创建Win32应用程序,可不使用MFC,采用SDK方式编程或C语言编程。 Win32 Dynamic-Link Library:创建Win32动态连接库,采用SDK方法。 Win32 Static Library:创建Win32静态连接库,采用SDK方法。 其中,最常使用的是MFC AppWizard[exe]。

41 使用应用程序向导 下面来看一下如何通过应用程序向导创建应用程序框架,其具体操作步骤如下:
(1)启动Visual C++6.0集成开发环境,单击菜单栏中的“File”/“New”命令,打开New窗口。 (2)在New窗口中选择Projects选项卡,在列表中选择MFC AppWizard[exe]项,在Project name文本框中输入工程名Hello World

42 使用应用程序向导 (3)单击OK按钮,弹出MFC AppWizard — Step1窗口
Single document:一次只能打开一个文档编辑窗口。 Multiple document:在应用程序中可同时打开多个文档。 Dialog based:在对话框基础上建立的程序。 Document/View architecture support:该选项允许生成文档/视图和非文档/视图结构程序。

43 使用应用程序向导 (4)这里选择Dialog based单选项,单击Next按钮,打开MFC AppWizard—Step 2 of 4窗口。

44 MFC AppWizard 在MFC AppWizard—Step 2 of 4窗口中有如下设置。 About box:生成“关于”对话框。
Context-sensitive Help:生成支持上下文相关帮助的帮助文件 。 3D controls:具有3D效果的程序界面。 Automation:应用程序能够操作在其他应用程序中实现的对 象,或者自己的应用程序可供Automation客户使用。 ActiveX Controls:支持ActiveX控件。 Windows Sockets:支持基于TCP/IP协议的网络通信。 Please enter a title for your dialog:设置应用程序主窗口的标 题。

45 使用应用程序向导 (5)单击Next按钮,打开MFC AppWizard — Step 3 of 4窗口。
MFC Standard:标准MFC项目。 Windows Explorer:“Windows资源管理器”风格项目。 Yes,please:在源文件中添加注释。 No,thank you:不添加注释。 As a shared DLL:共享动态链接库。 As a statically linked library:静态链接库。

46 使用应用程序向导 (6)单击Next按钮,打开MFC AppWizard — Step 4 of 4窗口。
(7)在MFC AppWizard — Step 4 of 4窗口中确定类的名称及所在文件的名称, 单击Finish按钮,打开New Project Information窗口.

47 使用应用程序向导 (8)在New Project Information窗口中显示将要创建的文件清单,单击OK按钮完成对话框应用程序的创建。

48 应用程序向导生成的类 打开前面创建的Hello World工程的工作区,可以看到 系统在生成应用程序框架的过程中,自动生成了以下 几个类。
CHelloWorldApp; CMainFrame; CHelloWorldView; CHelloWorldDoc。 这些类在工程Hello World工作区上的显示如图所示。

49 应用程序向导生成的类

50 CHelloWorldApp类 CHelloWorldApp的基类为CWinApp。如果需要创建 MFC应用程序,首先要使用CWinApp类,因为 CWinApp类不仅代表了程序中运行的主线程,而且代 表了应用程序本身。在任何MFC应用程序中只有一个 CWinApp对象,用于控制应用程序的初始化、启动应 用程序、运行主消息循环、终止应用程序。

51 CMainFrame类 类CMainFrame的基类为CFrameWnd。其是由 MFC中的CFrameWnd派生来的,所以它也是 一个框架窗口。主框架窗口类负责标题栏、菜 单栏工具栏及状态栏的生成。 这些子窗口是可以按照用户的意图自定义的, 只需要修改主框架窗口的实现文件即可。

52 CHelloWorldView类和CHelloWorldDoc类
CHelloWorldView类的基类为CView,而 CHelloWorldDoc类的基类为CDocument。之所以 把CHelloWorldView类和CHelloWorldDoc类一起 介绍是因为这两个类是密切相关的。 视图是显示文档数据的界面,它主要占据着主框 架窗口的客户区,视图类不仅把程序文档数据显 示出来,它还能接受用户的输入、编辑。视图对 象也通过消息与主框架、文档对象相互操作。

53 文档与视图的关系 文档对象是存储程序数据的地方。一般来说,把要存储的数据放到文档对象中,即把要存储的数据作为文档对象的成员变量,进而实现文档的串行化。文档与视图的关系如图所示。

54 应用程序向导生成的文件 res 编译后的二进制资源文件 扩展名 描述 opt 工程中关于开发环境的参数选项文件 clw
类向导文件信息,是按INI文件格式存储的 dsp 工程文件 dsw 工作区文件,将项目的详细情况组合到Workspace工作区中 aps 资源辅助文件,二进制格式 plg 编译信息文件,存储错误或警告信息 hpj 帮助文件 bsc 代码浏览文件,如果使用源代码浏览器,必须生成该文件 map 可执行文件的映像信息记录文件 pch 预编译文件,可以加快编译速度 pdb 记录了程序有关的一些数据和调试信息,在调试的时候有用 exp 只有在编译DLL时才会生成,记录DLL文件中的一些信息 ncb 无编译浏览文件,当自动完成功能出问题时可以删除此文件 c 头文件 cpp 原文 rc 资源文件 rc2 资源文件,用来将资源包含在项目中

55 典型文件举例 Visual C++中一个类由头文件和源文件两类文件支持 。 头文件用于定义类,包含指明派生关系,声明成员变 量及成员函数。
源文件用于实现类,主要定义成员函数的实现代码和 消息映射。 利用MFC AppWizard[exe]向导生成一个应用程序,根 据应用程序种类的不同,生成的文件也有所差异,下 面将分类列举。

56 应用文件 应用程序类文件 每个MFC应用程序都需要有一个应用程序类文件, 它一般与项目文件同名,例如:在默认情况下, MyProject项目应用程序类头文件为MyProject.h;源 文件的文件名为”MyProject.cpp”,它们主要声明及 实现应用程序类CMyProjectApp。 CMyProjectApp类主要负责完成应用程序的初始化、 程序的启动和程序运行结束时的清理工作。

57 应用文件 资源文件 在项目中,资源通过资源标识符加以区分,通常情 况下,应用程序向导会把一个项目中所有资源的标 识符放到Resource.h中。对资源ID的命名有一定规 则,如表所示。 标识符前缀 说 明 IDR_ 主菜单资源、工具栏资源和快捷键资源 IDD_ 对话框资源 IDC_ 控件和光标 IDS_ 字符串 IDP_ 提示信息对话框的字符串 ID_ 菜单命令项

58 应用文件 标准包含文件 应用程序向导会为每一个项目生成一个标准包含头 文件StdAfx.h。该文件用于包含一般情况下要用到 且不会被修改的头文件。 如MFC声明文件afxwin.h、使用工具栏、状态栏文 件afxext.h等。StdAfx.h和StdAfx.cpp文件用来生成 预编译文件。

59 单文档应用程序/多文档应用程序 框架窗口类文件
在默认情况下,框架窗口的头文件均为MainFrm.h ;源文件均为MainFrm.cpp,这两个文件定义和实 现了框架窗口类CMainFrame,这个类是MFC的 CFrameWnd类的派生类,它主要负责创建标题栏、 工具栏和状态栏。

60 文档类文件 在默认情况下,文档类头文件都是项目名称+“Doc.h” 组成;源文件都是项目名称+“Doc.cpp”组成。
例如:MyProject项目中文档类头文件为MyProjectDoc.h; 源文件为MyProjectDoc.cpp。它们是定义和实现文档类 CMyProjectDoc的。 CMyProjectDoc类是MFC中CDocument类的派生类, 它主要负责应用程序数据的保存和装载,实现文档 的序列化功能。

61 视图类文件 在默认情况下,视图类头文件都是项目名称 +“View.h”组成;源文件都是项目名称+“View.cpp”组 成。
例如:MyProject项目中视图类头文件为MyProjectView.h; 源文件为MyProjectView.cpp。它们是定义和实现视图类 CMyProjectView的。 CMyProjectView类是MFC中CView类的派生类,它 主要负责客户区文档数据的显示及如何进行人机交 互。

62 基于对话框应用程序 在默认情况下,对话框类头文件都是项目名称 +“Dlg.h”组成;源文件都是项目名称+“Dlg.cpp” 组成。例如:MyProject项目中对话框类头文件 为MyProjectDlg.h;源文件为MyProjectDlg·cpp。 它们是定义和实现对话框类CMyProjectDlg的。 CMyProjectDlg类是MFC中CDialog类的派生类。 它可以完成一个对话框的创建、显示等工作。

63 第7讲 MFC与消息处理 MFC简介 Windows编程机制 MFC应用程序框架原理 创建应用程序框架 消息及其分类 消息映射机制
ClassWizard类向导

64 消息 消息是Windows编程中的基本概念,许多情况下,Windows编程也就是编写消息处理函数,下面将简要介绍Windows程序设计中最常用的一些消息。

65 Windows消息分为三种类型 标准Windows消息:以WM_前缀(但不包括WM_COMMAND)开始的消息,包括鼠标消息、键盘消息和窗口消息,如WM_MOVE 、WM_PAINT等。 控件通知(Control Notification)消息:对控件操作引起的消息,是控件和子窗口向其父窗口发出的WM_COMMAND通知消息。例如,当用户修改了编辑控件中的文本后,编辑控件向其父窗口发送WM_COMMAND通知消息。 命令(Command)消息:由菜单项、工具栏按钮、快捷键等用户界面对象发出的WM_COMMAND消息。命令消息与其它消息不同,它可被更广泛的的对象如文档、文档模板、应用程序对象、窗口和视图等处理。

66 键盘消息 键盘消息是应用程序中使用最频繁的消息之一,当用户使用键盘对应用程序进行操作,就发送键盘消息。一般来说,Visual C++中的键盘消息主要有如下3种。 WM_CHAR:该消息的处理函数OnChar()。 WM_KEYDOWN:用户按下一个非系统键。 WM_KEYUP:在非系统键被释放时产生。

67 鼠标消息 与键盘消息类似,鼠标消息也是Windows应用程序中使用最为频繁的消息之一。
WM_MOUSEMOVE:用户将鼠标移进窗口或在窗口中移动。 WM_LBUTTONDOWN:用户按下左键。 WM_LBUTTONUP:用户释放左键。 WM_LBUTTONDBCLICK:用户双击左键。 WM_RBUTTONDOWN:用户按下右键。 WM_RBUTTONUP:用户释放右键。 WM_RBUTTONDBCLICK:用户双击右键。

68 窗口消息 窗口消息是指对Windows应用程序的窗口进行某些操作时发送的消息。Visual C++ 6.0中,包含了如下6种窗口消息。
WM_CREATE:窗口被创建。 WM_DESTROY:窗口被销毁。 WM_CLOSE:窗口被关闭。 WM_MOVE:窗口发生移动。 WM_SIZE:窗口发生改变。 WM_PAINT:窗口发生重绘。

69 焦点消息 焦点消息是指当窗口中的某个对象得到焦点和失去焦点的时候,对应窗口或对象触发的操作。一般来说,只有下面两种焦点消息。
WM_SETFOCUS:窗口得到焦点。 WM_KILLFOCUS:窗口失去焦点。 当一个窗口从非活动状态变为具有输入焦点的活动状态的时候,它就会收到WM_SETFOCUS消息,而当一个窗口失去输入焦点变为非活动状态的时候它就会收到WM_KILLFOCUS消息。

70 定时器消息 Windows的定时器是一种周期性消息产生装置,当用户为一个窗口设置了定时器资源之后,系统就会按规定的时间间隔向窗口发送定时器消息,在这个消息中就可以处理一些需要定期处理的事情。定时器消息只有一种:WM_TIMER,其响应函数是OnTimer。 对于定时器的操作,通常都会和函数SetTimer()配合使用。在响应OnTimer函数之前,应先添加一个定时器对其进行触发,如果没有建立定时器,系统是不会自己去触发OnTimer函数的,SetTimer()函数的作用就是设置定时器 。

71 命令消息 在应用程序的实际操作中,命令消息WM_COMMAND是使用很频繁的消息之一。命令消息是当用户选择某菜单项或单击某按钮时发送的消息,每当用户选择一个菜单项、单击一个按钮或需要告诉系统应当执行什么操作的时候,则发送一条命令消息WM_COMMAND。 在Visual C++中,命令消息一般都在ClassWizard中添加并以Onxxx的形式命名后,就可以在代码编辑框中为其添加代码了。

72 第7讲 MFC与消息处理 MFC简介 Windows编程机制 MFC应用程序框架原理 创建应用程序框架 消息及其分类 消息映射机制
ClassWizard类向导

73 MFC消息管理 MFC消息管理是MFC编程的一个重要内容,也是编写MFC 应用程序的基础。
MFC应用程序消息处理的方式与SDK(Software Development Kit)应用程序有所不同。MFC应用程序框架 截取了Windows向应用程序发出的消息,再确定将消息发 送给哪一个对象,可以根据需要利用函数重载对消息进行 处理,但不需要处理的消息将由应用程序框架自动处理。 消息管理包括消息的发送和处理。对于消息发送,MFC提 供了类似于API函数功能的消息发送函数,而MFC消息处理 的内部机制则相对复杂一些。从编程的角度出发,我们只 需了解其大致的原理。

74 MFC消息映射机制 MFC采用消息映射(Message Map)机制取代C/C++语言中 的switch-case结构来处理消息。
MFC消息映射机制包括一组消息映射宏。一条消息映射宏 把一个Windows消息和其消息处理函数联结起来。 MFC应用程序框架提供了消息映射功能。 在类的实现源文件中用BEGIN_MESSAGE_MAP()和 END_MESSAGE_MAP()宏来定义消息映射。 在类定义的结尾用DECLARE_MESSAGE_MAP()宏来声明 使用消息映射。

75 MESSAGE_MAP消息映射形式 BEGIN_MESSAGE_MAP(theclass, baseclass) //{{AFX_MSG_MAP(theclass) ON_ // MFC预定义的消息映射宏 ON_MESSAGE(message , memberFxn) // 用户自定义的消息映射宏 //}}AFX_MSG_MAP END_MESSAGE_MAP() 注意:特殊注解“//{{AFX_MSG_MAP”是ClassWizard类向导用于维护消息映射宏的标记,用户不要删除注解轻易修改注解内的代码。

76 ClassWizard在类的定义中声明了消息处理函数
class CMainFrame : CFrameWnd { public: CMainFrame(); protected: //{{AFX_MSG(CMainFrame) // 声明消息处理函数原形 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); // 由程序向导自动生成 afx_msg void OnClose(); // 由ClassWizard类向导添加 afx_msg void OnDestroy(); afx_msg void OnEditCopy(); //}}AFX_MSG DECLARE_MESSAGE_MAP() // 声明使用消息映射宏 };

77 消息的发送 发送消息到一个窗口可以采用传送(Send)或寄送(Post)方式,这两种方式之间的主要区别是消息被接收对象收到后是否立即被处理。Windows提供了三个API函数用于消息的发送。 函数SendMessage()用于向一个或多个窗口传送消息,该函数将调用目标窗口的窗口函数,直到目标窗口处理完收到的消息,该函数才返回。 函数PostMessage()用于向一个或多个窗口寄送消息,它把消息放在指定窗口创建的线程的消息队列中,然后不等消息处理完就返回。

78 消息的发送 函数SendDlgItemMessage()函数用于向对话框中指定的控件发送消息,直到目标控件处理完收到的消息,该函数才返回。
MFC将这三个函数封装为CWnd窗口类的成员函数,封装了目标窗口句柄,它们将向调用它的窗口对象发送或寄送消息,如pMyView->SendMessage()的调用形式表示向pMyView所指对象发送消息。 与用户输入相关的消息(如鼠标消息和键盘消息)通常是以寄送(Post)的方式发送,以便这些用户输入可以由运行较缓慢的系统进行缓冲处理。而其它消息通常是以传送(Send)的方式发送

79 手工处理消息映射 由于程序逻辑设计结构的限制或不同窗口之间数据的同步, 程序员需要手工自定义一些消息。
例如,如果需要在特定时间间隔内通知所有数据输出窗口重新取得数 据,就必须采用定时器事件来产生特定的消息。 MFC允许用户自定义消息,常量WM_USER(为0x0400)与 第一个自定义消息值相对应,用户必须为自己的消息定义相 对于WM_USER的偏移值。 利用#define语句定义自己的消息: #define WM_USER1 WM_USER+0 #define WM_USER2 WM_USER+1 自定义消息处理函数要进行声明

80 第7讲 MFC与消息处理 MFC简介 Windows编程机制 MFC应用程序框架原理 创建应用程序框架 消息及其分类 消息映射机制
ClassWizard类向导

81 ClassWizard(类向导)主要用来定制现有的类和建立新的类,如把消息映射到类的成员函数,把一个控件与类的成员变量对应起来。
只有在打开或创建一个项目后,View主菜单才会出现ClassWizard菜单项,这时才能使用ClassWizard(类向导)。一般通过<Ctrl+W>快捷键激活ClassWizard。

82 ClassWizard “MFC ClassWizard”对话框共有5个页面:
Message Maps页面用来处理消息映射,为消息添加或删除处理函数,查看已被处理的消息并定位消息处理代码; Member Variables页面用来给对话框类添加或删除成员变量,这些变量必须是和某些控件资源相关联的控件类型; Automation页面提供了对OLE自动化类的属性和方法的管理 ActiveX Events页面用于管理ActiveX类所支持的ActiveX事件; Class Info页面显示应用程序中所包含类的信息,如一个类的头文件、实现文件和基类信息。

83 ClassWizard界面

84 为项目添加新类 为项目添加新类的方法如下: (1)首先,建立一个基于对话框的应用程序。
(2)单击“View”/“ClassWizard”菜单命令打开“MFC ClassWizard”对话框。 (3)单击右上角“Add Class”按钮,在弹出的菜单中 选择“New”菜单项,弹出“New Class”对话框。

85 为项目添加新类

86 为项目添加新类 (4)在“Name”文本框中添入“CNewClassName”,在“Base class”文本框中选择需要创建的类的基类,单击“OK”按钮,将类CNewClassName添加到项目中,在Workspace工作区中就可以对这个类进行编辑。

87 第十五讲 MFC与消息处理 MFC简介 Windows编程机制 MFC应用程序框架原理 创建应用程序框架 消息及其分类 消息映射机制
ClassWizard类向导


Download ppt "第十五讲 MFC与消息处理 MFC简介 Windows编程机制 MFC应用程序框架原理 创建应用程序框架 消息及其分类 消息映射机制"

Similar presentations


Ads by Google