OnCloseQuery
メッセージに応答してイベントがトリガーされた場合WM_QUERYENDSESSION
、設定CanClose=False
するとメッセージが返されFALSE
ます。
XP以前では、Windowsのシャットダウンがキャンセルされます。その時点まで、メッセージを受信したアプリは、それらのアプリに終了しないように指示する値が設定されたメッセージWM_QUERYENDSESSION
を受信します。これが、アプリがトレイに移動し、Windowsのシャットダウン中に終了しない理由です。WM_ENDSESSION
wParam
FALSE
MicrosoftはWindowsVistaでこの動作を変更したため、アプリはWindowsのシャットダウンをキャンセルできなくなりWM_QUERYENDSESSION
ました。これが、WindowsVista以降でアプリが終了する理由です。アプリが意図的にWindowsのシャットダウンを停止する必要がある場合は、まったく新しいAPIが導入されています。
これはMSDNに文書化されています:
WindowsVistaでのアプリケーションシャットダウンの変更
WM_QUERYENDSESSION
求めていることを実行するには、メッセージを直接インターセプトして、OnCloseQuery
Windowsのシャットダウンが原因で呼び出されているかどうかを判断できるようにする必要があります。例えば:
type
TForm1 = class(TForm)
private
procedure WMQueryEndSession(var Message: TWMQueryEndSession); message WM_QUERYENDSESSION;
procedure WMEndSession(var Message: TWMEndSession); message WM_ENDSESSION;
end;
var
ShuttingDown: Boolean = False;
procedure TForm1.WMQueryEndSession(var Message: TWMQueryEndSession);
begin
ShuttingDown := True;
inherited;
end;
procedure TForm1.WMEndSession(var Message: TWMEndSession);
begin
ShuttingDown := Message.EndSession;
inherited;
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
CanClose := ShuttingDown;
if not ShuttingDown then
begin
// your Tray logic here ...
end;
end;