如果接收线程开始泵送消息,SendMessage 可以提前返回吗?
Windows 如何精确地决定 SendMessage 应返回——也就是说,它如何决定接收线程已完成对发送消息的处理?
详细场景: 我有线程 A 使用 SendMessage 将线程发送到线程 B。显然,直到线程 B 处理完消息后,SendMessage 才会返回。线程B弹出一个对话框并开始泵送消息。在我的场景中,队列中有一条 WM_KILLFOCUS 消息,该消息由线程 B 泵送。结果是线程 B 上的 WM_COMMAND 消息。线程 B 将此 WM_COMMAND 消息传递给默认窗口过程。当它执行此操作时,SendMessage 返回到线程 A,即使原始消息尚未完成处理!到底是怎么回事?看起来默认的窗口过程不知何故使窗口误以为原始发送的消息已完成。
那么是否存在已知的场景,其中泵送消息并调用默认窗口过程可以欺骗 SendMessage 返回?
谢谢! 菲尔
How precisely does windows decide that SendMessage should return- that is, how does it decide the receiving thread has finished processing the sent message?
Detailed scenario:
I've got thread A using SendMessage to send a thread to thread B. Obviously SendMessage doesn't return until thread B finishes processing the message. Thread B pops up a dialog box and starts pumping messages. In my scenario, there is a WM_KILLFOCUS message on the queue which gets pumped by thread B. This results is a WM_COMMAND message on thread B. Thread B passes this WM_COMMAND message to the default window proc. When it does this, SendMessage returns back to thread A, even though the original message hasn't finished processing yet! What is going on? It looks like somehow the default window proc is confusing windows into thinking the original sent message is finished.
So are there known scenarios where pumping messages and calling the default window proc can trick SendMessage into returning?
Thanks!
Phil
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
只要消息的处理已经开始,处理线程间消息的 WindowProc 就可以调用 ReplyMessage 允许调用线程在处理继续时继续。
As long as processing of the message has started, the WindowProc processing the interthread message can call ReplyMessage to allow the calling thread to continue while processing continues.
由于
SendMessage
有返回值,因此它总是在消息处理之后。另一方面,
PostMessage
不会等待消息被处理。来自 MSDN SendMessage:
不存在在消息被处理之前返回的情况。
Since
SendMessage
has a return value, it is always after the message is processed.PostMessage
on the other hand will not wait for the message to be processed.From MSDN on SendMessage:
There is no case where it will return before the message is processed.
从MSDN来看,问题可能是在线程B中显示对话框可能会导致死锁。请参阅消息死锁。
可能是因为线程 A 收到的消息是非排队消息。来自 MSDN:
From the MSDN, it sounds like that the problem may be that displaying a dialog box in thread B may cause deadlocks. See Message Deadlocks.
Possibly it is because the message received by thread A was a nonqueued message. From MSDN:
听起来好像您的原始 SendMessage 尚未返回,而是在处理发送的消息期间调用了线程 A 中的 WindowProc。不要求消息处理程序必须避免调用 SendMessage 来响应消息的接收。
当您收到响应焦点更改消息而发送的 WM_COMMAND 时,您应该能够在调用堆栈中看到对 SendMessage 的原始调用。
It sounds as if your original SendMessage has NOT returned but rather than the WindowProc in thread A has been called during the processing of the message sent. There is no requirement that a message handler must refrain from calling SendMessage in response to receipt of a message.
You should be able to see the original call to SendMessage in your callstack at the point where you receive the WM_COMMAND that you sent in response to the focus change message.