如果用户尝试关闭应用程序,我想显示“关闭查询”确认对话框。如果系统关闭或任务或进程正在从任务管理器结束,我只想清理并关闭。
我试过这段代码:
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;
弹出确认显示我是否关闭程序或从任务管理器终止进程。
答案 0 :(得分:3)
WM_QUERYENDSESSION是要处理的正确消息。这是在WM_ENDSESSION
之前发送的,根据以下VCL代码,您可以看到WMQueryEndSession立即调用CloseQuery
。
procedure TCustomForm.WMQueryEndSession(var Message: TWMQueryEndSession);
begin
Message.Result := Integer(CloseQuery);
end;
可以认为上述实现是VCL代码中的一个小错误,因为正如WM_QUERYENDSESSION
文档所述(强调我的):
每个应用程序应在收到此消息后立即返回TRUE或FALSE ,并推迟任何清理操作,直到收到WM_ENDSESSION消息。
应用程序可以显示一个用户界面,提示用户在关机时获取信息,但不推荐。 五秒后,系统会显示有关阻止关闭的应用程序的信息,并允许用户终止它们。例如,Windows XP显示一个对话框,而Windows Vista显示一个完整的屏幕,其中包含有关阻止关闭的应用程序的其他信息。如果您的应用程序必须阻止或推迟系统关闭,请使用ShutdownBlockReasonCreate
功能。有关详细信息,请参阅关闭Windows Vista的更改。
如果用户无法响应在5秒内弹出的对话框,则他们必须 终止 应用或取消关机。不幸的是,由于CloseQuery
通常用于提示用户,所以这样做并不是一个好主意
注意:这在Vista之前是完全可以接受的,上面的代码可能更像是一个遗留问题。但是,如果CloseQuery
至少被调整以指示关闭请求的来源,那么将很容易处理查询结束会话的具体情况。
所以鉴于我不想在响应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;
转到问题的第二部分。
以上原因不能通过任务管理器对 End Task 起作用,因为任务管理器不使用与shutdown相同的机制。它只是向您的应用程序发送WM_CLOSE
消息。
因此,您的应用程序的行为方式与“正常”关闭时的行为方式完全相同。事实上,您可以尝试使用记事本:
但是,如果希望/需要在从任务管理器关闭时阻止提示,则可以执行此操作。但是代码必须处理许多特殊情况,并且在所有版本的Windows上可能不会以完全相同的方式运行。 (所以你必须问自己,这是否值得付出努力。)
你必须至少满足3种情况:
让所有3个人按照你想要的方式行事会变得有点棘手。
WM_CLOSE
。因此,您必须在没有提示的情况下关闭“默认”行为。并使用Flag
启用提示。通过这种方式,选项3可以“静默地”关闭。WM_SYSCOMMAND
SC_CLOSE
后跟WM_CLOSE
。因此,您可以设置Flag
以响应第一条消息。因此,您的用户将收到提示。Close
来实现。但为了确保您获得提示,您必须先设置Flag
。Flag
。最后的想法
我个人认为“近距离确认”非常烦人。当然,我习惯经常保存,所以不要冒着丢失数据的风险。
基本上,提示关闭的唯一合理理由是防止未保存数据的意外数据丢失。如果您遵循此规则,您可以创建更愉快的用户体验:
当应用程序打开时,请务必将其恢复为 与其关闭时所处的完全相同的状态 。
即。如果文档有未保存的数据,请将其存储在临时文件中。当应用程序重新打开时,文档将自动置于关机状态下的“编辑”状态。
(是的。也许这只是过于简单化了,但这个想法在移动设备上非常适用。)