Solved

Detecting windows shutdown.

Posted on 2002-07-26
19
689 Views
Last Modified: 2007-12-19
Hi folks,

I need a bit of help.  I've got an application which I have password protected to prevent it from being closed.  However, if the user whats to do a Windows shutdown, the app asks for a password still.  I would like a way of being able to detect when Windows is shutting down/restarting and override the CloseQuery (CanClose) for the main form.

I've experimented with Procedure WMEndSession(var Msg : TWMEndSession); message WM_ENDSESSION, but it was never triggered.

Any help at all would be greatfully accepted :P

Cheers!

Stu
0
Comment
Question by:Stuart_Johnson
  • 10
  • 9
19 Comments
 
LVL 20

Expert Comment

by:Madshi
ID: 7181676
You have to handle WM_QUERYENDSESSION.

Regards, Madshi.
0
 
LVL 6

Author Comment

by:Stuart_Johnson
ID: 7181685
I realise that, Madshi :)

procedure TMainForm.WMEndSession(var Msg : TWMEndSession);
begin
  if Msg.EndSession = TRUE then
    TerminateWithoutPassword := true;
    end;
  inherited;
end;              

This is what I'm using now, and it's never triggered.

Stu
0
 
LVL 6

Author Comment

by:Stuart_Johnson
ID: 7181686
It was actually supposed to look like:

procedure TMainForm.WMEndSession(var Msg : TWMEndSession);
begin
  if Msg.EndSession = TRUE then
    TerminateWithoutPassword := true;
  inherited;
end;              

I just forgot to cut out the other end
0
 
LVL 20

Expert Comment

by:Madshi
ID: 7181691
:-)   I think this one should solve all your problems:

type
  TMainForm ...
    ...
    procedure WMQueryEndSession(var Msg: TMessage); message WM_QUERYENDSESSION;
    ...
  end;

procedure TMainForm.WMQueryEndSession(var Msg: TMessage);
begin
  Msg.result := 1;
end;

No need to handle WM_ENDSESSION. Also no need for a TerminateWithoutPassword box, I think...
0
 
LVL 20

Expert Comment

by:Madshi
ID: 7181693
Meant "TerminateWithoutPassword variable", not box, of course...
0
 
LVL 6

Author Comment

by:Stuart_Johnson
ID: 7181800
Hi Madshi,

Nope.  Didn't work.  I still have to close the application before windows will close.

I don't know if this makes a difference or not, but I'm testing this on XP Pro (I dont have any other systems here to test on either).

Stu
0
 
LVL 20

Expert Comment

by:Madshi
ID: 7181801
Hmmmm... Where do you show that password box? In FormCloseQuery or in FormClose? Try both, I think one should work. Sorry for not testing it for you, don't have the time right now...
0
 
LVL 6

Author Comment

by:Stuart_Johnson
ID: 7181821
Madshi,

The event isn't even fired.  It's like that message is completely ignored.  If I put a message box in like this:

procedure TMainForm.WMQueryEndSession(var Msg: TMessage);
begin
 Msg.result := 1;
 MessageBox('Closing');
end;

It never shows.

I have no idea why.  This same code used to work perfectly under Windows 95, 98, ME and NT4, but it just won't work with XP (unsure about 2000 because I havent tried it).

Stu
0
 
LVL 6

Author Comment

by:Stuart_Johnson
ID: 7181837
I'm upping the carrots, I mean points.  I really need this solved.

Stu
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 20

Expert Comment

by:Madshi
ID: 7181850
It does work on my XP professional. Please try this:

procedure TMainForm.WMQueryEndSession(var Msg: TMessage);
begin
  Msg.result := 0;
  MessageBoxA(0, 'Shutdown denied!', 'info', 0);
end;

Does the message box appear now?
0
 
LVL 6

Author Comment

by:Stuart_Johnson
ID: 7181917
Hi Madshi,

OK, I wrote a small sample application, and yes, I do get this message.  However, if I add in a closequery event for the form, Windows won't shut down.

Do this:

procedure TMainForm.WMQueryEndSession(var Msg: TMessage);
begin
 Msg.result := 1;
 Tag := 1;
end;

procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := Tag = 1;
end;

I'll guarentee you that you won't be able to shut down Windows anymore.

So, if I remove the CloseQuery event, my App does what it's supposed, but it defeats the purpose because I need the CloseQuery event active.

What do you think I can do?

Thanks for your help, Madshi.

Stu
0
 
LVL 20

Expert Comment

by:Madshi
ID: 7181943
Why do you need the FormCloseQuery event? Why not simply moving the code to FormClose? It should have exactly the same effect, except that shutting down will work again...

Regards, Madshi.
0
 
LVL 6

Author Comment

by:Stuart_Johnson
ID: 7181947
Because I have to test for a password.  I don't want the users to be able to just close this application when ever they want without a password.  The only time it should ever be shut is when Windows is turned off.  AFAIK there is no way to prevent an app from being shut down in the FormClose event is there?

  CanClose := true;
  if TerminateWithoutPassword or (FCloseCheckOption = 0) then
    CanClose := true
  else
    begin
      PasswordForm := TPasswordForm.Create(nil);
      if PasswordForm.ShowModal = mrOK then
        case FCloseCheckOption of
          1: CanClose := PasswordForm.PasswordEdit.Text = PasswordEdit.Text;
          2: CanClose := PasswordForm.PasswordEdit.Text = ShutDownPassword.Text;
        end;
      PasswordForm.Free;
    end;
end;


Cheers!

Stu
0
 
LVL 20

Expert Comment

by:Madshi
ID: 7181975
>> AFAIK there is no way to prevent an app from being shut down in the FormClose event is there?

Of course there is!! Set Action := caNone. That has the same effect as setting CanClose to false in the FormCloseQuery event.
0
 
LVL 6

Author Comment

by:Stuart_Johnson
ID: 7183358
I forgot about that :)

And yes, you're right.  It does have the same effect.  Including not allowing the PC to shutdown.

There seems to be no way to catch the shutdown/restart message before the application is attempted to be closed. This really sucks because it takes away so much functionality from my program.  I can not allow unauthorised users to shut it down, but I can't ask them for a password when they shutdown or restart Windows.

I guess I'm going to have to work out another way of doing this.

Thanks for the info Madshi.

Stu
0
 
LVL 20

Expert Comment

by:Madshi
ID: 7183450
No, Stu, <sigh>, my first comments were right from the beginning. I tested it in XP. If you handle WM_QUERYENDSESSION correctly, OnClose and OnCloseQuery are not even called. Did you really test what I suggested? It doesn't seem so to me...   :-(
0
 
LVL 20

Accepted Solution

by:
Madshi earned 150 total points
ID: 7183453
>> OK, I wrote a small sample application, and yes, I do get this message.  However, if I add in a closequery event for the form, Windows won't shut down.
>> Do this:
>> procedure TMainForm.WMQueryEndSession(var Msg: TMessage);
>> begin
>> Msg.result := 1;
>> Tag := 1;
>> end;
>> procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
>> begin
>>  CanClose := Tag = 1;
>> end;
>> I'll guarentee you that you won't be able to shut down Windows anymore.

Wrong, I am able to shut down Windows.
0
 
LVL 6

Author Comment

by:Stuart_Johnson
ID: 7301808
Hi Madshi,

Oops.  Sorry about this one.  I hardly use EE anymore, so I forgot about it :)

I never did get this working.  Your computers were the only ones this code ever worked correctly on.  None of my ones at work would work, or any of my friends.

Oh well, project was finished with this part taken out.

Thanks for all the info and help.

Stu
0
 
LVL 20

Expert Comment

by:Madshi
ID: 7301818
Then there must have been some component in your project (perhaps a third party component) which also handled those messages. Did you try with a brand new project?

Anyway, too late, I guess...   :-)
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now