0

我发现一些提到窗口消息的 地方是由 GetMessage 按优先级顺序返回的,这些优先级是从它们以SendMessage最高的发送方式得出的,而不是PostMessage仅比用户输入。但是我在这方面找不到任何权威参考,即来自微软。明显的页面似乎明确否认它(说消息按 FIFO 顺序处理,很少有例外),我找不到任何其他参考。

但是,我有一个应用程序行为表明存在优先级(每秒处理几个 WM_USER线程消息,但单击有时需要几秒钟才能得到处理)。因此,我想从权威来源了解它的预期行为,以便我可以修复应用程序。

注意:消息是用 发送的PostThreadMessage。我正在观看来自 的消息GetMessage,因此非排队消息不会在这里发挥作用。线程和窗口消息之间可能存在差异。

注意:该应用程序在 WinCE 上运行,尤其是在重要的 5.0 上。

4

1 回答 1

2

汉斯的回答与链接的 MSDN 文档没有什么不同。

消息按照先进先出的顺序处理,就像标准队列一样,有一些特殊的例外,如WM_TIMERWM_PAINT消息。Hans 将这类消息称为“从窗口状态合成”的消息;MSDN 只是明确地把它们叫出来:

除了WM_PAINT消息、WM_TIMER消息和WM_QUIT消息之外,系统始终将消息发布在消息队列的末尾。这可确保窗口以正确的先进先出 (FIFO) 顺序接收其输入消息。但是,WM_PAINT消息、WM_TIMER消息和WM_QUIT消息都保存在队列中,并且仅当队列不包含其他消息时才转发到窗口过程。此外,WM_PAINT同一窗口的多条消息合并为一条WM_PAINT消息,将客户区的所有无效部分合并为一个区域。组合WM_PAINT消息减少了窗口必须重绘其客户区内容的次数。

问题是发送的消息SentMessage没有排队,而发送的消息PostMessage 。MSDN 上的同一篇文章在下一节中说了这么多:

未排队的消息立即发送到目标窗口过程,绕过系统消息队列和线程消息队列。

[...]

发送非排队消息的一些函数是BroadcastSystemMessageBroadcastSystemMessageExSendMessageSendMessageTimeoutSendNotifyMessage

没有“优先事项”。但是,您描述的行为很容易解释。最有可能的是,WM_USER消息是通过调用SendMessage函数发送的,该函数绕过消息队列并将消息直接发送到目标窗口的窗口过程。这使得它们看起来以更高的“优先级”进行处理,因为它们在SendMessage函数返回之前立即被处理,有效地绕过了队列的其余部分。

这反过来解释了为什么单击事件需要更长的时间来处理 - 因为它们只是与所有其他输入消息一起被推入队列,因此窗口在处理消息之前不会处理它们通过调用 直接发送给它SendMessage

Important caveat: I know nothing about Windows CE, which your question indicates you're talking about specifically. The behavior I describe here is accurate for desktop versions of Windows, but if there are any differences between that behavior and that of Windows CE, I wouldn't know and I might have gotten something wrong.

于 2012-05-18T12:19:03.607 回答