gpt4 book ai didi

delphi - 如何区分 UI 关闭和使用 Delphi 强制关闭

转载 作者:行者123 更新时间:2023-12-02 06:16:25 27 4
gpt4 key购买 nike

如果用户尝试关闭应用程序,我想显示关闭查询确认对话框。如果系统关闭或任务或进程正在从任务管理器结束,我只想清理并关闭。

我试过这段代码:

private
procedure WMEndSession(var Message: TWMEndSession); message WM_ENDSESSION;

...
procedure TxxxForm.WMEndSession(var Message: TWMEndSession);
begin
gShuttingDown := Message.EndSession;
end;

...
procedure TxxxForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
Application.ProcessMessages;
if gShuttingDown then
CanClose := True
else
CanClose := MessageDlg('Are you sure you want to stop the close?', mtConfirmation,
[mbYes, mbNO], 0) = mrYes;
end;

弹出确认显示我是关闭程序还是从任务管理器终止进程。

最佳答案

WM_QUERYENDSESSION是要处理的正确消息。这是在 WM_ENDSESSION 之前发送的根据以下 VCL 代码,您可以看到 WMQueryEndSession 立即调用 CloseQuery .

procedure TCustomForm.WMQueryEndSession(var Message: TWMQueryEndSession);
begin
Message.Result := Integer(CloseQuery);
end;

可以认为上述实现是 VCL 代码中的一个小错误,因为 WM_QUERYENDSESSION文件状态(强调我的):

Each application should return TRUE or FALSE immediately upon receiving this message, and defer any cleanup operations until it receives the WM_ENDSESSION message.
Applications can display a user interface prompting the user for information at shutdown, however it is not recommended. After five seconds, the system displays information about the applications that are preventing shutdown and allows the user to terminate them. For example, Windows XP displays a dialog box, while Windows Vista displays a full screen with additional information about the applications blocking shutdown. If your application must block or postpone system shutdown, use the ShutdownBlockReasonCreate function. For more information, see Shutdown Changes for Windows Vista.



如果用户未能在 5 秒内对弹出的对话框做出响应,他们将不得不 终止应用程序或取消关机。不幸的是,自从 CloseQuery通常用于提示用户,因此这样做不是一个好主意。
注意:这在 Vista 之前是完全可以接受的,上面的代码可能更多的是遗留问题。但是,如果 CloseQuery 就好了。至少进行了调整以表明关闭请求的来源,以便于处理 Query End Session 的具体情况。

因此,鉴于我不希望弹出任何提示以响应 WM_QUERYENDSESSION,我实际上执行以下操作:
procedure TxxxForm.WMQueryEndSession(var Message: TWMQueryEndSession);
begin
Message.Result := 1;
{ Do not call inherited bc VCL may prevent/delay shutdown via
calls to: CloseQuery and CallTerminateProcs (in older
versions of Delphi).
As per Vista requirements, this should not be done. Use
ShutdownBlockReasonCreate and ShutdownBlockReasonDestroy to
control when shutdown is allowed. }
end;

继续你问题的第二部分。
上述方法不适用于通过任务管理器结束任务的原因是任务管理器不使用与关闭相同的机制。它只是发送一个 WM_CLOSE向您的应用程序发送消息。

因此,您的应用程序的行为方式与“正常”关闭时完全相同是完全可以接受的。实际上,您可以使用记事本尝试一下:
  • 打开记事本
  • 输入一些文字
  • 转到任务管理器,然后单击记事本的结束任务。
  • 您会看到记事本会提示确认,并且任务管理器将显示一个对话框,说明记事本正在等待用户的响应。 (至少在 Win7 中。)

  • 但是,如果您确实希望/需要在从任务管理器关闭时阻止提示,您可以这样做。但是代码必须处理一些特殊情况,并且可能不会在所有版本的 Windows 上以完全相同的方式运行。 (所以你必须问自己是否真的值得付出努力。)

    您必须满足至少 3 种情况:
  • 从应用程序中的自定义菜单或按钮关闭。
  • 从标准 Windows 命令关闭:右上角的 X、系统菜单或双击左上角、Alt+F4 组合键。
  • 最后从任务管理器关闭。

  • 让这三个人都按照你想要的方式行事有点棘手。
  • 选项 3 发送 WM_CLOSE .因此,您必须在没有提示的情况下关闭“默认”行为。并使用 Flag启用提示。这样,选项 3 可以“静默”关闭。
  • 选项 2 首先发送 WM_SYSCOMMANDSC_CLOSE后跟 WM_CLOSE .所以你可以设置你的Flag响应第一条消息。因此,您的用户将收到提示。
  • 选项 1 很可能通过调用 Close 来实现.但是为了确保你得到提示,你必须设置你的 Flag第一的。
  • 不要忘记清除您的Flag如果您的用户选择不关闭应用程序。


  • 最后的想法

    我个人觉得“关闭确认”很烦人。当然,我有经常保存的习惯,所以不要冒险丢失数据。

    基本上,提示关闭的唯一正当理由是防止未保存数据的意外数据丢失。如果您遵循以下规则,您可以创造更愉快的用户体验:

    When an app opens, always restore it to exactly the same state it was in when it closed.



    IE。如果文档有未保存的数据,请将其存储在临时文件中。当应用程序重新打开时,文档会自动置于与关闭时相同的“编辑”状态。

    (是的。也许这过于简单化了,但这个想法在移动设备上运行得非常好。)

    关于delphi - 如何区分 UI 关闭和使用 Delphi 强制关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28885657/

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