Если OnCloseQuery
события срабатывает в ответ на WM_QUERYENDSESSION
сообщений, установка CanClose=False
вызовет сообщение для возврата FALSE
.
В XP и более ранних версиях это приведет к отключению Windows. До этого момента любое приложение, получившее сообщение WM_QUERYENDSESSION
, получит сообщение WM_ENDSESSION
с его значением wParam
, установленным на FALSE
, сообщая этим приложениям NOT, чтобы закончить себя. Вот почему ваше приложение отправляется в лоток и не выходит во время выключения Windows.
Microsoft изменила это поведение в Windows Vista, поэтому приложения больше не могут отменять завершение работы Windows через WM_QUERYENDSESSION
. Вот почему Windows Vista и более поздние версии прекратят ваше приложение. Появился целый новый API, если приложение должно остановить остановку Windows.
Это описано в MSDN:
Application Shutdown Changes in Windows Vista
Для того, чтобы сделать то, что вы просите, вы должны перехватить 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;
А вы пробовали улавливание [ 'WM_QUERYENDSESSION'] (http://msdn.microsoft.com/en-us/library/aa376890%28VS.85%29.aspx) сообщение? – RRUZ
Я переместил свой комментарий на ответ. –