平台 SDK: 动态链接库,进程和线程

MsgWaitForMultipleObjects

当发生下列之一时,MsgWaitForMultipleObjects函数会返回:

  • 任何一个或所有指定的对象都处于信号状态。 这些对象可以包含使用dwWakeMask参数指定的输入事件对象。

  • 超时间隔已过。

要进入可警告的等待状态,请使用MsgWaitForMultipleObjectsEx函数。

注意 如果在线程调用函数检查队列后,消息队列中存在未读的指定类型的输入,则MsgWaitForMultipleObjects不会返回。 这是因为诸如PeekMessage,GetMessage,GetQueueStatus和WaitMessage等函数会检查队列,然后更改队列的状态信息,以使输入不再被视为新的。 在指定类型的新输入到达之前,对MsgWaitForMultipleObjects的后续调用将不会返回。 现有的未读输入(在线程最后一次检查队列之前收到)将被忽略。

DWORD MsgWaitForMultipleObjects(
  DWORD nCount,          // 数组中的句柄数量
  CONST HANDLE pHandles, // 对象句柄数组
  BOOL bWaitAll,         // 等待选项
  DWORD dwMilliseconds,  // 超时间隔
  DWORD dwWakeMask       // 输入事件类型
);

参数

  • nCount

  • [in] 指定由pHandles指向的数组中的对象句柄的数量。 对象句柄的最大数量是MAXIMUM_WAIT_OBJECTS减1。

  • pHandles

  • [in] 指向一个对象句柄数组的指针。 有关可以指定其句柄的对象类型的列表,请参见下面的“注释”部分。 该数组可以包含不同类型对象的句柄。 它可能不包含同一句柄的多个副本。

    如果其中一个句柄在等待仍然未决时关闭,则该函数的行为未定义。

    Windows NT/2000/XP: 句柄必须具有SYNCHRONIZE访问权限。 有关更多信息,请参阅标准访问权限。

    Windows 95/98/Me: 没有句柄可能是使用DuplicateHandle创建的另一个句柄的重复。

  • bWaitAll

  • [in] 指定等待类型。 如果为TRUE,则当pHandles数组中的所有对象的状态都已设置为发信号且已收到输入事件时,此函数会返回。 如果为FALSE,则当任何一个对象的状态设置为发信号或接收到输入事件时,该函数返回。 在这种情况下,返回值表示其状态导致函数返回的对象。

  • dwMilliseconds

  • [in] 指定超时间隔(以毫秒为单位)。 即使间隔过去了,即使由bWaitAll或dwWakeMask参数指定的条件未满足,该函数也会返回。 如果dwMilliseconds为零,该函数将测试指定对象的状态并立即返回。 如果dwMilliseconds是INFINITE,则该函数的超时间隔永不过时。

  • dwWakeMask

  • [in] 指定输入事件对象句柄将添加到对象句柄数组的输入类型。 该参数可以是以下值的任意组合。

    含义
    QS_ALLEVENTS输入,WM_TIMER,WM_PAINT,WM_HOTKEY或发布的消息在队列中。

    该值是QS_INPUT,QS_POSTMESSAGE,QS_TIMER,QS_PAINT和QS_HOTKEY的组合。

    QS_ALLINPUT任何消息都在队列中。

    该值是QS_INPUT,QS_POSTMESSAGE,QS_TIMER,QS_PAINT,QS_HOTKEY和QS_SENDMESSAGE的组合。

    QS_ALLPOSTMESSAGE发布的消息在队列中。

    当您调用GetMessage或PeekMessage时,无论您是否过滤消息,都会清除此值。

    QS_HOTKEYWM_HOTKEY消息在队列中。
    QS_INPUT输入消息在队列中。

    该值是QS_MOUSE和QS_KEY的组合。

    Windows XP: 该值还包括QS_RAWINPUT。

    QS_KEYWM_KEYUP,WM_KEYDOWN,WM_SYSKEYUP或WM_SYSKEYDOWN消息在队列中。
    QS_MOUSEWM_MOUSEMOVE消息或鼠标按钮消息(WM_LBUTTONUP,WM_RBUTTONDOWN等)。

    该值是QS_MOUSEMOVE和QS_MOUSEBUTTON的组合。

    QS_MOUSEBUTTON鼠标按钮消息(WM_LBUTTONUP,WM_RBUTTONDOWN等)。
    QS_MOUSEMOVEWM_MOUSEMOVE消息在队列中。
    QS_PAINTWM_PAINT消息在队列中。
    QS_POSTMESSAGE发布的消息在队列中。

    当您在不过滤消息的情况下调用GetMessage或PeekMessage时,该值将被清除。

    QS_RAWINPUTWindows XP: 原始输入消息在队列中。 有关更多信息,请参阅原始输入。
    QS_SENDMESSAGE由另一个线程或应用程序发送的消息在队列中。
    QS_TIMERWM_TIMER消息在队列中。


返回值

如果函数成功,则返回值指示导致函数返回的事件。 成功的返回值是以下之一:

含义
WAIT_OBJECT_0 to
(WAIT_OBJECT_0 + nCount – 1)
如果bWaitAll为TRUE,则返回值表示指示所有指定对象的状态。 如果bWaitAll为FALSE,则返回值减去WAIT_OBJECT_0指示满足等待的对象的pHandles数组索引。
WAIT_OBJECT_0 + nCount线程的输入队列中提供了dwWakeMask参数中指定类型的新输入。 诸如PeekMessage,GetMessage和WaitMessage等函数将队列中的消息标记为旧消息。 因此,在调用其中一个函数之后,在指定类型的新输入到达之前,对MsgWaitForMultipleObjects的后续调用将不会返回。

此值也是在发生需要线程操作的系统事件(如前台激活)时返回的。 因此,即使没有适当的输入可用,并且即使将dwWaitMask设置为0,MsgWaitForMultipleObjects也可以返回。如果发生这种情况,请在再次尝试调用MsgWaitForMultipleObjects之前调用PeekMessage或GetMessage来处理系统事件。

WAIT_ABANDONED_0 to
(WAIT_ABANDONED_0 + nCount – 1)
如果bWaitAll为TRUE,则返回值指示指示所有指定对象的状态,并且至少有一个对象是废弃的互斥对象。 如果bWaitAll为FALSE,则返回值减去WAIT_ABANDONED_0指示已满足等待的废弃互斥对象的pHandles数组索引。
WAIT_TIMEOUT超时间隔已过,并且bWaitAll和dwWakeMask参数指定的条件未得到满足。


如果函数失败,返回值是WAIT_FAILED。 要获得扩展的错误信息,请调用GetLastError。

备注

MsgWaitForMultipleObjects函数确定是否满足等待条件。 如果条件未满足,则调用线程将进入等待状态。 它在等待满足等待条件的条件时不使用处理器时间。

当bWaitAll为TRUE时,该功能不会修改指定对象的状态,直到所有对象的状态都设置为发信号。 例如,一个互斥信号可以发送信号,但是线程不会获得所有权,直到其他对象的状态也被设置为发送信号。 同时,其他一些线程可能会获得互斥量的所有权,从而将其状态设置为非信号。

当bWaitAll为TRUE时,只有当所有对象的状态都被设置为发信号且接收到输入事件时,该功能的等待才会完成。 因此,将bWaitAll设置为TRUE可防止输入被处理,直到pHandles数组中的所有对象的状态都设置为发信号。 因此,如果将bWaitAll设置为TRUE,则应该在dwMilliseconds中使用短超时值。 如果你有一个创建窗口的线程来等待pHandles数组中的所有对象,包括由dwWakeMask指定的输入事件,而没有超时间隔,系统将会死锁。 这是因为创建窗口的线程必须处理消息。 DDE将消息发送到系统中的所有窗口。 因此,如果线程创建窗口,则不要在调用该线程所做的MsgWaitForMultipleObjects时将bWaitAll参数设置为TRUE。

该函数修改某些类型的同步对象的状态。 修改只发生在信号状态导致函数返回的对象或对象上。 例如,信号量对象的计数减1。 当bWaitAll为FALSE且多个对象处于信号状态时,函数选择其中一个对象来满足等待; 未选中的对象的状态不受影响。

MsgWaitForMultipleObjects函数可以指定pHandles数组中任何以下对象类型的句柄:

  • 更改通知

  • 控制台输入

  • 事件

  • 作业

  • 互斥量

  • 进程

  • 信号量

  • 线程

  • 等待定时器

有关更多信息,请参阅同步对象。

QS_ALLPOSTMESSAGE和QS_POSTMESSAGE标志在清除时不同。 当您调用GetMessage或PeekMessage时,QS_POSTMESSAGE会被清除,无论您是否正在过滤消息。 当您调用GetMessage或PeekMessage而不过滤消息时,会清除QS_ALLPOSTMESSAGE(wMsgFilterMin和wMsgFilterMax为0)。 当您多次调用PeekMessage来获取不同范围的消息时,这会很有用。

示例代码

有关使用MsgWaitForMultipleObjects的示例,请参阅在消息循环中等待。

要求

  Windows NT/2000/XP: 包含在Windows NT 3.51和更高版本中。

  Windows 95/98/Me: 包含在Windows 95和更高版本中。

  头文件: 声明于 Winuser.h; 包含于 Windows.h.
  库: 使用 User32.lib.