在关闭应用程序期间停止 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);
}
所以本质上是这样的:
在这种情况下,检查我的自定义 WM_APP
范围消息(WM_SETTINGS_UPDATE
和 WM_GUI_UPDATE
)。
处理这些消息然后将 fMessage.Result
设置为 1
表示消息已处理并且 returns(避免 TForm:WndProc(fMessage)
,我的理解是与 Delphi 中的 inherited
相同,如果处理消息则不需要)。
如果我的消息没有被处理,它只是调用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)?
自定义消息完全可以。
我定义了一个类似于下面的 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);
}
所以本质上是这样的:
-
在这种情况下,
检查我的自定义
WM_APP
范围消息(WM_SETTINGS_UPDATE
和WM_GUI_UPDATE
)。处理这些消息然后将
fMessage.Result
设置为1
表示消息已处理并且 returns(避免TForm:WndProc(fMessage)
,我的理解是与 Delphi 中的inherited
相同,如果处理消息则不需要)。如果我的消息没有被处理,它只是调用
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 (setResult
to 1 and return)?
自定义消息完全可以。