提问人:Coder12345 提问时间:11/15/2023 最后编辑:Coder12345 更新时间:11/15/2023 访问量:37
BEGIN_MESSAGE_MAP vs 调度 vs WndProc
BEGIN_MESSAGE_MAP vs Dispatch vs WndProc
问:
在阅读了大量内容后,我得出的结论是,这 3 个本质上是处理自定义消息的相同内容:
使用 BEGIN_MESSAGE_MAP 宏:
#define WM_CUSTOM_MESSAGE WM_APP + 12345
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_CUSTOM_MESSAGE, TMessage, WMCustomMessageHandler);
END_MESSAGE_MAP(TForm)
void TForm1::WMCustomMessageHandler(TMessage &message)
{
// <code to handle custom message here>
}
或者扩展它并直接覆盖 Dispatch()(与上面的作用相同):
void __fastcall TForm1::Dispatch(void* message)
{
switch ((TMessage*)message->Msg)
{
case WM_CUSTOM_MESSAGE: // <code to handle custom message here>
break;
default: TForm::Dispatch(message);
break;
}
}
或覆盖 WndProc:
void __fastcall TForm1::WndProc(TMessage &message)
{
switch (message.Msg)
{
case WM_CUSTOM_MESSAGE: // <code to handle custom message here>
message.Result = 0;
break;
default: TForm::WndProc(message);
break;
}
}
在此示例中,使用一个比另一个有优势吗?从我收集到的信息来看,前两种方法级别较高,而最后一种方法级别较低,尽管不确定它会有什么区别。
我之所以问,是因为我收到WM_SETICON消息,当我的程序退出时,偶尔会因读取地址00000018而崩溃(崩溃跟踪到 )。这可能是我的程序中的错误,但也可能是我正在使用的 RAD Studio 10.4.2 中的错误。但是,当我使用 BEGIN_MESSAGE_MAP 时,这似乎不是问题,我切换到 WndProc 以提高可读性。TForm::WndProc(message);
解决此问题的另一种方法可能是在退出程序(事件)之前删除 WndProc 为默认值(例如保存然后),我发现这是不必要的,因为上面的代码实际上与原始 WndProc 没有任何不同,当它崩溃时没有处理自定义消息,因为它崩溃了 WM_SETICON,或者我在这里弄错了?DefaultWndProc
this->WindowProc = DefaultWndProc;
OnClose
答: 暂无答案
评论
WindowProc
默认指向,并调用任何未处理的消息。所以真的没有什么区别。 只是先得到消息。但是,地址 0 附近的访问冲突通常意味着正在取消引用空指针,这更有可能是你自己的代码中的错误,而不是 VCL 代码中的错误。WndProc
WndProc()
Dispatch()
WndProc()