WM_DESTROY 消息混淆
Posted
技术标签:
【中文标题】WM_DESTROY 消息混淆【英文标题】:WM_DESTROY message confusion 【发布时间】:2021-01-04 17:30:55 【问题描述】:拥有这么简单的 Win 应用程序:
bool continueRunning = true;
...
int APIENTRY wWinMain(...)
while (continueRunning)
PeekMessage(&msg, 0, 0, 0, PM_REMOVE);
TranslateMessage(&msg);
DispatchMessage(&msg);
if (WM_DESTROY == msg.message)
OutputDebugString(L"--- WM_DESTROY (WinMain) ---\n");
...
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
switch (message)
case WM_DESTROY:
OutputDebugString(L"--- WM_DESTROY (WndProc) ---\n");
continueRunning = false;
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
return 0;
我收到了--- WM_DESTROY (WndProc) ---
消息,但没有 --- WM_DESTROY (WinMain) ---
。
WM_DESTROY
没有收到消息,如何将消息 PeekMessage
传递给应用程序?
【问题讨论】:
WM_DESTROY
是 sent 并直接进入窗口 proc。请参阅docs 中的第一段。
好的,但是由于没有PeekMessage
- 窗口进程中的类似功能,应用程序如何获取这样的消息?
WM_DESTROY
永远不会进入消息队列。它是一个发送的消息,直接传递给window proc。
但我的代码中没有明确的SendMessage
调用。当我单击“X”按钮时,它只是由系统隐式/默认/自动发送吗?
它是由 Windows “当窗口被销毁时”发送的,引用自相同的文档。在Why can't I get a WM_DESTROY or WM_CLOSE message outside a window procedure? 和WndProc calling mechanism (WinAPI) 上查看更多信息。
【参考方案1】:
PeekMessage
(或GetMessage
)自行调度发送的消息(来自其他线程)而不返回它们。它只返回已发布的消息。如果消息是由同一个线程发送的,它甚至不会通过PeekMessages
,它实际上是一个直接的窗口过程调用。 WM_DESTROY
已发送。
顺便说一句,避免不将系统消息传递给DefWindowProc
,包括WM_DESTROY
。
【讨论】:
抱歉,没听懂。 “自己发消息”和“只发消息”是什么意思? 我已经编辑了我的答案,希望现在更清楚 好的,谢谢。为了澄清。 “它实际上是一个直接的窗口过程调用”,这意味着当我关闭窗口(例如单击X
按钮)时,系统会使用消息参数 == WM_DESTROY 隐式调用 WndProc?
点击X
按钮会引发连锁反应,其中一个步骤(但不是第一步)是系统将WM_DESTROY
消息发送到窗口。以上是关于WM_DESTROY 消息混淆的主要内容,如果未能解决你的问题,请参考以下文章