UE4环境下WinAPI消息发送正常但自定义消息无法接收问题排查
优先替换自定义消息ID的生成方式
别用WM_USER + 常量这类硬编码ID,UE4内部大量使用该范围的消息,极易冲突。必须用RegisterWindowMessage生成全局唯一的消息ID,发送和接收逻辑统一使用这个ID:// 全局或类内静态变量存储消息ID UINT MyCustomMsg = RegisterWindowMessage(L"UE4_Custom_Message_For_Timing_Test");确认Message-Only窗口的归属线程与消息循环
如果你的接收线程是自定义线程,必须在该线程内部启动独立的Windows消息循环,不能依赖UE4游戏线程的消息分发。UE4的游戏线程消息循环会过滤非引擎相关的消息,不会帮你处理自定义窗口的消息。示例循环代码:MSG MsgLoopBuffer; while (GetMessage(&MsgLoopBuffer, nullptr, 0, 0)) { TranslateMessage(&MsgLoopBuffer); DispatchMessage(&MsgLoopBuffer); }另外创建窗口时必须明确指定父窗口为
HWND_MESSAGE,确保是纯消息窗口:HWND hMsgOnlyWnd = CreateWindowEx(0, L"YourCustomWndClass", L"", 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, nullptr);排查UE4的消息拦截逻辑
UE4的FWindowsApplication类会接管系统消息的处理流程,如果你是在游戏线程关联的窗口上绑定的Message-Only窗口,自定义消息可能被UE4的消息过滤机制拦截。可以尝试在项目的FWindowsApplication子类中重写PreProcessMessage或PostProcessMessage,手动将你的自定义消息分发给目标窗口;或者检查UE4是否将该消息标记为需要跳过处理。验证消息发送的有效性
确保发送消息时使用的窗口句柄是正确的Message-Only窗口句柄,而非游戏主窗口句柄。如果用PostMessage,要确认接收线程的消息循环处于运行状态;如果用SendMessage,要确认接收线程没有被UE4的同步任务阻塞导致无法响应。可以在发送后调用GetLastError()再次确认,虽然你说返回无错误,但结合句柄有效性排查更稳妥。检查自定义线程的UE4配置
如果你用UE4的FRunnable框架创建接收线程,要确保线程拥有完整的Windows线程上下文,不要使用UE4的任务线程池(比如AsyncTask)来运行消息循环——任务线程池的线程是复用的,不会持续驻留处理消息。必须创建独立的、长期运行的线程来维护Message-Only窗口的消息循环。
内容的提问来源于stack exchange,提问作者Physician

