如何使用PeekMessage检索除输入(鼠标+键盘)之外的每个消息

7
我在代码中有一个循环函数,调用PeekMessage以检索事件。
目前它看起来像这样:
while (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE))
{
    // Process events
}

现在我想在不同的位置管理输入,也就是说,我想在主循环的不同时间获取消息,例如 WM_KEYDOWN, WM_MOUSEMOVE (鼠标和键盘事件)。 PeekMessage 的第三个和第四个参数允许定义要返回的消息范围,因此我可以使用提供的宏 WM_KEYFIRSTWM_KEYLASTWM_MOUSEFIRSTWM_MOUSELAST。但这非常不方便,因为我需要检查两个输入范围,因此对于其余所有内容,我需要检查三个范围。
最后一个参数是一个标志,我可以传递 PM_REMOVE | PM_QS_INPUT 来处理输入。但那么,在另一个循环中,当我想要获取其他所有消息时,我应该传递什么呢?没有 PM_QS_EVERYTHING_EXCEPT_INPUT 宏……
最优雅的方法是什么?

1
你最后一个不存在的标志可以被视为~PM_QS_INPUT,它可以通过按位或与PM_REMOVE组合。 - chris
是的,那可能是一个解决方案。但它并不能令我满意,因为这个标志有两个不同的语义:1)要检索哪种类型的消息(PM_QS_*),以及2)对消息要执行什么操作(PM_REMOVE、PM_NOREMOVE,但也包括我不想设置的PM_NOYIELD,以及可能在下一个Windows版本中出现的任何新标志)。我没有找到任何宏来区分这两个语义,尽管看实际值时,前16位保留给第二个语义。 - Benlitz
2
我的错误,你应该使用~PM_QS_INPUT,但只掩盖适用于该类型标志的位范围。我在那里脑子短路了。所以如果后半部分是为此目的,前半部分将为0,并且除了最后半部分的PM_QS_INPUT之外,其他所有内容都将为1。 - chris
我不太明白你所面临的问题。你不能调用两次 PeekMessage,一次使用 WM_KEYFIRST,另一次使用 WM_MOUSEFIRST 吗?你将要进行的测试(类似 while(PeekMessage(...WM_KEYFIRST...) || PeekMessage(...WM_MOUSEFIRST...)))与增强型、多范围 PeekMessage 所做的是相同的。 - ixe013
是的,我可以,但在另一个循环中,我还需要调用三次PeekMessage,分别使用BEFORE_KEY_RANGE、BETWEEN_KEY_AND_MOUSE_RANGE和AFTER_MOUSE_RANGE范围,这样就会有五个调用。而且我仍然必须假设键盘范围在鼠标范围之前,这是不好的(或者,好吧,我可以测试哪个是第一个,并进行适应...但这会产生很多肮脏的代码,这就是为什么我问是否存在一种优雅的方法来解决这个问题)。我不知道有没有办法遍历消息队列,所以我必须依靠PeekMessage提供的过滤选项。 - Benlitz
1个回答

1
你可以尝试使用"过滤器"。Win32调用它为"hooks",请查看MSDN的SetWindowsHookEx函数。您有可能安装一个线程特定的键盘和鼠标消息过滤器。然后,您可以将消息推送到您维护的队列中,并稍后手动访问它(知道您可以从钩子中删除该线程的公共队列相关消息,以便只有您的用户队列会有消息)。 虽然,在每个您感兴趣的情况下,您也可以直接从PeekMessage开关直接推送到此使用队列。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接