如果接收线程开始泵送消息,SendMessage 可以提前返回吗?

发布于 2024-08-14 01:30:16 字数 416 浏览 5 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

童话里做英雄 2024-08-21 01:30:16

只要消息的处理已经开始,处理线程间消息的 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.

梦幻的味道 2024-08-21 01:30:16

由于 SendMessage 有返回值,因此它总是在消息处理之后。

另一方面,PostMessage 不会等待消息被处理。

来自 MSDN SendMessage

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:

The SendMessage function calls the
window procedure for the specified
window and does not return until the
window procedure has processed the
message.

There is no case where it will return before the message is processed.

夜巴黎 2024-08-21 01:30:16

从MSDN来看,问题可能是在线程B中显示对话框可能会导致死锁。请参阅消息死锁


可能是因为线程 A 收到的消息是非排队消息。来自 MSDN:

但是,发送线程将
处理传入的非排队消息
在等待其消息时
已处理。为了防止这种情况,请使用
使用 SMTO_BLOCK 的 SendMessageTimeout
放。有关非排队的更多信息
消息,请参阅非排队消息

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:

However, the sending thread will
process incoming nonqueued messages
while waiting for its message to be
processed. To prevent this, use
SendMessageTimeout with SMTO_BLOCK
set. For more information on nonqueued
messages, see Nonqueued Messages.

岛徒 2024-08-21 01:30:16

听起来好像您的原始 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文