Winapi 窗口消息优先级权威描述

Winapi 窗口消息优先级权威描述,winapi,windows-ce,Winapi,Windows Ce,我发现,GetMessage返回的提及窗口消息的优先级顺序源自于它们的发送方式,SendMessage的优先级高于PostMessage且仅高于用户输入。但是,我在这方面找不到任何权威参考,即来自微软的参考。似乎明确否认了这一点(说消息是按FIFO顺序处理的,很少有例外),我找不到任何其他参考 然而,我有一个应用程序行为,它表明存在优先级(每秒处理几个WM_用户线程消息,但单击有时需要几秒钟才能得到处理)。因此,我想从权威来源了解它的预期行为,以便我能够修复该应用程序 注意:这些消息是通过Pos

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

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

注意:这些消息是通过
PostThreadMessage
发送的。我正在观察从
GetMessage
发送的消息,因此未排队的消息不会在这里发挥作用。线程消息和窗口消息之间的差异可能会导致错误

注意:应用程序在WinCE上运行,如果有问题,尤其是在WinCE 5.0上。

没有说明任何不同于

消息以先进先出的顺序处理,就像标准队列一样,还有一些特殊的例外,如
WM\u TIMER
WM\u PAINT
消息。Hans将此类消息称为“从窗口状态合成”的消息;MSDN只是明确地指出:

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

问题在于,使用
SentMessage
发送的消息不排队,而使用
PostMessage
发布的消息则排队。MSDN上的同一篇文章在

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

[……]

发送非排队消息的一些函数有
BroadcastSystemMessage
BroadcastSystemMessageEx
SendMessage
SendMessageTimeout
SendNotifyMessage

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

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


重要注意事项:我对Windows CE一无所知,您的问题表明您正在专门谈论Windows CE。我在这里描述的行为对于Windows的桌面版本来说是准确的,但是如果这种行为与Windows CE的行为有任何区别,我不知道,我可能会出错。

这个答案与MSDN文档的说法不同。答案是,发布的消息仍然在用户交互消息之前进行处理,这与观察结果相符,但我在MSDN文档中没有看到类似的内容。此外,我正在观察来自GetMessage的消息,因此我甚至不应该看到未排队的消息。我在回答中阐明:用户消息通过
PostThreadMessage
发送,并由调用
GetMessage
的代码处理。“在发送到窗口程序之前,我正在查看它。@Jan:我不知道如何解释才能使它更清楚。”。Hans对相关问题的回答与MSDN文档之间绝对没有不一致之处。发布的消息在特殊消息(如
WM_PAINT
WM_TIMER
)之前进行处理。答案和文件中都明确指出了这些问题。此外,
GetMessage
确实返回/处理已发送的消息,因此您仍然可以看到通过调用
SendMessage
发送的消息。使用
SendXxx
函数发送的消息将首先被处理,然后使用
PostXxx
函数发送。这不是一个特殊的“优先级”问题,只是因为它们的实现方式不同。发送的消息不排队,而是由窗口过程立即处理。在发送的消息被处理后,已发送的消息被排队并按FIFO顺序处理。像
WM_PAINT
WM_TIMER
这样的特殊消息表示布尔值,并且是特殊大小写的。另请参见,它为您提供了在未提供覆盖的情况下如何处理消息的简要概述。不,不涉及“特殊”消息。仅发布线程消息和鼠标事件。不过,此链接确实提到,已发布的消息是在硬件消息之前处理的。请将此链接放入主答案中(并删除其余大部分,即