1、第2章 Windows编程与MFC,程序运行结果展示,引言,理解MFC的概念和作用(了解) 理解Windows应用程序的特点和运行机制(了解) 理解消息的概念,掌握编写Windows应用程序过程中所涉及到的消息的种类、特点、以及消息的发送和接收的基本过程和机制(了解) 弄清所创建的应用程序中所产生的主要类及其功能、组成文件和程序的框架结构(了解) 掌握消息映射、消息处理函数的概念及二者间的关系(了解) 掌握利用属性窗口来增加、修改和删除窗口消息处理函数的方法和步骤,并理解程序代码的变化过程和特点(重点),在编写Windows应用程序时,可采用两种方法,第一种方法是直接调用Windows API
2、(Windows Application Programming Interface,即Windows应用程序接口)函数的编程方法。第二种方法是基于MFC(Microsoft Foundation Class,微软基础类库)的程序设计方法。,2.1 Windows应用程序的特点 与运行机制,2.1.1 Windows应用程序的特点,Windows应用程序具有下列几个特点。(1)标准的图形用户界面,如窗口、菜单、按钮和列表框等;(2)应用程序与硬件无关的特性,对于同一类硬件,不论厂家和型号程序都无需进行任何修改就可以运行;(3)所有的Windows应用程序都是消息驱动机制,也就是说,Window
3、s程序是通过操作系统发送的消息来处理用户的输入的。,2.1.2 事件与消息的概念,事件:在Windows操作系统中,无论是系统产生的动作或是用户在运行应用程序中发出的操作动作都称为事件(Events), 消息(Message)就是用于描述某个事件发生的信息。消息的响应其实质就是事件的响应。在Visual C+ 2005编程过程中,系统规定每一种消息用一个特定的值表示,为了便于记忆,系统针对每一个消息值定义了对应的符号常量,常用的消息及对应的含义如表2.1所示。,表2.1 Windows编程中常用的消息值及对应含义,在应用程序运行中,消息是最重要的通信手段,在编程过程中,Windows中的每一个
4、消息中所包括的所有信息用一个MSG结构体来表示,MSG结构体的定义如下所示:typedef struct tagMSG HWND hwnd; /获取消息的窗口句柄UINT message; /消息标识符(用对应整数表示)WPARAM wParam; /记录消息附加信息的字参数LPARAM lParam; /记录消息附加信息的长字参数DWORD time; /消息被发送到消息队列的时间POINT pt; /消息发送时的光标所在位置 MSG;,2.2.2 Windows编程中常用的句柄,句柄(Handle)是Windows编程中的一个重要概念。 句柄是一个4字节长的整数值,是应用程序中不同对象的编
5、号,每个对象的句柄是惟一的。应用程序通过句柄来访问相应的对象。,表2.4 Windows编程中常用的句柄类型,2.3 MFC应用程序的类和文件,2.3.1 类说明,CAboutDlg: “关于”对话框的对话框类 CChildFrame:子框架窗口类 CMainFrame:主框架窗口类 CMyExpApp:应用程序类 CMyExpDoc:文档类 CMyExpView:视图类,在工程中,每个类都拥有自己的类定义文件(也称为头文件)(*.h)和类实现文件(*.cpp)。类定义文件主要用来保存各种类的定义;类实现文件主要用来保存各种类的成员函数的实现代码。,2.3.2 文件说明,应用程序模版在自动生成
6、应用程序框架时,除了生成上面介绍的各个类的头文件和实现文件外,还生成了一些为建立应用程序所需要的其他文件。,下面分别对这些文件加以说明: (1)MyExp.sln:Visual Studio方案文件。 (2)MyExp.suo:项目的用户选择文件。 (3)MyExp.vcproj:Visual C+ 项目文件。 (4)MyExp.ncb:Visual C+ IntelliSence数据库。 (5)MyExp.rc:资源定义文件,包含了程序资源的定义,其中保存了应用程序中使用到的各种资源的信息,包括存贮在文件夹中的图标、位图和光标等。 (6)Resource.h:标准的头文件,它包含了所有资源I
7、D号的定义,与MyExp.rc文件相对应。 (7)StdAfx.h:包含在所有AppWizard程序中的标准头文件,用于生成预编译信息。 (8)StdAfx.cpp:包含在所有AppWizard程序中,它包含所有标准include文件。,(9)resMyExp.rc2:资源定义文件,包含了用Visual C+不能直接编辑的资源。它可以将所有不能由资源编辑器编辑的资源放置到这个文件中。 (10)resMyExpDoc.ico:文件中包含了打开文档时所用的图标文件。 (11)resMyExp.ico:应用程序的图标文件。它包含在资源文件MyExp.rc中。 (12)resToolbar.bmp:用
8、于创建工具栏按钮的位图文件。初始工具栏和状态栏是在主边框窗口类中构造的。 (13)ReadMe.txt:包含了对所有该程序文件的解释信息,并说明了所有创建的类。 (14)MyExp.ilk:增量链接文件。 (15)MyExp.pdb:程序数据库文件,保存着调试和项目状态信息,使用这些信息可以对程序的调试配置进行增量链接。,2.4 Windows消息,2.4.1 事件驱动的程序设计,所有的Windows应用程序都是由消息驱动的(或事件驱动)事件驱动系统把用户的动作如鼠标单击和键盘操作定义为事件,也把系统操作如更新屏幕定义为事件。消息不仅可由Windows发出,也可由应用程序本身或其他程序产生,应
9、用程序还可以自定义消息。,Windows为每一个应用程序都维护一个或多个消息队列,发送到每个程序窗口的消息都排成一个队列,这种队列称为消息队列。 应用程序轮流检测消息队列中的消息,但只对它感兴趣的消息作出回应处理,其他消息由默认的窗口函数处理。,Windows的消息系统的三个部分:消息队列:存放应用程序执行时产生的消息。消息循环:应用程序利用循环机制,不断从消息队列中检索消息并进行处理,直到检索到运行结束的消息为止。消息处理:应用程序通过编写相应的消息处理函数来实现消息对应的特定功能。,Windows系统中的消息主要有3种类型:标准的Windows消息控件消息命令消息,2.4.2 标准的Win
10、dows消息,所有以WM_为前缀的消息(WM_COMMAND消息除外)都是标准的Windows消息 1. 键盘消息 在程序运行过程中,当用户对键盘进行操作时,会产生对应的消息,系统将把此消息发送给对应的窗口。当键盘的某个键被按下时将产生WM_CHAR消息,这个消息带有字符代码值、重复次数和先前状态码3个参数。,WM_CHAR消息的处理函数为OnChar(),此函数的原型为:afx_msg void OnChar(UINT nChar,UINT nRepCnt,UINT nFlags);参数说明: nChar是所按键的字符代码值。 nRepCnt是重复的次数,它表示用户按键时重复击键的次数。 n
11、Flags表示扫描码、先前键状态和键转换状态等,其参数值功能描述见表2.5。,2. 鼠标消息在程序运行过程中,当用户对鼠标进行操作时,会产生对应的消息,系统将把此消息发送给对应的窗口。 在Windows中处理鼠标操作的方法基本上有3种: (1)单击(Click):表示按一下鼠标的左键或右键,然后释放; (2)双击(Double Click):表示快速连续按两下鼠标左键; (3)拖动(Drag):指按住鼠标的按键后,再移动鼠标。,所有鼠标的操作都会产生相应的消息。 鼠标的消息类型有: (1)WM_MOUSEMOVE:表示鼠标移动。 (2)WM_LBUTTONDOWN:表示按下鼠标左键。 (3)W
12、M_LBUTTONUP:表示抬起鼠标左键。 (4)WM_LBUTTONDBLCLK:表示双击鼠标左键。 (5)WM_MBUTTONDOWN:表示按下鼠标中间键。 (6)WM_MBUTTONUP:表示抬起鼠标中间键。 (7)WM_MBUTTONDBLCLK:表示双击鼠标中间键。 (8)WM_RBUTTONDOWN:表示按下鼠标右键。 (9)WM_RBUTTONUP:表示抬起鼠标右键。 (10)WM_RBUTTONDBLCLK:表示双击鼠标右键。,3. 窗口消息 所有窗口的变化包括 窗口内容重绘WM_PAINT、窗口最大化WM_MAXIMIZE、窗口最小化WM_MINIMIZE、 窗口改变大小WM
13、_RESIZE、 窗口滚动WM_HSCROLL、WM_VSCROLL 窗口定时WM_TIMER等消息,这些消息所带参数各不相同。,2.4.3 控件消息控件是一个小的子窗口,其隶属于其他窗口(如对话框等),能够接受操作并向父窗口发送消息。常见的控件有按钮、列表框、编辑框、复合框和滚动条等。控件消息分为两类: (1)从控件传给消息,通常这类消息的前缀的最后一个字符为N; (2)由系统发送给控件的消息,这类消息的前缀的最后一个字符为M。,2.4.4 命令消息命令消息主要包括由用户界面对象发送的WM_COMMAND消息,用户界面对象是指菜单、工具栏和快捷键等。 1. 用户界面对象菜单、工具栏和快捷键等
14、都是可以产生命令消息的用户界面对象。每个这样的对象都被分配了一个ID号,通过给对象和命令分配同一个ID号将用户界面对象和命令联系在一起,2. 命令ID在MFC中定义了一些命令消息,MFC应用程序中的标准菜单的ID号都已经在MFC中定义(定义在头文件afxres.h)过了 3. 命令目标当用户界面对象被单击后将调用处理函数来执行所产生的命令。Windows把非命令消息的消息直接发送给窗口,窗口中用于处理这些消息的处理函数将被调用。,Visual C+ 2005中存在几种系统已经定义的消息分类,如有必要用户也可以自定义消息用于特定操作。通过不同的消息前缀能够判断出产生消息的对象类型。,表2.7 W
15、indows消息前缀和对象类型,2.6 消息映射与消息处理函数,2.6.2 消息映射与消息处理函数的概念,消息映射就是将消息或命令发送到程序员为处理消息所编写的函数中,使其对消息进行处理。 在Visual C+ 2005中,用户只需要编写对于该消息发生响应的函数,而Visual C+ 2005内部将自动为用户添加一个消息映射关系。 通过消息映射,消息就和它的处理函数对应起来 消息处理函数指的是与某个消息对应的函数,2.6.3 管理消息处理函数,在Visual C+ 2005环境中,可以利用属性窗口管理消息处理函数。属性窗口作为一个单独的子窗口,可以查看和修改编辑器和设计器中被选对象的属性和事件
16、,可以对工程、类、函数等的属性进行管理,其中包括对函数的重载、消息映射等功能。,1.用属性窗口增加一个消息处理函数 想为工程中的一个类CMyExpView添加名为WM_LBUTTONDOWN的消息,相应的步骤如下所示: 在“类视图”中,单击该类。 在“属性”窗口中,单击“消息”按钮。 如果项目有消息处理程序,处理程序的名称将出现在右列中消息的旁边。 如果消息没有处理程序,则在“属性”窗口中单击右列中的单元格以将建议的处理程序名称显示为“OnLButtonDown”(如图2.7所示)。,单击建议的名称以添加该函数的存根代码。 若要编辑消息处理程序,请在“类视图”中双击消息并在源窗口中编辑代码。,
17、5. 删除窗口消息处理函数,用属性窗口删除消息处理函数的方法很简单: 遵循与添加一个消息函数相同的步骤找到属性窗口,处理程序的名称OnLButtonDown()将出现在右列中消息WM_LBUTTONDOWN的旁边。单击消息处理函数并选择OnLButtonDown,函数的代码被注释掉。,2.9 综合实例,【例2.1】用键盘移动窗口中的字符,程序的运行结果如图2.9所示。,程序的实现过程如下: (1)按照【例1-2】的方法利用MFC应用程序模版生成单文档应用程序,项目名称为Move。 (2)在MoveView.h中修改视图类的定义,添加一个CRect类型的变量记录指定显示位置的信息。(操作方法) (3)在MoveView.cpp中视图类的构造函数对变量MoveRect进行初始化。 (4)在MoveView.cpp中修改视图类的OnDraw()函数。 (5)在视图类中添加消息处理函数OnKeyDown(),并添加相应处理程序代码。,