问题
To detect and prevent shutdown the computer I use very simple program. It has only one form and one private procedure like below:
TForm3 = class(TForm)
private
procedure WMQueryEndSession(var Msg : TWMQueryEndSession) ;
message WM_QueryEndSession;
end;
and the implementation
procedure TForm3.WMQueryEndSession(var Msg: TWMQueryEndSession);
begin
Msg.Result := 0; //so I don't want to shutdown while my program is running
end;
I compiled it Delphi 5 and Delphi 2010. Both of them detect shutdown. But when I compiled in Delphi 2010; after preventing shutdown my program closes. (PC doesn't shutdown)
How do I get the same result from both of them?
回答1:
This looks like a bug in Delphi. I suggest you to post this on Quality Central.
回答2:
EDIT: changed to intercept WM_ENDSESSION instead of WM_QUERYENDSESSION.
As you cannot directly change the behaviour of TApplication, you can install a TApplication message hook instead that neutralizes the WM_ENDSESSION message.
Installing such a hook is quite simple, you only have to add a method similar to the following to your mainform and register the hook in FormCreate.
function TForm25.HookEndSession(var Message: TMessage): Boolean;
begin
result := false;
if Message.Msg = WM_ENDSESSION then begin
Message.Result := 0;
result := true;
end;
end;
procedure TForm25.FormCreate(Sender: TObject);
begin
Application.HookMainWindow(HookEndSession);
end;
回答3:
I usually run "shutdown -a" command. You can do the same from your code to interrupt Windows from shutdown.
Regards
回答4:
Edit: Here's an approach that doesn't work. Thanks
Procedure TMyForm.FormClose(Sender: TObject; Var Action: TCloseAction);
Begin
Action := caNone; //The form is not allowed to close, so nothing happens.
End; // Note: the OP says he tried this, doesn't help. See the comments.
回答5:
Are you testing on the same OS? There are some application shutdown changes in Vista. Read this: Application Shutdown Changes in Windows Vista
If you are testing on the same OS, maybe Delphi 2010 handles WM_ENDSESSION messages in a different way. In Delphi 7, WM_ENDSESSION message are handled in Application.WndProc.
回答6:
In all versions should you not be using the FormCloseQuery event?
procedure TForm3.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
Canclose := Not StillDoingImportantStuff;
end;
Oops - just read comments to "this does not work" :( Is win 7 different?
In all my apps this gets called if windows is trying to shut down...
回答7:
ShutdownGuard is built with Delphi and it's open source, you can download it tweak it for your needs
来源:https://stackoverflow.com/questions/3085267/preventing-windows-shut-down