Board index » delphi » Help! Can't trap WM_QUERYENDSESSION

Help! Can't trap WM_QUERYENDSESSION

I have a systemtray app that works just fine except when I try to
close windows it prevents it happening. I added the following but it
still doesn't allow the close. Where am I going wrong??

The OnMessage event is called twice during closing but the Msg is = to
zero both times.

procedure TfrmMainSoooEasy.FormCreate(Sender: TObject);
begin
  Application.OnMessage:=MsgReallyClose;
  // This is declared as a procedure in "Private"
end;

procedure TfrmMain.MsgReallyClose(var Msg: TMsg; var Handled:
Boolean);
begin
  if Msg.Message = wm_QueryEndSession then
  begin
    ReallyClose:=True; // Never seems to get here
    Handled:=True;
  end;
end;

procedure TfrmMain.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
  CanClose:=ReallyClose;
  if not ReallyClose then
    Visible:=False;
end;

--

Grumpy, the Third Dwarf
(Dave Johnson)

*****************************************
If I were taller, I wouldn't be so short!
      Dyslexics of the world, untie
*****************************************

 

Re:Help! Can't trap WM_QUERYENDSESSION


"Grumpy, the Third Dwarf" schrieb:

Quote

> I have a systemtray app that works just fine except when I try to
> close windows it prevents it happening. I added the following but it
> still doesn't allow the close. Where am I going wrong??

> The OnMessage event is called twice during closing but the Msg is = to
> zero both times.

> procedure TfrmMainSoooEasy.FormCreate(Sender: TObject);
> begin
>   Application.OnMessage:=MsgReallyClose;
>   // This is declared as a procedure in "Private"
> end;

[snip]

I didn't test your code, but try to catch the message *before*
Application sees it:

  TfrmMain= class(TForm)
  private
    procedure WMQueryEndSession(var Message: TWMQueryEndSession);
message WM_QUERYENDSESSION;

procedure TfrmMain.WMQueryEndSession(var Message: TWMQueryEndSession);
begin
  // do what you want here
  inherited;
  // or even return 0 without calling inherited
  // to stop Windows from shutting down
end;

-Michael

Re:Help! Can't trap WM_QUERYENDSESSION


On Wed, 10 May 2000 09:19:54 +0200, Michael Winter <m...@aquila.de>
wrote:

Thanks Michael,

Quote
>>  TfrmMain= class(TForm)
>>  private
>>    procedure WMQueryEndSession(var Message: TWMQueryEndSession);
>>message WM_QUERYENDSESSION;

I had finally fixed it out of frustration and trial and error. This
was the only bit I didn't show in the original posting and it turned
out to be the "message WM_QUERYENDSESSION;" following the declaration
in the Private section. I had **not** added it to the declaration.

Because there was no "Message..." it was treated as a normal procedure
and not a message handler.

Quote
>>procedure TfrmMain.WMQueryEndSession(var Message: TWMQueryEndSession);
>>begin
>>  // do what you want here
>>  inherited;
>>  // or even return 0 without calling inherited
>>  // to stop Windows from shutting down
>>end;

A little confused here though. If I include the "Inherited" are you
saying that will prevent Windows closing? What is the purpose of
"Inherited" in this position?

Also how can one return Zero in a procedure??? Are you suggesting I
set the "Message.Msg:=0" since it is a Var parameter?

I will post the full code for closing the systemtray app later today
as I had the devils own job finding a solution on DejaNews or the MER
database. There were a lot of alluding to what to do but no code
samples. I'd appreciate a reply on the "Inherited" questions above as
it would be good to include that in the code too.

The most important part though was the Message declaration as part of
the original procedure declaration in the Private section. Very
confusing as it worked both ways albeit **quite differently** when it
was made a Message Handler.

Thanks again.

--

Grumpy, the Third Dwarf
(Dave Johnson)

*****************************************
If I were taller, I wouldn't be so short!
      Dyslexics of the world, untie
*****************************************

Re:Help! Can't trap WM_QUERYENDSESSION


"Grumpy, the Third Dwarf" schrieb:

Quote
> I had finally fixed it out of frustration and trial and error. This
> was the only bit I didn't show in the original posting and it turned
> out to be the "message WM_QUERYENDSESSION;" following the declaration
> in the Private section. I had **not** added it to the declaration.

This makes the compiler think it is a 'normal' procedure. But you should
get a warning like 'The private procedure blabla is declared but never
used.'

Quote
> >>procedure TfrmMain.WMQueryEndSession(var Message: TWMQueryEndSession);
> >>begin
> >>  // do what you want here
> >>  inherited;
> >>  // or even return 0 without calling inherited
> >>  // to stop Windows from shutting down
> >>end;

> A little confused here though. If I include the "Inherited" are you
> saying that will prevent Windows closing? What is the purpose of
> "Inherited" in this position?

WMQueryEndSession is introduced as a message handler in TCustomForm.
That's why under normal circumstances it's a good idea to call let
TCustomForm see that event by calling inherited. If you want prevent
Windows from shutting down, simply return 0 as Message.Result and do
*not* call inherited since this would return 1.

I just tested this, and it works: (And I just had to re-login sine I
clicked 'Yes'. <g>)

procedure TForm1.WMQueryEndSession(var Message: TWMQueryEndSession);
begin
  if MessageDlg('Shutdown Windows?', mtConfirmation, [mbYes, mbNo],
0)<>mrYes
  then Message.Result:=0
  else inherited;
end;

-Michael

Other Threads