在关闭应用程序期间停止 WndProc 处理

Stop WndProc processing during shutdown of the app

我定义了一个类似于下面的 WndProc(代码是用 C++Builder 编写的,但它也以类似于 Delphi 的形式应用):

#define WM_SETTINGS_UPDATE WM_APP + 1234
#define WM_GUI_UPDATE      WM_APP + 1235

void __fastcall TForm1::WndProc(TMessage &fMessage)
{
switch (fMessage.Msg)
    {
    default:                 break;

    case WM_SETTINGS_UPDATE: ProcessMySettingsUpdate();
                             fMessage.Result = 1;
                             return;
                             break; // I know this is not needed, I do this purely for aesthetics

    case WM_GUI_UPDATE:      ProcessMyGUIUpdate();
                             fMessage.Result = 1;
                             return;
                             break; // I know this is not needed, I do this purely for aesthetics
    }

TForm::WndProc(fMessage);
}

所以本质上是这样的:

    在这种情况下,
  1. 检查我的自定义 WM_APP 范围消息(WM_SETTINGS_UPDATEWM_GUI_UPDATE)。

  2. 处理这些消息然后将 fMessage.Result 设置为 1 表示消息已处理并且 returns(避免 TForm:WndProc(fMessage),我的理解是与 Delphi 中的 inherited 相同,如果处理消息则不需要)。

  3. 如果我的消息没有被处理,它只是调用TForm:WndProc(fMessage)(或inherited)进行默认处理。

我担心的是 - 如果出现应用程序正在关闭的情况,并且仍有一些消息未处理(PostMessage() 留在消息队列中)怎么办?

在这种情况下我想做的是避免调用我自己的处理,因为它可能会导致一些未初始化的内存访问冲突或类似情况。这基本上够了吗,还是我需要应用一些特殊的处理来避免这种情况,或者处理一些“应用程序关闭”代码?

还有 - 我是否需要在完成处理后调用 inherited / TForm:WndProc(fMessage),还是像上面那样安全(将 Result 设置为 1和 return)?

注意 - 这不一定适用于 MainForm(正在创建的第一个表单)。

what if there is a situation where the application is shutting down, and there are still some messages being unprocessed (left in the message queue by PostMessage())?

完全可以。一旦表单的 HWND 被销毁,为该 window 发布的任何剩余消息将在主消息循环调度时被简单地丢弃。您的 WndProc 不会被叫到。

What I'd like to do in such a situation is to avoid calling my own processing, as it might result in some uninitialized memory Access Violations or similar.

这不应该是一个问题。第一,因为消息不会在你的表单被销毁后​​发送到 HWND,第二,当 MainForm 关闭时,主消息循环发出停止 运行 的信号,然后任何活动的表格 HWND 都被销毁。因此,无论如何不会有任何进一步的消息调度。

Is this basically enough, or do I need to apply some special processing to avoid that kind of situation

应该够了。您通常不需要处理这种特殊情况(除非您的自定义消息携带指向必须释放的对象的指针)。

or process some "application shutting down" code?

如果您真的想检测应用程序何时关闭,请尝试让您的 WndProc 处理 WM_CLOSE 消息(或者您可以使用表单的 OnClose/Query 事件)。

do I need to call inherited / TForm:WndProc(fMessage) after I am done with my processing, or is it safe to do it like above (set Result to 1 and return)?

自定义消息完全可以。