这个Win32消息循环到底发生了什么?

时间:2013-03-28 19:54:27

标签: winapi visual-c++ messaging

这个Win32消息传递循环内部究竟发生了什么?我知道TranslateMessage正在将密钥代码转换为UTF字符代码并发送WM_CHAR事件,但对PeekMessage的调用是什么呢?它是否过滤掉某种类型的消息并只翻译那些消息?

// Application / Player message loop.
MSG msg;
ZeroMemory(&msg, sizeof(msg));

while(msg.message != WM_QUIT)
{
    if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

   // work happens here...
}

2 个答案:

答案 0 :(得分:4)

通常,消息循环将使用GetMessage而不是PeekMessage。区别在于PeekMessage立即返回。如果邮件已删除,则返回TRUE;如果未提取邮件,则返回FALSE。另一方面,如果队列为空,GetMessage将阻塞,直到消息到达。

关键是说明工作在这里发生。据推测,作者有一些理由说正常的阻塞消息循环是不够的。问题中非阻塞消息循环代码的缺点是它是一个繁忙的循环。它不会空闲,因此它将完全消耗CPU,除非有Sleep()或类似的已被切除的呼叫。

在评论中,您说您实际上只想取消键盘消息,而只是针对特定窗口发送消息。您需要像这样致电PeekMessage

PeekMessage(&msg, hwnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)

答案 1 :(得分:2)

所有这一切都是获取消息的非阻塞方式。它检查是否有消息,如果有消息,则将其从队列中取出并将其放入& msg。

检查the docs

第二个参数说明要查看的窗口。在这种情况下,它是“线程中的所有窗口。”

第三个和第四个参数可让您指定是否需要键盘或鼠标事件,但当前设置为“全部”。