汉斯的回答与链接的 MSDN 文档没有什么不同。
消息按照先进先出的顺序处理,就像标准队列一样,有一些特殊的例外,如WM_TIMER
和WM_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 上的同一篇文章在下一节中说了这么多:
未排队的消息立即发送到目标窗口过程,绕过系统消息队列和线程消息队列。
[...]
发送非排队消息的一些函数是BroadcastSystemMessage
、BroadcastSystemMessageEx
、SendMessage
、SendMessageTimeout
和SendNotifyMessage
。
没有“优先事项”。但是,您描述的行为很容易解释。最有可能的是,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.