消息机制

王朝百科·作者佚名  2010-01-16  
宽屏版  字体: |||超大  

消息机制是Windows应用程序的核心。在Windows中发生的一切都可以用消息来表示,消息用于告诉操作系统发生了什么,所有的Windows应用程序都是消息驱动的,

在Windows中,不同的消息由应用程序的不同部分进行处理。MFC库将很多底层的消息都屏蔽了,使用户更加方便、简易地处理消息。例如,用户接收到诸如移动鼠标键(WM_MOUSEMOVE)消息或单击鼠标键(WM_LRBUTTONDOWN)消息时不必处理窗口和鼠标的重画工作,MFC及应用程序框架会替用户做这些工作。在使用MFC进行编程时,用户只需处理一些高层的消息,例如,“用户在单击窗口中的OK按扭”,“用户现在选中了下拉列表框中的第五项”等等,这样就大大减轻了程序员的负担。

一个消息是由消息的名称(UINT)和两个参数(WPARAM, LPARAM)组成。消息的参数中包含有重要的信息。例如对鼠标消息而言,LPARAM中一般包含鼠标的位置信息,而WPARAM参数中包含了发生该消息时,SHIFT、CTRL等键的状态信息,对于不同的消息类型来说,两个参数也都相应地具有明确意义。

消息与输入焦点

Windows是一个以消息为导向的系统,应用程序只能被动地等待用户按键的消息,不能主动地去读键盘的状态,也就是说,每当键盘上有个键被按下,系统就会发出一个按键消息给窗口,告诉它某个键被按下去了,只要鼠标移动一下,系统也会发出相应的消息,并把鼠标的坐标信息传给窗口。

Windows可以同时执行许多程序,但键盘只有一个,怎么判断由哪个窗口接收键盘及鼠标的消息呢?采用“输入焦点”(inpuut focus)技术可以解决这个问题。只要某个窗口取得输入焦点,它不但会被提升到屏幕的最前面,颜色也会有所不同,所有的键盘消息就会导向该窗口,该窗口也成为“活动窗口”。

窗口如何取得输入焦点?通常被鼠标单击的窗口会得到输入焦点,除此之外,程序本身也可以利用SetFocus()来指定哪个窗口拥有输入焦点。

CWnd* CWnd::SetFocus();

如果调用某窗口的SetFocus()成员函数,该窗口就可以取得输入焦点,该函数返回前一个拥有输入焦点的窗口。

如果某个窗口的输入焦点被抢走,Windows系统就会发出WM_KILLFOCUS消息给这个失去输入焦点的窗口,同时还会告诉该窗口下一个取得输入焦点的窗口的指针。而获得输入焦点的窗口则会收到WM_SETFOCUS消息。

消息响应函数分别为:

afx_msg void OnKillFocus(CWnd* pNewWnd);

其中的参数为得到输入焦点的窗口的指针。

Afx_msg void OnSetFocus(CWnd* pOldWnd);

其中的参数为失去输入焦点的窗口的指针。

消息的分类

Windows系统预定义了许多消息,每个消息都拥有一个宏定义,即用形象的字符串来标识消息,一系列#define 语句将消息与特定数值联系起来,可以在头文件WinUser.h中找到这些宏定义,例如

#define WM_PAINT 120

可以在程序中通过消息名“WM_PAINT”来访问它。其他消息如:

#define WM_MOUSEMOVE 0x0200

#define WM_LBUTTONDOWN 0x0201

#define WM_LBUTTONUP 0x0202

#define WM_LBUTTONDBLCLK 0x0203

#define WM_RBUTTONDOWN 0x0204

#define WM_RBUTTONUP 0x0205

#define WM_RBUTTONDBLCLK 0x0206

#define WM_MBUTTONDOWN 0x0207

#define WM_MBUTTONUP 0x0208

#define WM_MBUTTONDBLCLK 0x0209

系统定义的消息有不同的前缀,不同的前缀有不同的含义。

1. 标准的Windows消息

除了WM_COMMAND消息,所有以WM_为前缀的消息都是标准的Windows消息,如窗口、鼠标移动、窗口大小改变等,程序启动或退出甚至每一段固定的时间都会产生标准Windows消息。如

1) 键盘消息

对于窗口而言,来自用户的按键输入可分为两类,一类是系统键(system key),另一类则是非系统键。凡是ALT和其它键一同按下的组合称为“系统键”,窗口收到系统键之后,会自动地将它解释成系统事件,或者查阅键盘加速表,将系统键翻译成加速表指定的信息。如:ALT+F4的组合会迫使窗口关闭,“ALT+字母”的组合可能会拉下某个菜单。

当用户按下某个键时,Windows系统会先发出WM_KEYDOWN消息给窗口,这个消息的意思是“按键被压下去”。接着Windows系统会发出WM_CHAR给同一个窗口,这个消息代表的意义是“系统送来某个字符”,如果用户放开此键,Windows系统会发出WM_KEYUP消息,表示“按键被放开”。如果用户一直按住某个键不放,经过一段时间之后会产生“连发”的效果,造成Windows系统不停地发出WM_KEYDOWN与WM_CHAR消息。

计算机内部以ASCII码的规则来记录所有的英文字母和数字符号。不过不是键盘上每个按键都可以对应成ASCII码中的字符,如大小写键、CTRL键、F1到F12键等。

每个按键都有对应的扫描码,PC BIOS收到键盘的中断消息后,会自动将扫描码翻译成ASCII码,但有些控制键无法译成ASCII码,如Page UP、Page Down等。Windows定义了一套与硬件无关的“虚拟键码”来表示键盘上所有的按键,如A键就是VK_A、ESC键就是VK_ESC、F1键是VK_F1、ALT键是VK_MENU等。因为“虚拟键码”定义的规则与硬件无关,所以有些虚拟键在通常的键盘上根本就找不着。

#define VK_LBUTTON 0x01

#define VK_RBUTTON 0x02

#define VK_CANCEL 0x03

#define VK_MBUTTON 0x04 /* NOT contiguous with L & RBUTTON */

#define VK_BACK 0x08

#define VK_TAB 0x09

#define VK_CLEAR 0x0C

#define VK_RETURN 0x0D

#define VK_SHIFT 0x10

#define VK_CONTROL 0x11

#define VK_MENU 0x12

#define VK_PAUSE 0x13

#define VK_CAPITAL 0x14

#define VK_F1 0x70

#define VK_F2 0x71

#define VK_F3 0x72

#define VK_F4 0x73

#define VK_F5 0x74

#define VK_F6 0x75

#define VK_F7 0x76

#define VK_F8 0x77

#define VK_F9 0x78

#define VK_F10 0x79

#

#define WM_CHAR 0x0102 //字符消息

WM_CHAR也称为键盘消息,如果某窗口拥有输入焦点,当用户在应用程序运行时按下一个键时,系统就会产生一个键盘消息WM_CHAR,告诉此窗口键盘上哪个键被按下了。该消息的处理函数为OnChar()。具体形式为:

afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)

各参数含义为:

nChar: 键盘所输入的ASCII码。

nRepCnt: 按键的重复次数,当用户按下某个键不放时,该参数将持续增加。

nFlag: 用于传递按键的其它一些信息,如扫描码,上一次按键状态等。具体如下:

字节 说明

0-7 键盘扫描码

8 此按键为扩充按键,如F1,F12等功能键,此字节等于1时为真

9-12 保留

13 此字节为1表示按下键的同时,ALT键也被按住了

14 前一个按键状态。此字节为1代表信息在按键被按下之前就送出来了

15 此字节为1表示这个按键已经被放开了,反之就表示还被按着

此外还有两个常用的键盘消息:WM_KEYDOWN和WM_KEYUP.

WM_KEYDOWN消息是当用户按下一个非系统键时产生的,非系统键就是不按下ALT键时的按键。

WM_KEYUP 消息是当用户释放一个非系统键时产生的。

2) 鼠标消息

① #define WM_MOUSEMOVE 0x0200 //鼠标移动消息

当鼠标在某个窗口内移动时,Windows会不断地发出鼠标移动消息WM_MOUSEMOVE,并把鼠标的最新位置传给该窗口。如果在窗口的范围内按下鼠标左键,系统就会发出“按下左键”的WM_LBUTTONDOWN消息给该窗口,等到用户放开按键后,再发出“放开左键”的WM_LBUTTONUP消息给该窗口。

鼠标移动消息的消息响应函数为:

afx_msg void OnMouseMove(UINT nFlags, CPoint point)

其中的参数含义如下:

UINT nFlag:此事件发生时,鼠标按键、键盘控制键的状态,可以是以下值的任意组合:

当用户按下CTRL键时,nFlags设置为MK_CONTROL。

当用户按下鼠标左键时,nFlags设置为MK_LBUTTON。

当用户按下鼠标中键时,nFlags设置为MK_MBUTTON

 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝百科 版权所有