我的应用程序中的某个地方(以及第三方代码库)是一个阻止
Windows的窗口过程:
我在我的代码中找到了一个位置,我在调用DefWindowProc时犯了一个非常常见的错误,但调用错误:
FbroadcastListenerHwnd := AllocateHWnd(broadcastListenerWindowProc); procedure TGrobber.broadcastListenerWindowProc(var msg: TMessage); begin DefWindowProc(FbroadcastListenerHwnd,msg.msg,msg.wparam,msg.lparam); end;
我修复了那个bug,而我的test program不再停止关机了.
但完整的应用程序
我现在面临着不得不撕掉一个程序,直到我的计算机终于重新启动.
在我的应用程序内部的某个地方是一个附加到HWND的Window过程,它返回零到WM_QUERYENDSESSION
.如果我只知道HWND,我可以使用Spy找到Window.
但我怎么能找到那个人呢?
Windows应用程序事件日志记录了停止关闭的过程:
并且在更详细的应用程序和服务日志中有更详细的日志.但那些没有证件.
我怎样才能找到有问题的hwnd?
尝试
我尝试使用EnumThreadWindows来获取我的“主”线程的所有窗口,并想要手动向它们发送WM_QUERYENDSESSION以查看谁返回false:
var wnds: TList<HWND>; function DoFindWindow(Window: HWnd; Param: LParaM): Bool; stdcall; var wnds: TList<HWND>; begin wnds := TList<HWND>(Param); wnds.Add(Window); Result := True; end; wnds := TList<HWND>.Create; enumProc := @DoFindWindow; EnumThreadWindows(GetCurrentThreadId,EnumProc,LParaM(wnds));
现在我列出了12个hwnds.戳他们:
var window: HWND; res: LRESULT; for window in wnds do begin res := SendMessage(window,WM_QUERYENDSESSION,0); if res = 0 then begin ShowMessage('Window: '+IntToHex(window,8)+' returned false to WM_QUERYENDSESSION'); end; end;
但没有人确实归零.
所以这是排水管的一个管.
EnumThreadWindows只枚举一个特定线程的窗口.可能是在一个线程中创建了违规窗口.因此,我建议您使用EnumWindows在您的应用程序中枚举所有顶级窗口以进行测试.
它足以在一个线程中初始化COM,你将拥有一个你不知道的窗口.这样在线程中调用WaitForSingleObject可能是你的罪魁祸首:
Debugging an application that would not behave with WM_QUERYENDSESSION
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。