1、第第12章章 Visual C+环境下环境下Windows程序开发概述程序开发概述n12.1 Visual C+可视化集成开发环境可视化集成开发环境n12.2 创建、组织文件、工程和工作区创建、组织文件、工程和工作区n12.3 Windows编程基础编程基础n12.4 Win32开发开发n12.5 MFC编程编程12.1 Visual C+可视化集成开发环境可视化集成开发环境n12.1.1 Visual C+简介简介n12.1.2 项目开发过程项目开发过程n12.1.3 集成开发环境集成开发环境Developer Studion12.1.4 常用功能键及其意义常用功能键及其意义返回首页12.1
2、.1 Visual C+简介简介n1Visual C+集成开发环境(集成开发环境(IDE)集成开发环境(集成开发环境(IDE)是一个将程序编辑器、编译器、调是一个将程序编辑器、编译器、调试工具和其他建立应用程序的工具集成在一起的用于开试工具和其他建立应用程序的工具集成在一起的用于开发应用程序的软件系统。发应用程序的软件系统。n2向导(向导(Wizard)向导是一个通过一步步的帮助引导你工作的工具。向导是一个通过一步步的帮助引导你工作的工具。Developer Studio中包含三个向导中包含三个向导。n 3MFC库库库(库(library)是可以重复使用的源代码和目标代码的集合。是可以重复使用
3、的源代码和目标代码的集合。MFC(Microsoft Fundamental Classes)是是Visual C+开发环境所带的类库,在该类库中提供了大量的类,开发环境所带的类库,在该类库中提供了大量的类,可以帮助开发人员快速建立应用程序。可以帮助开发人员快速建立应用程序。返回本节12.1.2 项目开发过程项目开发过程一个用C+开发项目的通用开发过程如图12-1所示。n建立一个项目的第一步是利用编辑器建立程序代码文件,建立一个项目的第一步是利用编辑器建立程序代码文件,包括头文件、代码文件、资源文件等。然后,启动编译包括头文件、代码文件、资源文件等。然后,启动编译程序,编译程序首先调用预处理程
4、序处理程序中的预处程序,编译程序首先调用预处理程序处理程序中的预处理命令(如理命令(如#include,#define等),经过预处理程序处等),经过预处理程序处理的代码将作为编译程序的输入。编译对用户程序进行理的代码将作为编译程序的输入。编译对用户程序进行词法和语法分析,建立目标文件,文件中包括机器代码、词法和语法分析,建立目标文件,文件中包括机器代码、连接指令、外部引用以及从该源文件中产生的函数和数连接指令、外部引用以及从该源文件中产生的函数和数据名。此后,连接程序将所有的目标代码和用到的静态据名。此后,连接程序将所有的目标代码和用到的静态连接库的代码连接起来,为所有的外部变量和函数找到连
5、接库的代码连接起来,为所有的外部变量和函数找到其提供地点,最后产生一个可执行文件。一般有一个其提供地点,最后产生一个可执行文件。一般有一个makefile文件来协调各个部分产生可执行文件。文件来协调各个部分产生可执行文件。返回本节12.1.3 集成开发环境集成开发环境Developer Studion1进入进入Developer Studion2Developer Studio的界面的界面n3获得帮助信息获得帮助信息n4Visual C+的编辑器的编辑器图12-2 Developer Studio界面Developer Studio它具有以下特点:它具有以下特点:n(1)自动语法。)自动语法。
6、n(2)自动缩进。)自动缩进。n(3)参数帮助。)参数帮助。n(4)集成的关键字帮助。)集成的关键字帮助。n(5)拖放编辑。)拖放编辑。n(6)自动错误定位。)自动错误定位。返回本节12.1.4 常用功能键及其意义常用功能键及其意义表12-1 常用功能键返回本节12.2 创建、组织文件、工程和工作区创建、组织文件、工程和工作区n12.2.1 新建工程新建工程n12.2.2 新建工作区新建工作区n12.2.3 增加已有文件到工程中增加已有文件到工程中n12.2.4 打开工作区打开工作区n12.2.5 设置当前工程设置当前工程返回首页12.2.1 新建工程新建工程n项目工作区是一个包含用户的所有相
7、关项目和项目工作区是一个包含用户的所有相关项目和配置的实体。工程定义为一个配置和一组文件,配置的实体。工程定义为一个配置和一组文件,用以生成最终的程序或二进制文件。一个项目用以生成最终的程序或二进制文件。一个项目工作区可以包含多个工程,这些工程既可以是工作区可以包含多个工程,这些工程既可以是同一类型的工程,也可以是不同类型的工程同一类型的工程,也可以是不同类型的工程(如(如Visual C+和和Visual J+工程)。工作区工程)。工作区现在以现在以.dsw为后缀名(以前为为后缀名(以前为.mdp),),项目文项目文件现在以件现在以.dsp(以前为以前为.mak)为后缀名。项目为后缀名。项目
8、工作区如图工作区如图12-3所示。所示。图12-3 项目工作区n要新建一个工程,可以:要新建一个工程,可以:n(1)在)在File菜单上,单击菜单上,单击New,选择选择Projects标签。标签。n(2)从列表中选择项目类型)从列表中选择项目类型n(3)单击)单击Create New Workspace(新建工作新建工作区)或区)或Add to Current Workspace(加入到当加入到当前工作区中)。前工作区中)。n(4)要 使 新 工 程 为 子 工 程,可 以 选 择)要 使 新 工 程 为 子 工 程,可 以 选 择Dependency of 检查框,并从列表中选择一个检查框
9、,并从列表中选择一个工程。工程。n(5)在)在Project Name框中,输入新工程名,确框中,输入新工程名,确保该名字必须与工作区中的别的工程名字不重保该名字必须与工作区中的别的工程名字不重名。名。n(6)在)在Location框中,指定工程存放的目录:框中,指定工程存放的目录:可以直接输入路径名,也可以单击旁边的可以直接输入路径名,也可以单击旁边的Browse按钮,浏览选择一个路径。按钮,浏览选择一个路径。n(7)单击)单击Platform框中的相应检查框,指定工框中的相应检查框,指定工程的开发平台程的开发平台返回本节12.2.2 新建工作区新建工作区n要创建一个空的工作区,可以:要创建
10、一个空的工作区,可以:n(1)在)在File菜单上,单击菜单上,单击New。n(2)在随后弹出的对话框上,单击在随后弹出的对话框上,单击Workspace标签。标签。n(3)从类型列表中选择)从类型列表中选择Blank Workspace。n(4)在在Workspace Name框中输入名字,注意框中输入名字,注意名字不能与它将要包含的工程同名。名字不能与它将要包含的工程同名。n(5)在)在Location框中指定存放工作区文件的目框中指定存放工作区文件的目录。录。n(6)单击)单击OK。返回本节12.2.3 增加已有文件到工程中增加已有文件到工程中n(1)打开包含目标工程的项目工作区文件。)
11、打开包含目标工程的项目工作区文件。n(2)在)在Project菜单上,单击菜单上,单击Add to Project,然后单击然后单击Files。n(3)在在Insert Files into Project对话框中,浏对话框中,浏览并定位要加入到工程中的文件名,然后选择览并定位要加入到工程中的文件名,然后选择它们。它们。n(4)从)从Insert Into中选择工程名字,然后单击中选择工程名字,然后单击OK。返回本节12.2.4 打开工作区打开工作区n选择选择File-Open Workspace,指定要打开的工指定要打开的工作区;或选择作区;或选择File-Recent Workspaces
12、,从最从最近打开过的工作区列表中选择一个。近打开过的工作区列表中选择一个。返回本节12.2.5 设置当前工程设置当前工程n选择选择Project Setting,可以为当前工程设置编可以为当前工程设置编译、链接和译、链接和C/C+等各种选项。等各种选项。返回本节12.3 Windows编程基础编程基础n12.3.1 Windows APIn12.3.2 Windows基础基础n12.3.3 Windows消息映射和处理消息映射和处理返回首页12.3.1 Windows APIn1Windows API的定义的定义Windows API是应用程序编程接口(是应用程序编程接口(Applicatio
13、n Programming Interface)的英文缩写。它是大量函数的英文缩写。它是大量函数加上数字常量、宏、结构、类型以及其他相关项的集合。加上数字常量、宏、结构、类型以及其他相关项的集合。n2Windows API函数的分类函数的分类根据根据Windows API函数的功能,可以将其分为三类:函数的功能,可以将其分为三类:(1)窗口管理函数。用以实现窗口的创建、移动和修改功)窗口管理函数。用以实现窗口的创建、移动和修改功能。能。(2)图形设备()图形设备(GUI)函数。用以实现与设备无关的图形函数。用以实现与设备无关的图形操作功能。操作功能。(3)系统服务函数。用以实现与操作系统有关的
14、多种功能。)系统服务函数。用以实现与操作系统有关的多种功能。返回本节12.3.2 Windows基础基础n1事件事件 事件以如下三种方式产生:事件以如下三种方式产生:(1)通过输入设备,如键盘和鼠标。)通过输入设备,如键盘和鼠标。(2)通过屏幕上的可视对象,如菜单、工具栏按钮、滚动)通过屏幕上的可视对象,如菜单、工具栏按钮、滚动条和对话框上的控件。条和对话框上的控件。(3)来自)来自Windows内部。内部。2消息消息但但Windows捕获一个事件后,它会编写一条消息,并将相捕获一个事件后,它会编写一条消息,并将相关信息放入一个数据结构中,然后将包含此数据结构的关信息放入一个数据结构中,然后将
15、包含此数据结构的消息发送给需要此消息的程序。消息发送给需要此消息的程序。Windows消息是在消息是在Windows文件中用宏定义的常数。消息常数名通常以文件中用宏定义的常数。消息常数名通常以WM开头,格式为开头,格式为WM_XXX。n3绘图及设备环境绘图及设备环境Windows具有图形用户界面(具有图形用户界面(GUI),),它包括菜它包括菜单、工具栏、滚动条和对话框中的按钮等元素。单、工具栏、滚动条和对话框中的按钮等元素。n4对象与句柄对象与句柄对设备环境的访问是通过对设备环境的访问是通过Windows返回的句柄进返回的句柄进行的。行的。n5坐标系坐标系要为绘制和其他任务指定位置,需要坐标
16、系统。要为绘制和其他任务指定位置,需要坐标系统。Windows提供了提供了8种不同的坐标系。种不同的坐标系。返回本节12.3.3 Windows消息映射和处理消息映射和处理n开始执行开始执行n在在Windows中,管理消息的方式通常是这样的:中,管理消息的方式通常是这样的:当发生某个消息后,该消息进入消息队列,操当发生某个消息后,该消息进入消息队列,操作系统根据消息提供的信息决定由哪个应用程作系统根据消息提供的信息决定由哪个应用程序来处理,该应用程序依照一定的方式查找应序来处理,该应用程序依照一定的方式查找应用程序各个类的消息映射(一组宏,这些宏用用程序各个类的消息映射(一组宏,这些宏用来确定
17、某个消息及相应的处理程序的对应关来确定某个消息及相应的处理程序的对应关系),找到处理程序,然后由处理程序执行。系),找到处理程序,然后由处理程序执行。图图12-4是是Windows程序和程序和Windows消息的基本消息的基本流程。流程。图12-4 Windows程序和Windows消息处理的基本流程Windows程序要处理的消息种类如下:程序要处理的消息种类如下:n(1)Windows消息。该类消息以消息。该类消息以WM_开头开头(WM_COMMAND例外),通常由窗口和视图例外),通常由窗口和视图来处理。来处理。n(2)由控件和其他子窗口发送给父窗口的)由控件和其他子窗口发送给父窗口的WM
18、_COMMAND消息。这些消息中包括消息。这些消息中包括EN_CHANGE通知码。通知码。n(3)来自于用户界面对象的)来自于用户界面对象的WM_COMMAND消息。这些用户界面对象包括菜单、工具栏按消息。这些用户界面对象包括菜单、工具栏按钮和快捷键。钮和快捷键。返回本节12.4 Win32开发开发n12.4.1 抢先式多任务和多线程抢先式多任务和多线程n12.4.2 连续的地址空间和先进的内存管理连续的地址空间和先进的内存管理n12.4.3 内存映射文件内存映射文件n12.4.4 Win32s:Windows 3.x对对Win32 API的的支持支持n12.4.5 Win32编程基础编程基础
19、返回首页nWin32可以应用于特定的操作系统,这种系统可以应用于特定的操作系统,这种系统可以直接控制和处理可以直接控制和处理PC硬件资源,而不必象硬件资源,而不必象Win16 API那样依赖于那样依赖于MS-DOS系统服务。然而,系统服务。然而,Win32不是简单的由不是简单的由Win16从从16位到位到32位的升位的升级,更重要的在于它支持:级,更重要的在于它支持:n(1)高性能的抢先式多任务和多线程;)高性能的抢先式多任务和多线程;n(2)连续的)连续的32位地址空间和先进的内存管理;位地址空间和先进的内存管理;n(3)对所有的可为进程共享的对象,解决了它)对所有的可为进程共享的对象,解决
20、了它的安全性问题;的安全性问题;n(4)内存映射文件;)内存映射文件;12.4.1 抢先式多任务和多线程抢先式多任务和多线程nWindows是一个多任务操作系统,它提供了一是一个多任务操作系统,它提供了一次运行多个应用程序的能力。次运行多个应用程序的能力。n Windows 3.x的多任务是一种由协作、软件方的多任务是一种由协作、软件方式产生的有限的非抢先式的多任务。式产生的有限的非抢先式的多任务。n Windows 95的多任务是一种抢先式多任务。的多任务是一种抢先式多任务。在抢先式多任务操作系统中,系统在运行的所在抢先式多任务操作系统中,系统在运行的所有进程之间对有进程之间对CPU时间进行
21、共享,从而保证每时间进行共享,从而保证每个进程都能频繁的访问处理器,并且实现指令个进程都能频繁的访问处理器,并且实现指令的连续执行。这样,每个的连续执行。这样,每个Win32进程都需要分进程都需要分配一个优先级,系统调度程序利用这种优先级配一个优先级,系统调度程序利用这种优先级来决定哪一时刻来决定哪一时刻。一个线程处于以下三种状态之一:正在执行,挂一个线程处于以下三种状态之一:正在执行,挂起,准 备 运 行。在 单 处 理 器 环 境 下(如起,准 备 运 行。在 单 处 理 器 环 境 下(如Windows 95),),同一时刻只能运行一个线程。同一时刻只能运行一个线程。为了在为了在Win3
22、2中支持多线程进程结构,中支持多线程进程结构,Win32在原在原来来Win16基础上增加了:基础上增加了:(1)对进程以及线程创建、操纵的支持;)对进程以及线程创建、操纵的支持;(2)对一个进程内线程之间的同步和同步对象的)对一个进程内线程之间的同步和同步对象的支持;支持;(3)一个统一的共享机制。)一个统一的共享机制。返回本节12.4.2 连续的地址空间和先进的内存管理连续的地址空间和先进的内存管理n(1)申请一块可移动的内存块。)申请一块可移动的内存块。n(2)锁定该内存块。因为)锁定该内存块。因为Windows引入了虚拟引入了虚拟内存管理,可以把内存块移动到硬盘交换文件内存管理,可以把内
23、存块移动到硬盘交换文件中,所以在使用内存块之前,必须将它锁定在中,所以在使用内存块之前,必须将它锁定在真正的内存真正的内存RAM之中,也就是告诉操作系统,之中,也就是告诉操作系统,现在这块内存暂时由应用程序来管理。现在这块内存暂时由应用程序来管理。n(3)对该内存块进行各种操作:如复制数据到)对该内存块进行各种操作:如复制数据到内存块。内存块。n(4)解锁内存,应用程序将对该内存的控制交)解锁内存,应用程序将对该内存的控制交予予Windows。下面给出一个程序片段,来说明内存管理函数的用法。下面给出一个程序片段,来说明内存管理函数的用法。HGLOBAL memHandle;/内存句柄内存句柄c
24、har far*lpMem;/假设长度为假设长度为memLenmemHandle=GlobalAlloc(GHND,memLen+1);/申请内存块,此申请内存块,此处未做返回结果检查,处未做返回结果检查,/事实上,申请内存有时会失败事实上,申请内存有时会失败memcpy(lpMem,string,textLen);/拷贝数据,其中拷贝数据,其中string为为一字符串变量,一字符串变量,textLen/是这个字符串的长度是这个字符串的长度GlobalUnlock(memHandle);/解锁内存解锁内存.GlobalFree(HGLOBAL)memHandle);/释放内存释放内存返回本节1
25、2.4.3 内存映射文件内存映射文件n内存映射文件是由一个文件到一块内存的映射。内存映射文件是由一个文件到一块内存的映射。Win32提供了允许应用程序把文件映射到一个提供了允许应用程序把文件映射到一个进程的函数(进程的函数(CreateFileMapping)。)。这样,文这样,文件内的数据就可以用内存读件内的数据就可以用内存读/写指令来访问,而写指令来访问,而不是用不是用ReadFile和和WriteFile这样的这样的I/O系统函数,系统函数,从而提高了文件存取速度。从而提高了文件存取速度。n这种函数最适用于需要读取文件并且对文件内这种函数最适用于需要读取文件并且对文件内包含的信息做语法分
26、析的应用程序,如对输入包含的信息做语法分析的应用程序,如对输入文件进行语法分析的彩色语法编辑器,编译器文件进行语法分析的彩色语法编辑器,编译器等。等。返回本节12.4.4 Win32s:Windows 3.x对对Win32 API的支持的支持nWin32s与与Win32是有区别的。是有区别的。Win32s的的s的含的含义是指子集(义是指子集(subset)。)。n运行在运行在Windows 3.x/Win32s系统上的系统上的Win32程程序支持序支持32位指针和位指针和32位寄存器,只需要在系统位寄存器,只需要在系统调用之前稍作形式替换。调用之前稍作形式替换。nWin32s子集同子集同Win
27、32相比,不支持多线程,高相比,不支持多线程,高级图形级图形API,异步文件异步文件I/O,Unicode和安全性;和安全性;而且它是运行于而且它是运行于16位的位的Windows系统上的。但系统上的。但是同是同Win16相比,有它的优越之处,目前在相比,有它的优越之处,目前在16位位Windows程序开发方面有相当的潜力。程序开发方面有相当的潜力。返回本节12.4.5 Win32编程基础编程基础nWin32数据类型数据类型n这里的数据类型指的是一些关键字,这些关键字定义了这里的数据类型指的是一些关键字,这些关键字定义了Win32中的函数中的有关参数和返回值的大小和意义。中的函数中的有关参数和
28、返回值的大小和意义。n这里需要解释一下的是句柄。句柄是这里需要解释一下的是句柄。句柄是Windows编程的一编程的一个关键性的概念,编写个关键性的概念,编写Windows应用程序总是要和各种应用程序总是要和各种句柄打交道。所谓句柄,就是一个惟一的数,用以标识句柄打交道。所谓句柄,就是一个惟一的数,用以标识许多不同的对象类型,如窗口、菜单、内存、画笔、画许多不同的对象类型,如窗口、菜单、内存、画笔、画刷和电话线路等。刷和电话线路等。n由于由于Windows是一个多任务操作系统,它可以同时运行是一个多任务操作系统,它可以同时运行多个程序或一个程序的多个副本。多个程序或一个程序的多个副本。n Win
29、dows不仅使用句柄来管理实例,也用它来管理窗不仅使用句柄来管理实例,也用它来管理窗口、位图、字体、元文件和图标等系统资源。口、位图、字体、元文件和图标等系统资源。Win32常用的数据类型有:常用的数据类型有:返回本节12.5 MFC编程编程n12.5.1 MFC类库概念和组成类库概念和组成n12.5.2 MFC应用程序框架应用程序框架n12.5.3 MFC的优点的优点n12.5.4 MFC对消息的管理对消息的管理返回首页12.5.1 MFC类库概念和组成类库概念和组成n类库是一个可以在应用中使用的相互关联的类库是一个可以在应用中使用的相互关联的C+类的集合。类的集合。n Microsoft提
30、供了一个基础类库提供了一个基础类库MFC,其中包含其中包含用来开发用来开发C+和和C+Windows应用程序的一组应用程序的一组类。基础类库的核心是以类。基础类库的核心是以C+形式封装了大部分形式封装了大部分的的Windows API。类库表示窗口、对话框、设类库表示窗口、对话框、设备上下文、公共备上下文、公共GDI对象如画笔、调色板、控制对象如画笔、调色板、控制框和其他标准的框和其他标准的Windows部件。这些类提供了部件。这些类提供了一个面向一个面向Windows中结构的简单的中结构的简单的C+成员函成员函数的接口。数的接口。MFC可分为两个主要部分:可分为两个主要部分:n基础类;基础类
31、;n宏和全程函数。宏和全程函数。基础类;基础类;nMFC中的类按功能来分可划分为以下几类:中的类按功能来分可划分为以下几类:n基类、应用程序框架类、应用程序类、命令相基类、应用程序框架类、应用程序类、命令相关类、文档关类、文档/视图类、线程类、可视对象类、窗视图类、线程类、可视对象类、窗口类、视图类、对话框类、属性表口类、视图类、对话框类、属性表、控制类、控制类、菜单类、设备描述表、绘画对象类、通用类、菜单类、设备描述表、绘画对象类、通用类、文件、诊断、异常、收集、模板收集、其他支文件、诊断、异常、收集、模板收集、其他支持类、持类、OLE2类、类、OLE基类、基类、OLE可视编辑包装可视编辑包
32、装程序类、程序类、OLE 可视编辑服务器程序类、可视编辑服务器程序类、OLE数数据传输类、据传输类、OLE对话框类、其他对话框类、其他OLE类和数据类和数据库类。库类。宏和全程函数。宏和全程函数。nMicrosoft基本宏和全程函数提供以下功能:基本宏和全程函数提供以下功能:数据类型、运行时刻对象类型服务、诊断服务、数据类型、运行时刻对象类型服务、诊断服务、异常处理、异常处理、CString格式化及信息框显示、消息格式化及信息框显示、消息映射、应用消息和管理、对象连接和嵌入映射、应用消息和管理、对象连接和嵌入(OLE)服务、标准命令和服务、标准命令和Windows IDs。约定:全程函数以约定
33、:全程函数以“Afx”为前缀,所有全程变量为前缀,所有全程变量都是以都是以“Afx”为前缀,宏不带任何特别前缀,为前缀,宏不带任何特别前缀,但是全部大写。但是全部大写。n例例12-1:CObject类的定义。类的定义。/class CObject is the root of all compliant objectsclass CObjectpublic:/Object model(types,destruction,allocation)virtual CRuntimeClass*GetRuntimeClass()const;virtual CObject();/virtual destr
34、uctors are necessary/Diagnostic allocationsvoid*PASCAL operator new(size_t nSize);void*PASCAL operator new(size_t,void*p);void PASCAL operator delete(void*p);#if defined(_DEBUG)&!defined(_AFX_NO_DEBUG_CRT)/for file name/line number tracking using DEBUG_NEWvoid*PASCAL operator new(size_t nSize,LPCSTR
35、 lpszFileName,int nLine);#endif/Disable the copy constructor and assignment by default so you will get/compiler errors instead of unexpected behaviour if you pass objects/by value or assign objects.protected:CObject();private:CObject(const CObject&objectSrc);/no implementationvoid operator=(const CO
36、bject&objectSrc);/no implementation/Attributespublic:BOOL IsSerializable()const;BOOL IsKindOf(const CRuntimeClass*pClass)const;/Overridablesvirtual void Serialize(CArchive&ar);/Diagnostic Supportvirtual void AssertValid()const;virtual void Dump(CDumpContext&dc)const;/Implementationpublic:static cons
37、t AFX_DATA CRuntimeClass classCObject;#ifdef _AFXDLLstatic CRuntimeClass*PASCAL _GetBaseClass();#endif;CObject类为派生类提供了下述服务:类为派生类提供了下述服务:n(1)对象诊断。)对象诊断。n(2)运行时访问类的信息。)运行时访问类的信息。n(3)对象持续性。)对象持续性。n下面举个具体的例子来说明下面举个具体的例子来说明MFC所提供的应用程序框架,程序如例所提供的应用程序框架,程序如例12-2所示。所示。n例例12-2:应用程序框架示例。应用程序框架示例。#include/deri
38、ved an application classclass CMinMFCApp:public CWinApppublic:BOOL InitInstance();/Derive the main window classclass CMainWindow:public CFrameWndpublic:CMainWindow();DECLARE_MESSAGE_MAP();BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd)END_MESSAGE_MAP()/*CMinMFCApp Member Functions*/BOOL CMinMFCApp:InitInst
39、ance()m_pMainWnd=new CMainWindow();m_pMainWnd-ShowWindow(m_nCmdShow);m_pMainWnd-UpdateWindow();return TRUE;/*CMainWindow member functions*/CMainWindow:CMainWindow()/constructorCreate(NULL,Min MFC Application,WS_OVERLAPPEDWINDOW,rectDefault,NULL,NULL);/*an instance of type CMinMFCApp*/CMinMFCApp This
40、App;返回本节12.5.2 MFC应用程序框架应用程序框架nMFC AppWizard生成的应用程序包含以下要素。生成的应用程序包含以下要素。n(1)WinMain()函数。函数。Windows要求应用程序必须有要求应用程序必须有一个一个WinMain()函数。函数。n(2)应用程序类)应用程序类CMyFirstApp。该类的每一个对象代该类的每一个对象代表一个应用程序。表一个应用程序。n(3)应用程序启动。)应用程序启动。n(4)成员函数)成员函数CMyFirstApp:InitInstance()。n(5)成员函数)成员函数CWinApp:Run()。n(6)CMainFrame类。类。
41、n(7)文档与视图类。)文档与视图类。n(8)关闭应用程序。)关闭应用程序。返回本节12.5.3 MFC的优点的优点nMicrosoft MFC具有以下不同于其他类库的优势:具有以下不同于其他类库的优势:n完全支持完全支持Windows所有的函数、控件、消息、所有的函数、控件、消息、GDI基本图形函数、菜单及对话框。基本图形函数、菜单及对话框。n使用与传统的使用与传统的Windows API同样的命名规则,同样的命名规则,即匈牙利命名法。即匈牙利命名法。n进行消息处理时,不使用易产生错误的进行消息处理时,不使用易产生错误的switch/case语句,所有消息映射到类的成员函语句,所有消息映射到
42、类的成员函数,这种直接消息到方法的映射对所有的消息数,这种直接消息到方法的映射对所有的消息都适用。都适用。返回本节12.5.4 MFC对消息的管理对消息的管理n1MFC对消息的处理对消息的处理n2消息的发送消息的发送1MFC对消息的处理对消息的处理nMFC不使用用不使用用C语言编写语言编写Windows程序时用的程序时用的易产生错误的易产生错误的switch/case语句,而采用一种消语句,而采用一种消息映射机制来决定如何处理特定的消息。这种息映射机制来决定如何处理特定的消息。这种消息映射机制包括一组宏,用于标识消息处理消息映射机制包括一组宏,用于标识消息处理函数、映射类成员函数和对应的消息等
43、。函数、映射类成员函数和对应的消息等。n例例12-3:消息处理函数例子。消息处理函数例子。class CMainFrame:CFrameWndpublic:CMainFrame();protected:/AFX_MSG(CMainFrame)afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnEditCopy();afx_msg void OnClose();/AFX_MSGDECLARE_MESSAGE_MAP();n例例12-4:使用用户自定义消息。使用用户自定义消息。#include#define CM_A
44、PPLE(WM_USER+0)#define CM_ORANGE(WM_USER+1)class CMainFrame:CFrameWndpublic:CMainFrame();protected:afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnClose();/handle user select appleafx_msg LRESULT CMApple(WPARAM wParam,LPARAM lParam);/handle user select orangeafx_msg LRESULT CMOran
45、ge(WPARAM wParam,LPARAM lParam);DECLARE_MESSAGE_MAP();相应的消息映射如下:相应的消息映射如下:BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)ON_WM_CREATE()ON_MESSAGE(CM_APPLE,CMApple)ON_MESSAGE(CM_ORANGE,CMOrange)ON_WM_CLOSE()END_MESSAGE_MAP()2消息的发送消息的发送nWindows应用程序允许应用程序向自己发送消应用程序允许应用程序向自己发送消息、向其他应用程序发送消息,甚至可以向息、向其他应用程序发送消息,甚
46、至可以向Windows操作系统本身发送消息(比如要求关操作系统本身发送消息(比如要求关闭操作系统或重新启动操作系统)。闭操作系统或重新启动操作系统)。Windows提供了三个提供了三个API函数用于发送消息,这三个函数函数用于发送消息,这三个函数是:是:SendMessage()、PostMessage()和和SendDlgItemMessage()。SendMessage()用于向窗口发送消息,该函数说明如下:用于向窗口发送消息,该函数说明如下:LRESULT SendMessage(HWND hWnd,/消息要发往的窗口的句消息要发往的窗口的句柄柄UINT Msg,/要发送的消息要发送的消
47、息WPARAM wParam,/消息的第一个参数消息的第一个参数LPARAM lParam/消息的第二个参数消息的第二个参数);PostMessage()函数说明如下:函数说明如下:BOOL PostMessage(HWND hWnd,/消息发往的窗口消息发往的窗口UINT Msg,/要发送的消息要发送的消息WPARAM wParam,/消息的第一个参数消息的第一个参数LPARAM lParam/消息的第二个参数消息的第二个参数);nSendDlgItemMessage()函数用于向对话框的函数用于向对话框的某个控制发送消息,函数声明如下:某个控制发送消息,函数声明如下:LONG SendDlgItemMessage(HWND hDlg,/对话框句柄对话框句柄int nIDDlgItem,/对话框控件的对话框控件的IDUINT Msg,/要发送的消息要发送的消息WPARAM wParam,/消息的第一个参数消息的第一个参数LPARAM lParam/消息的第二个参数消息的第二个参数);返回本节