发布消息:未收到消息
PostMessage: Messages not received
我正在寻找一些关于我可以解决的问题的反馈,但想更好地了解。我有一些多线程代码,其中工作线程使用 Win32 API PostMessage 函数将消息发布到主 UI 线程以更新树视图。某些发布的消息有时无法通过 UI 线程的消息泵出现,尽管我的日志记录显示 PostMessage 成功返回。
我已经找到了许多解释,说明如果我在我的消息泵中做了一些时髦的事情,这会发生什么,因为在某些情况下存在模态消息泵,但我没有做任何时髦的事情。
我认为(但希望确认(我的问题是由于在 UI 线程的生命周期中过早调用 PostMessage。我的 WinMain 调用 CreateWindowEx 来创建其主窗口,该窗口的WM_CREATE处理程序间接启动后台线程,这些线程将使用主窗口的 HWND 相当快速地调用 PostMessage,甚至可能在WM_CREATE处理程序完成之前,很可能在 WinMain 的消息泵启动之前。
在这种情况下,即使PostMessage返回成功,是否有可能/可能丢失某些消息?在测试中,我确定在工作线程调用 PostMessage 之前在工作线程中添加一个小延迟 (Sleep(50(( 足以防止任何消息丢失。但是,我不相信这能解决根本问题,所以想知道我是否需要继续挖掘。
编辑:
我的所有代码中只有一个消息循环,除了调用通常的 TranslateAccelerator 等之外,它没有做任何异常的事情:
// Enter the message loop
while (GetMessage (&msg, NULL, 0, 0)) {
if (!TranslateMDISysAccel(hwndClient, &msg) && !TranslateAccelerator (hwndFrame, hAccel, &msg)) {
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
我已经找到了很多解释,如果我在我的消息泵中做了一些时髦的事情,由于在某些情况下存在模态消息泵,这种情况是如何发生的,但我没有做任何时髦的事情。
模态循环不会丢弃窗口消息,除非它们编码错误,并且不会像它们应该的那样将未知消息传递给TranslateMessage()
/DispatchMessage()
。
我认为(但希望确认(我的问题是由于在 UI 线程的生命周期中过早调用 PostMessage。
如果是这样的话,PostMessage()
会失败,但你已经排除了这一点。 只要线程调用任何user32.dll
函数,消息队列就会创建并可以开始接收消息,即使队列没有立即轮询也是如此。
即使PostMessage返回成功,是否有可能/可能丢失某些消息?
不。其他事情正在发生。要么是消息循环过滤不正确,要么是格式错误的模式循环丢弃了消息,要么只是发布到错误的HWND
。很难说,因为你没有显示任何代码。
在测试中,我确定在工作线程调用 PostMessage 之前在工作线程中添加一个小延迟 (Sleep(50(( 足以防止任何消息丢失。
在这 50 毫秒内,您的主线程通常在做什么?听起来您的 UI 代码中的某些内容在此期间正在接收和丢弃您发布的消息。
另一方面,线程如何知道要发布到哪个HWND
?您的WM_CREATE
处理程序是将其hwnd
参数传递给线程,还是线程依赖于CreateWindowEx()
返回的HWND
?在后一种情况下,如果在CreateWindowEx()
退出之前调用PostMessage()
应该失败。除非您的接收HWND
变量最初未初始化,并且包含一个随机的非空值,PostMessage()
该值解释为系统上其他位置的有效HWND
。
- boost::进程间消息队列引发错误
- 在线编译器中的分段C++没有打印消息
- C++错误消息*成员参考.**初学者*
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 如何通过参数抛出错误消息
- 从服务器传输到客户端的消息不会出现
- ROS2 动态消息模板
- C++秘密消息学校作业
- glad 导致 glfwSwapBuffers 返回错误消息
- C++入门 5 版:类消息和文件夹
- FindPackageHandleStandardArgs.cmake:137 的 CMake 错误(消息):找不到 Boost (缺少:正则表达式)(找到合适的版本"1.72.0",
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 如何接受 [ENTER] 键作为无效输入并发送错误消息
- 由于无效的 ValidateRgn() 子窗口不会收到WM_PAINT消息
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- 如何将 Firebase 与基于 Linux 的客户端应用配合使用,以便与服务器进行双向消息通信
- (普罗托布夫)无法解析类型 "data.Data" 的消息,因为它缺少必填字段:ID
- 错误是发送还是接收?未发送完整消息或消息未正确解码
- 发送Windows消息的消息框