Delphi阻止应用程序关闭
我试图阻止我的应用程序被
Windows关闭.
该应用程序在Windows 8上运行并以XE6编写. 我尝试了下面的代码,但它似乎完全被忽略了.为了测试它,我只需通过任务管理器向其发送“结束任务”. 我需要的是一种方法,让我的应用程序完成它在用户关闭应用程序时所执行的操作,由Windows关闭的任务管理器完成. 正常关闭不是问题,这由FormCloseQuery事件处理.但其他两种方法我都无法工作.直到windows XP,通过捕获wm_endsession和wm_queryendsession很容易,从vista开始你需要使用ShutDownBlockReasonCreate,它返回true但似乎无论如何都不起作用. procedure WMQueryEndSession(var Msg : TWMQueryEndSession); message WM_QUERYENDSESSION; procedure WMEndSession(var Msg: TWMEndSession); message WM_ENDSESSION; function ShutdownBlockReasonCreate(hWnd: HWND; Reason: LPCWSTR): Bool; stdcall; external user32; function ShutdownBlockReasonDestroy(hWnd: HWND): Bool; stdcall; external user32; procedure TForm1.WMEndSession(var Msg: TWMEndSession); begin inherited; Msg.Result := lresult(False); ShutdownBlockReasonCreate(Handle,'please wait while muting...'); Sleep(45000); // do your work here ShutdownBlockReasonDestroy(Handle); end; procedure TForm1.WMQueryEndSession(var Msg: TWMQueryEndSession); begin inherited; Msg.Result := lresult(False); ShutdownBlockReasonCreate(Handle,'please wait while muting...'); Sleep(45000); // do your work here ShutdownBlockReasonDestroy(Handle); end; 更新 将消息结果更改为true并删除睡眠不会改变任何内容. procedure TForm1.WMEndSession(var Msg: TWMEndSession); begin inherited; Msg.Result := lresult(True); ShutdownBlockReasonDestroy(Application.MainForm.Handle); ShutdownBlockReasonCreate(Application.MainForm.Handle,'please wait while muting...'); end; procedure TForm1.WMQueryEndSession(var Msg: TWMQueryEndSession); begin inherited; Msg.Result := lresult(True); ShutdownBlockReasonDestroy(Application.MainForm.Handle); ShutdownBlockReasonCreate(Application.MainForm.Handle,'please wait while muting...'); end; 解决方法
根据
documentation阻止关闭,你需要返回FALSE以响应WM_QUERYENDSESSION.
更重要的是,你不能在这个消息处理程序中工作.这项工作必须在别处进行.如果您未及时回复此消息,系统将不会等待您. >在开始工作之前调用ShutdownBlockReasonCreate. WM_QUERYENDSESSION的处理程序如下所示: procedure TMainForm.WMQueryEndSession(var Msg: TWMQueryEndSession); begin if Working then Msg.Result := 0 else inherited; end; 然后执行工作的代码需要在工作开始之前调用ShutdownBlockReasonCreate,在工作结束时调用ShutdownBlockReasonDestroy,并确保上面使用的Working属性在工作期间评估为True. 如果你的工作阻止主线程,那你就麻烦了.主线程必须是响应式的,否则系统不会等你.将工作放在一个线程中往往是前进的方向.如果您的主窗口不可见,那么您将无法阻止关闭.详情如下:http://msdn.microsoft.com/en-us/library/ms700677.aspx 如果你被发送到WM_ENDSESSION,那就太晚了.系统正在下降.
这与关闭阻塞无关.测试关闭阻塞的方法是注销.如果用户坚持要求杀死您的流程,那么您无能为力. Sertac的答案详细介绍了这一点. 最后,忽略API调用的返回值也是非常差的形式.不要那样做. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |