函数功能描述:阻塞时仍可以响应消息返回的线程同步API
函数原型
DWORD MsgWaitForMultipleObjectsEx(
DWORD nCount, // 句柄数组中句柄数目
LPHANDLE pHandles, // 指向句柄数组的指针
DWORD dwMilliseconds, // 以毫秒计的超时值
DWORD dwWakeMask, // 要等待的输入事件类型
DWORD dwFlags // 等待标志
);
参数
nCount
指定pHandles指向的数组中的对象句柄数目。最大对象数目是MAXIMUM_WAIT_OBJECTS-1
pHandles
指向一个对象句柄数组。要得到可以使用的对象句柄类型清单,请查看备注部分。数组中可以包含多种对象类型。 Windows NT: 数组中句柄必须拥有SYNCHRONIZE访问权。要得到更多相关信息,请查阅MSDN中Standard Access Rights。
dwMilliseconds
指定以毫秒计的超时值。即使参数dwWakeMask与dwFlags中指定的条件未满足,超时后函数仍然返回。如果dwMilliseconds值为0,函数测试指定的对象状态并立即返回。如果dwMilliseconds值为INFINITE,函数超时周期为无穷大。
dwWakeMask
指定被加到对象句柄数组中的输入事件对象句柄的对象类型。这个参数可以是下面列出值的任意组合:
| 含义 |
| WM_TIMER, WM_PAINT, WM_HOTKEY输入消息或登记消息(posted message)在消息队列中 |
| 任何消息在消息队列中 |
| 登记消息(在此处列出的除外)在消息队列中 |
| WM_HOTKEY消息在消息队列中 |
| 输入消息在消息队列中 |
| WM_KEYUP,WM_KEYDOWN,WM_SYSKEYUP或WM_SYSKEYDOWN消息在消息队列中 |
| WM_MOUSEMOVE消息或鼠标点击消息(WM_LBUTTONUP,WM_RBUTTONDOWN等)在消息队列中 |
| 鼠标点击消息(WM_LBUTTONUP,WM_RBUTTONDOWN等)在消息队列中 |
| WM_MOUSEMOVE消息在消息队列中 |
| WM_PAINT消息在消息队列中 |
| 登记消息(在此处列出的除外)在消息队列中 |
| 由另一个线程或应用发送的消息在消息队列中 |
| WM_TIMER消息在消息队列中 |
dwFlags
指定等待类型。这个参数可以是下面列出值的任意组合:
| 含义 |
| 当对象中任意一个变为有信号状态则函数返回。返回值指出是哪个对象状态的改变导致函数返回。 |
| 只有当pHandles数组中所有对象有信号时函数返回 |
| 调用QueueUserAPC加入一个APC将导致函数返回 |
| 只适用于Windows 98, Windows NT 5.0及其以后版本: 消息队列中存在输入函数将返回,甚至于输入已经被另一个函数检测过了,如PeekMessage函数 |
返回值
假如函数成功,返回值表明引起函数返回的事件。成功的函数值是下面中的一个:
值 | 含义 |
WAIT_OBJECT_0 到 | 假如MWMO_WAITALL标志置位,返回值指明所有指定的对象处于有信号状态。返回值减去WAIT_OBJECT_0就是pHandles数组中引起函数返回的对象的索引 |
WAIT_OBJECT_0 + nCount | 有新的在dwWakeMask参数中指定的输入类型存在于输入队列中。函数如:PeekMessage,GetMessage,GetQueueStatus与WaitMessage将队列中的消息标记为旧的。因此,当你在这些函数之后调用MsgWaitForMultipleObjectsEx,函数将不会返回,除非有新的被指定的输入到达。当一个需要该线程活动的系统事件发生时也将返回该值,例如前台活动。因此即使没有相应的输入发生或dwWaitMask置0,MsgWaitForMultipleObjectsEx也可以返回。如果发生这种情况,那么在再次调用MsgWaitForMultipleObjectsEx之前要调用PeekMessage或GetMessage处理系统事件。 |
WAIT_ABANDONED_0 到 | 假如MWMO_WAITALL标志置位,返回值指明所有指定的对象处于有信号状态并且至少其中的一个是一个被舍弃的(abandoned)互斥对象。另外,返回值减去WAIT_ABANDONED_0即是pHandles数组中引起函数返回的被舍弃的互斥对象的索引 |
WAIT_IO_COMPLETION | 等待被一加入队列中的用户模式异步过程调用(user-mode asynchronous procedure call (APC))所终止 |
WAIT_TIMEOUT | 超时,但dwFlags与dwWakeMask参数中条件未满足 |
假如函数调用失败,返回值是0xFFFFFFFF。若想获得更多的错误信息,请调用GetLastError函数。
备注
MsgWaitForMultipleObjectsEx函数检测是否dwWakeMask与dwFlags参数中指定的条件满足。假如条件未满足,调用线程进入高效的等待状态。线程在等待条件之一满足或超时时只用很少的处理器时间。
返回前,等待函数会修改某些异步对象的状态。修改只会针对那些置信号状态后会导致函数返回的对象,例如系统将信号对象(semaphore)的引用计数减一。当dwFlags为零并且多个对象处于信号状态时,函数选择对象中的一个来确保等待;未被选中的对象的状态不受影响。
MsgWaitForMultipleObjectsEx函数可以在pHandles数组中指定下列的对象类型:
-
改变通知(Change notification)
-
控制台输入
-
事件
-
作业(job)
-
互斥
-
进程
-
信号
-
线程
-
等待计时器
要获取更多信息,请参阅Synchronization Objects
QS_ALLPOSTMESSAGE与QS_POSTMESSAGE标志被消除时是有区别的。QS_POSTMESSAGE在你调用GetMessage或PeekMessage时被消除,而不管你是否正在过滤消息。QS_ALLPOSTMESSAGE在你调用不过滤消息(wMsgFilterMin与wMsgFilterMax皆为零)的GetMessage或PeekMessage时被消除。这在你调用PeekMessage多次以获得不同区域的消息时会很有用。
Windows CE:Windows CE不支持QS_HOTKEY赋予dwWakeMask参数,也不支持MWMO_WAITALL和MWMO_ALERTABLE标志赋予dwFlags参数。
MsgWaitForMultipleObjectsEx复制句柄表,将消息队列事件加入其中,然后调用WaitForMultipleObjects