gpt4 book ai didi

delphi - 了解堆栈跟踪以进行消息处理

转载 作者:行者123 更新时间:2023-12-03 19:48:07 27 4
gpt4 key购买 nike

我在主窗体上放置了TApplicationEvents组件,并添加了以下事件代码:

procedure TAniWinMainForm.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
begin
if (ActiveMDIChild is TFormStartDialog) and
(Msg.Message = WM_KEYDOWN) and (Msg.WParam = VK_F4) then
Handled := True;
end;


部署应用程序后,我通过以下EurekaLog错误报告从用户报告了 EInvalidOp错误:

Modul Name   : KERNELBASE.dll
Typ : EInvalidOp


|77A4E60A|ntdll.dll | | |NtCallbackReturn | |
|74515EAA|win32u.dll | | |NtUserGetPointerInfoList | |
|754595F9|user32.dll | | |GetPointerTouchInfo | |
|778E3923|msvcrt.dll | | |sqrt | |
|778E388D|msvcrt.dll | | |sqrt | |
|778E387B|msvcrt.dll | | |_CIsqrt | |
|778E3870|msvcrt.dll | | |_CIsqrt | |
|75460AC0|user32.dll | | |SendMessageW | |
|77A235DB|ntdll.dll | | |RtlDeactivateActivationContextUnsafeFast| |
|75470090|user32.dll | | |CallWindowProcA | |
|00CA5549|Program.exe |MAIN.pas |TMainForm |ApplicationEvents1Message |700[1] |
|7547BC0B|user32.dll | | |DispatchMessageA | |
|7547BC00|user32.dll | | |DispatchMessageA | |
|00D1376A|Program.exe |Program.dpr| | |1145[477]|
|772962C2|KERNEL32.DLL| | |BaseThreadInitThunk | |


我猜该错误与我的代码无关,但我不知道可能会发生什么。
谁能解释一下导致此堆栈跟踪的原因?
我不应该看到哪个函数正在调用CallWindowProcA吗?

最佳答案

我的猜测是对CallWindowProcA的调用是由ActiveMDIChild进行的。那是一个其getter如下所示的属性:

function TCustomForm.GetActiveMDIChild: TForm;
begin
Result := nil;
if (FormStyle = fsMDIForm) and (FClientHandle <> 0) then
Result := TForm(FindControl(SendMessage(FClientHandle, WM_MDIGETACTIVE, 0,
0)));
end;


您可能希望在调用堆栈中的 SendMessage上方看到 ApplicationEvents1Message,但是我怀疑EurekaLog堆栈跟踪代码不足以在Win32 API函数中找到它。现在,对 SendMessage的调用将调用客户端窗口的窗口过程,因此对 CallWindowProcA的调用非常合理。

至于实际的问题,这闻起来很像Win32代码中的问题,希望浮点异常被掩盖。我建议您在引用 ActiveMDIChild之前掩盖异常。

我也强烈建议您在 if语句中更改条件的顺序。程序处理的每个单个排队的消息都调用此事件。您真的不想读取每个属性的 ActiveMDIChild属性。像这样写 if语句:

if (Msg.Message = WM_KEYDOWN) and
(Msg.WParam = VK_F4) and
(ActiveMDIChild is TFormStartDialog) then


因此,您可以像这样重新编写事件处理程序:

procedure TAniWinMainForm.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
var
Save8087CW: Word;
begin
if (Msg.Message = WM_KEYDOWN) and (Msg.WParam = VK_F4) then
begin
Save8087CW := Get8087CW;
Set8087CW($027F); // this is the default Windows control word, with floating point exceptions masked
if ActiveMDIChild is TFormStartDialog then
Handled := True;
Set8087CW(Save8087CW);
end;
end;

关于delphi - 了解堆栈跟踪以进行消息处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44155569/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com