GetMessage()有点像特殊版本的WaitForSingleObject(),它等待消息而不是核心对象,一旦调用GetMessage(),除非有一个消息真正进入消息队列之中,否则它不会返回。问题是,如果你正在使用WaitForSingleObject()或WaitForMultipleObjects()等待某个对象被激发,你根本无法回到主消息循环中去。
MsgWaitForMultipleObjects()函数类似WaitForMultipleObjects(),但它会在“对象被激发”或“消息到达队列”时被唤醒而返回。MsgWaitForMultipleObjects()多接收一个参数,允许指定哪些消息是观察对象。
DWORD MsgWaitForMultipleObjects(
DWORD nCount, // 表示pHandles所指的handles数组的元素个数,最大容量是MAXIMUM_WAIT_OBJECTS
LPHANDLE pHandles, // 指向一个由对象handles组成的数组,这些handles的类型不需要相同
BOOL fWaitAll, // 是否等待所有的handles被激发才返回
DWORD dwMilliseconds, // 超时时间
DWORD dwWakeMask // 欲观察的用户输入消息类型
);
参数
dwWakeMask| Value | Meaning |
|---|---|
| QS_ALLEVENTS | An input, WM_TIMER, WM_PAINT, WM_HOTKEY, or posted message is in the queue. |
| QS_ALLINPUT | Any message is in the queue. |
| QS_ALLPOSTMESSAGE | A posted message (other than those listed here) is in the queue. |
| QS_HOTKEY | A WM_HOTKEY message is in the queue. |
| QS_INPUT | An input message is in the queue. |
| QS_KEY | A WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, or WM_SYSKEYDOWN message is in the queue. |
| QS_MOUSE | A WM_MOUSEMOVE message or mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on). |
| QS_MOUSEBUTTON | A mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on). |
| QS_MOUSEMOVE | A WM_MOUSEMOVE message is in the queue. |
| QS_PAINT | A WM_PAINT message is in the queue. |
| QS_POSTMESSAGE | A posted message (other than those just listed) is in the queue. |
| QS_SENDMESSAGE | A message sent by another thread or application is in the queue. |
| QS_TIMER | A WM_TIMER message is in the queue |
返回值
WAIT_TIMEOUT :因时间终了而返回
WAIT_OBJECT_0 :当bWaitAll是TRUE
WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount – 1) :bWaitAll是FALSE,将返回值减去WAIT_OBJECT_0,就表示数组中哪
一个handle被激发了
WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount – 1) :等待的对象中有任何mutexes
WAIT_FAILED :函数失败时返回该值,可以使用GetLastError()找出失败的原因
WAIT_OBJECT_0 + nCount :消息到达队列
MsgWaitForMultipleObjects()的正确使用方式是改写主消息循环,使得激发状态的handles得以像消息一样被对待。通常程序中只会有一个地方调用MsgWaitForMultipleObjects(),而这个调用存在于消息循环中。
注意:
1. 在收到WM_QUIT之后,Windows仍然会传送消息给你,如果要在收到WM_QUIT之后等待所有线程结束,必须继续处理你的消息,否则窗口会变得反应迟钝,而且没有重绘能力。
2.MsgWaitForMultipleObjects()不允许handles数组中有缝隙产生。所以当某个handle被激发了时,应该在下一次调用MsgWaitForMultipleObjects之前先把handles数组做个整理、紧压,不要只是把数组中的handle设为NULL
3.如果有另一个线程改变了对象数组,而那是你正在等待的,那么需要一种方法,可以强迫MsgWaitForMultipleObjects返回,并重新开始,以包含新的handle
本文详细介绍了MsgWaitForMultipleObjects函数的使用方法及其参数意义,包括如何通过该函数实现对象激发与消息到达的同步处理。同时,文章还强调了在特定场景下使用此函数时需要注意的关键事项。
742





