3

一般的问题是,如果我从一个单独的工作线程向 Windows 消息泵发布多条消息,它们会按照我发送的顺序出现在目的地吗?IE..

::PostMessage(m_hUsers, WM_BULKPROCESS, 0, 0);
// ... some processing here ...
::PostMessage(m_hUsers, WM_BULKDONE, 0, 0);

m_hUsers 是我从工作线程向其发送消息的窗口的句柄 (HWND)。那么,WM_BULKPROCESS 是否总是首先显示在窗口中(因此由该对话框类中的处理程序处理),或者它们是否可能出现故障,即 WM_BULKDONE 在 WM_BULKPROCESS 之前得到处理,即使它是最后发送的?

4

4 回答 4

5

有一些例外(如 WM_PAINT),但通常会保留消息的顺序。如果消息以错误的顺序出现,图像会试图理解鼠标输入!

来自 GetMessage 的报价

在此调用期间,系统会传递待处理的非排队消息,即使用 SendMessage、SendMessageCallback、SendMessageTimeout 或 SendNotifyMessage 函数发送到调用线程拥有的窗口的消息。然后检索与指定过滤器匹配的第一个排队消息。系统还可以处理内部事件。如果未指定过滤器,则按以下顺序处理消息:

Sent messages
Posted messages
Input (hardware) messages and system internal events
Sent messages (again)
WM_PAINT messages
WM_TIMER messages
于 2011-09-15T18:41:59.763 回答
2

窗口消息存储在队列中。所以你可以依靠先进先出机制。

于 2011-09-15T18:40:28.157 回答
1

它们应该是,除非您在消息泵中有专门以不同方式发送消息(有意或无意)的代码,例如以某种方式选择两条消息并无序发送它们。通常,程序员按照您从队列中获取的顺序为每条消息调用 DispatchMessage。

于 2011-09-15T18:40:32.857 回答
0

我怀疑问题是同步而不是消息队列。如果您的代码允许对工作线程 proc 进行多次调用,则必须更严格地管理它以了解工作线程的哪个“实例”正在发布消息。

您是否检查过以确保一次只执行一个工作线程,或者保护 m_hUsers 窗口句柄不会在 BULKPROCESS 和 BULKDONE 之间更改?

SendMessage 对于管理 BULKDONE 很有用,因为它会阻塞直到消息被处理,从而允许调用工作线程的代码同步工作线程的调用,并且在调用另一个工作线程之前真正知道一个工作线程已经完成。Postmessage 不会阻塞,但请记住您的工作线程的时间敏感部分是 `// ...这里有一些处理...不发送 windows 消息。

于 2011-09-16T08:49:27.843 回答