GetMessage超时

qdi*_*dii 15 c++ windows winapi

我有一个第二个线程GetMessage()在循环中调用的应用程序.在某些时候,第一个线程意识到用户想要退出应用程序并通知第二个线程它应该终止.当第二个线程被卡住时GetMessage(),程序永远不会退出.有没有办法等待超时的消息?我也对其他想法持开放态度.

编辑:(补充说明)

第二个线程运行该代码片段:

while ( !m_quit && GetMessage( &msg, NULL, 0, 0 ) )
{
    TranslateMessage( &msg );
    DispatchMessage( &msg );
}
Run Code Online (Sandbox Code Playgroud)

第一个线程设置m_quit为true.

rod*_*igo 20

没有经过测试,但您可以尝试使用MsgWaitForMultipleObjects函数而不需要实际的任何对象.

MsgWaitForMultipleObjects(0, NULL, FALSE, timeout, QS_ALLEVENTS);
Run Code Online (Sandbox Code Playgroud)

如果if返回WAIT_TIMEOUT则是超时,但如果返回则WAIT_OBJECT_0可以 GetMessage保证不被阻止.

但请注意以下事项:

如果在线程调用检查队列的函数后消息队列中存在指定类型的未读输入,则MsgWaitForMultipleObjects不会返回.

因此,您必须确保上次调用任何消息函数时,队列中没有消息,否则您将遇到某种竞争条件.

可能你最好的选择是替换GetMessage为:

if (MsgWaitForMultipleObjects(0, NULL, FALSE, timeout, QS_ALLEVENTS) == WAIT_OBJECT_0)
{
    while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
    {
        //dispatch the message
    }
}
Run Code Online (Sandbox Code Playgroud)

但正如我之前所说,我没有测试它,所以我不能确定它是否会起作用.

  • 我只是有一个死锁,等待这个例程的**SendMessage**msg.您应该使用**QS_ALLINPUT**而不是**QS_ALLEVENTS**,因为它还包括**QS_SENDMESSAGE**.有关详细信息,请参阅[msdn](http://msdn.microsoft.com/en-us/library/windows/desktop/ms684242%28v=vs.85%29.aspx) (8认同)

rod*_*igo 13

最简单的方法是在打电话UINT_PTR timerId=SetTimer(NULL, NULL, 1000, NULL)前打电话GetMessage.它会WM_TIMER每秒向调用线程发送一条消息,因此GetMessage会立即返回.然后,打电话KillTimer(NULL, timerId)取消它.

更新示例代码:

BOOL GetMessageWithTimeout(MSG *msg, UINT to)
{
    BOOL res;
    UINT_PTR timerId = SetTimer(NULL, NULL, to, NULL);
    res = GetMessage(msg);
    KillTimer(NULL, timerId);
    if (!res)
        return FALSE;
    if (msg->message == WM_TIMER && msg->hwnd == NULL && msg->wParam == timerId)
        return FALSE; //TIMEOUT! You could call SetLastError() or something...
    return TRUE;
}
Run Code Online (Sandbox Code Playgroud)