【问题标题】:WM_DESTROY message confusionWM_DESTROY 消息混淆
【发布时间】: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_DESTROYsent 并直接进入窗口 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) 上查看更多信息。

标签: c++ windows visual-studio


【解决方案1】:

PeekMessage(或GetMessage)自行调度发送的消息(来自其他线程)而不返回它们。它只返回已发布的消息。如果消息是由同一个线程发送的,它甚至不会通过PeekMessages,它实际上是一个直接的窗口过程调用。 WM_DESTROY 已发送。

顺便说一句,避免不将系统消息传递给DefWindowProc,包括WM_DESTROY

【讨论】:

  • 抱歉,没听懂。 “自己发消息”和“只发消息”是什么意思?
  • 我已经编辑了我的答案,希望现在更清楚
  • 好的,谢谢。为了澄清。 “它实际上是一个直接的窗口过程调用”,这意味着当我关闭窗口(例如单击X 按钮)时,系统会使用消息参数 == WM_DESTROY 隐式调用 WndProc?
  • 点击X按钮会引发连锁反应,其中一个步骤(但不是第一步)是系统将WM_DESTROY消息发送到窗口。
猜你喜欢
  • 1970-01-01
  • 2013-09-24
  • 1970-01-01
  • 2016-12-22
  • 1970-01-01
  • 2021-03-21
  • 2018-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多