龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > C/C++开发 >

windows消息和消息队列实例详解(2)

时间:2014-10-25 02:26来源:网络整理 作者:网络 点击:
分享到:
应用程序可以通过创建自定义的消息,用来和自己的窗口和其他进程通讯。如果应用程序创建了自己的消息,窗口处理函数可以解析这些信息,并作出相应

应用程序可以通过创建自定义的消息,用来和自己的窗口和其他进程通讯。如果应用程序创建了自己的消息,窗口处理函数可以解析这些信息,并作出相应的处理。

消息标识符值的取值范围:

该系统保留了一个消息范围,从0x0000到0x03FF(0x03FF等于WM_USER -1)范围. 这个范围内的值为系统定义的消息。应用程序不能使用这些值作为自己的自定义消息。

从0x0400(数值WM_USER)到0x7FFF的值是为应用程序保留的。应用程序可以使用这个范围内的值来定义自己的消息。

如果你的操作系用的版本(windows version)主版本为4.0版,你还可以使用0x8000(WM_APP)到0xBFF之间的值来定义自己的消息。

除此之外,应用程序还可以调用RegisterWindowMessage函数注册一个消息时,操作系统会返回一个介于0xC000和0xFFFF之间的一个消息标识符。并且保证这个返回值是系统唯一的。因此,可以避免和其他应用程序使用的消息相冲突。

3. 消息派发

windows使用两种方法将消派发到一个窗口消息处理函数:一是将消息放到消息队列(先进先出队列),二是不放到消息队列,直接发送到窗口消息处理函数,让窗口处理函数来处理消息。

派发到消息队列的消息被称为排队消息(Queued messages)。它们主要是用户输入事件,比如说鼠标或键盘消息盘,有WM_MOUSEMOVE消息,WM_LBUTTONDOWN,WM_KEYDOWN,和WM_CHAR消息。还有一些其他的,包括WM_TIMER,WM_PAINT,以及WM_QUIT。大多数其他的消息息,这是直接发送到窗口过程,被称为非队列消息(non queued messages)。

(1) 队列(Queued)消息

windows可同时显示任意数量的窗口。此时,系统使用消息队列来将键盘和鼠标事件正确的派发到正确的窗口。

windows维护着一个系统消息队列,以及分别为每个GUI线程维护一个各自的线程消息队列。为了避免非GUI线程的创建线程消息队列的开销,所有线程创建初始化时,均不创建消息队列。只有当线程第一次调用GDI函数时,系统才会为线程创建消息队列。所以那些非GUI线程是没有消息队列的。

每当用户移动鼠标,点击按钮或键盘时,鼠标或键盘的设备驱动程序会将输入转换成消息,并将消息放在系统消息队列里。删windows会检查自己的消息队列,如果消息队列不为空,则每次取出并删除一个消息,然后确定消息的目标窗口,然后把消息放到创建这个窗口的线程的线程消息队列里。线程的消息队列接收由线程创建的窗口的所有的鼠标和键盘消息。然后线程会从队列中删除信息,并告诉系统把它们派发到对应的窗口消息处理函数。

除了WM_PAINT, WM_TIMER和WM_QUIT消息以外,系统总是派发放在在消息队列的末尾的消息。这将保证让一个窗口以first-in, first-out的顺序接收消息。WM_PAINT,WM_TIMER,和WM_QUIT消息,会一直被保存在队列中,只有在队列中没有其他消息时才会被派发到窗口消息处理函数。此外,同一个窗口的多个WM_PAINT消息被合并成一个WM_PAINT消息,客户区的所有无效部分也会被合并。这样是为了减少窗口重绘客户区的次数。

精彩图集

赞助商链接