gpt4 book ai didi

Delphi防止应用程序关闭

转载 作者:行者123 更新时间:2023-12-03 14:56:17 25 4
gpt4 key购买 nike

我试图阻止我的应用程序被 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 并删除 sleep 不会改变任何内容。

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在你开始工作之前。
  • 工作返回时FALSE来自WM_QUERYENDSESSION 。处理此消息时请勿工作。立即返回。
  • 工作完成后,请调用 ShutdownBlockReasonDestroy

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那么就太晚了。不管怎样,系统都会崩溃。

To test it I simply send "end task" to it through the task manager.

这与关闭阻止无关。测试关闭阻止的方法是注销。如果用户坚持终止您的进程,您无能为力。 Sertac 的回答详细介绍了这一点。

最后,忽略 API 调用的返回值也是一种非常糟糕的形式。不要那样做。

关于Delphi防止应用程序关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25536216/

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