开发者

Preventing Windows shut down

开发者_StackOverflow中文版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?


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;


I usually run "shutdown -a" command. You can do the same from your code to interrupt Windows from shutdown.

Regards


This looks like a bug in Delphi. I suggest you to post this on Quality Central.


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.


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.


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...


ShutdownGuard is built with Delphi and it's open source, you can download it tweak it for your needs

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜