Board index » delphi » Detecting Windows Shutdown

Detecting Windows Shutdown

I have created an application that "lives" in the Tray.
When it is a form I use the OnCloseQuery to Close it to Tray insted of terminating it. I have added an event called WM_QueryEndSession to detect the shutdown.
But when I shutdown/logoff my Windows User the application just crashes and stalls and stops Windows from quitting.
But to try this out I made my own app and sent the same message using SendMessage to my applications main form to check if the event fires or not. And this worked!
Why wont Windows do the same thing? Do Windows try to send the message to one of my other forms beside the mainform?

Morten.

 

Re:Detecting Windows Shutdown


Quote
m0rt3n wrote:
> I have created an application that "lives" in the Tray.
> When it is a form I use the OnCloseQuery to Close it to Tray insted of terminating it. I have added an event called WM_QueryEndSession to detect the shutdown.
> But when I shutdown/logoff my Windows User the application just crashes and stalls and stops Windows from quitting.
> But to try this out I made my own app and sent the same message using SendMessage to my applications main form to check if the event fires or not. And this worked!
> Why wont Windows do the same thing? Do Windows try to send the message to one of my other forms beside the mainform?

> Morten.

Declare a procedure in the private of you main form like

procedure AppOnMessage(var Msg: TMsg; var Handled: Boolean){of Object};

Go on form create and do the following:

Application.OnMessage:=AppOnMesage;

and then on the code

procedure TForm1.AppOnMessage(var Msg: TMsg; var Handled: Boolean);
begin
    if Msg.message = WM_QUERYENDSESSION then
    begin
        //your code goes here...
        Handled:=true;
    end;
    else
        Handled=false;
end;

I believe the above works.

Re:Detecting Windows Shutdown


On 25 Oct 2005 03:15:01 -0700, m0rt3n <m0r...@epost.no> wrote:

Quote
> I have added an event called WM_QueryEndSession to detect the shutdown.
> But to try this out I made my own app and sent the same message using  
> SendMessage to my applications main form to check if the event fires or  
> not. And this worked!

WM_QUERYENDSESSION is sent only to the top level forms. in a delphi
application, forms are not top level, but child forms of a hidden
window encapsulated in the Application object, and can be accessed
through Application.Handle. if you want to catch messages to this
window, you need Application.OnMessage.

Re:Detecting Windows Shutdown


Quote
"krisztian pinter" <pinte...@freemail.hu> wrote:
>WM_QUERYENDSESSION is sent only to the top level forms. in a delphi
>application, forms are not top level, but child forms of a hidden
>window encapsulated in the Application object, and can be accessed
>through Application.Handle. if you want to catch messages to this
>window, you need Application.OnMessage.

Ohhhh.. I forgot this.. Thanks ! Il try adding the procedure that was added by "qyte"! :D Thanks! :D

Re:Detecting Windows Shutdown


Quote
In article <opsy66xfwdwwfehv@kar_wst_pint>, Krisztian pinter wrote:
> WM_QUERYENDSESSION is sent only to the top level forms. in a delphi
> application, forms are not top level, but child forms of a hidden
> window encapsulated in the Application object, and can be accessed
> through Application.Handle. if you want to catch messages to this
> window, you need Application.OnMessage.

OnMessage only traps posted (POstMessage) messages, not send (SendMessage)
messages. WM_QUERYENDSESSION is send, not posted.

--
Peter Below (TeamB)  
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be

Re:Detecting Windows Shutdown


Quote
In article <435e05a...@newsgroups.borland.com>, M0rt3n wrote:
> I have created an application that "lives" in the Tray.
> When it is a form I use the OnCloseQuery to Close it to Tray insted
> of terminating it. I have added an event called WM_QueryEndSession
> to detect the shutdown.
> But when I shutdown/logoff my Windows User the application just crashes
> and stalls and stops Windows from quitting.

You fail to return a message result of 1 (<> 0) from your message handler.

--
Peter Below (TeamB)  
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be

Re:Detecting Windows Shutdown


On Tue, 25 Oct 2005 20:11:42 +0200, Peter Below (TeamB)  

Quote
<100113.1...@compuXXserve.com> wrote:
> OnMessage only traps posted (POstMessage) messages, not send  
> (SendMessage)
> messages. WM_QUERYENDSESSION is send, not posted.

if so, and it sounds true, we are doomed, as WM_QUERYENDSESSION is not
handled by the application window, at least not in D6.

but, and at this point i'm lost, WM_QUERYENDSESSION is handled buy
TCustomForm.

here's the snippet from win32 sdk:

------------------8<---------------------
ExitWindows

Windows NT: The ExitWindows function asks applications if they want to  
terminate by sending the WM_QUERYENDSESSION message to the main window of  
all running applications.
------------------8<---------------------

what's a main window? obviously not one without parent, although i thought  
so. another
question: what do they mean "the" main window? i'm not aware of such  
animal.

next question: why the OP does not receive it? because no TForm's ...  
existed? visible?

someone clear this out!

Re:Detecting Windows Shutdown


In article <opsy7si6n9lfy...@catv-5062d8e0.catv.broadband.hu>, Krisztian

Quote
Pinter wrote:
> if so, and it sounds true, we are doomed, as WM_QUERYENDSESSION is not
> handled by the application window, at least not in D6.

But of course it is, that has been there since D2, if memory serves. The
TApplication.WndProc handles both WM_QUERYENDSESSION and WM_ENDSESSION
properly.

TCustomform also has a message handler for WM_QUERYENDSESSION, that fires the
OnCloseQuery event. So it is easy to trap the message, on the form level you
simply declare a message handler for the message, if you really want to trap
it on the application level you use Application.HookMainWindow to install a
message hook for the application window.

The problem are helper windows created with AllocateHwnd if the message proc
used for them fails to pass unhandled messages to DefWindowProc. Poorly
written tray icon components often fall into this trap...

--
Peter Below (TeamB)  
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be

Re:Detecting Windows Shutdown


On Wed, 26 Oct 2005 20:24:04 +0200, Peter Below (TeamB)  

Quote
<100113.1...@compuXXserve.com> wrote:
>> if so, and it sounds true, we are doomed, as WM_QUERYENDSESSION is not
>> handled by the application window, at least not in D6.

> But of course it is, that has been there since D2, if memory serves. The
> TApplication.WndProc handles both WM_QUERYENDSESSION and WM_ENDSESSION
> properly.

better to look then remember. WM_ENDSESSION is handled, WM_QUERYENDSESSION
is not. what would it do anyway?

Quote
> TCustomform also has a message handler for WM_QUERYENDSESSION

it is exactly what i said. my question was, what "main window" might mean
in win32 sdk.

No offense, Peter, but i guess this post of yours was written without
really reading my post :)

Re:Detecting Windows Shutdown


Quote
In article <opszamnaxnwwfehv@kar_wst_pint>, Krisztian pinter wrote:
> > But of course it is, that has been there since D2, if memory serves. The
> > TApplication.WndProc handles both WM_QUERYENDSESSION and WM_ENDSESSION
> > properly.

> better to look then remember. WM_ENDSESSION is handled, WM_QUERYENDSESSION
> is not. what would it do anyway?

Return 1 as message result. D2005 does that but it looks like earlier
versions did not. It is a bit redundant anyway since DefWindowProc does that
already.

Quote
> it is exactly what i said. my question was, what "main window" might mean
> in win32 sdk.

Actually any window that is not a child of another window will get the
message, not only the main window (which is actually not distinguishable
from other windows an application may have by any particular set of window
styles). The term "main window" is just a convention, usually meant to
indicate the window that handles the main interaction with the user and
which will terminate the application when it is closed by the user.

Quote
> No offense, Peter, but i guess this post of yours was written without
> really reading my post :)

I did not follow the complete thread, true. Life is too short <g>...

--
Peter Below (TeamB)  
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be

Re:Detecting Windows Shutdown


On Thu, 27 Oct 2005 20:23:23 +0200, Peter Below (TeamB)  

Quote
<100113.1...@compuXXserve.com> wrote:
>> it is exactly what i said. my question was, what "main window" might  
>> mean
>> in win32 sdk.

> Actually any window that is not a child of another window will get the
> message

that's my problem. afaik, in a usual delphi program, there is no such
window, only the one in application.handle

all form's parent is application.handle. here is the code from Forms.pas:

procedure TCustomForm.CreateParams(var Params: TCreateParams);
var
   Icons: TBorderIcons;
   CreateStyle: TFormBorderStyle;
begin
   inherited CreateParams(Params);
   InitAlphaBlending(Params);
   with Params do
   begin
     if (Parent = nil) and (ParentWindow = 0) then
     begin
       WndParent := Application.Handle;
       Style := Style and not (WS_CHILD or WS_GROUP or WS_TABSTOP);
     end;
...

Re:Detecting Windows Shutdown


In article <opszbm84jxlfy...@catv-5062d8e0.catv.broadband.hu>, Krisztian

Quote
Pinter wrote:
> > Actually any window that is not a child of another window will get the
> > message

> that's my problem. afaik, in a usual delphi program, there is no such
> window, only the one in application.handle

No, you are confusing child windows with owned windows. Those are different
concepts on the API level. A child window has the WS_CHILD window style and
a parent window that contains it. A owned window does not have the WS_CHILD
style. What is a bit confusing is that the API uses the same field in the
window structure to store the handle of the parent or owner, and it is also
passed to CreateWindow(Ex) using the same field of the createparams record.

Quote

> all form's parent is application.handle. here is the code from Forms.pas:

Application.Handle is the API owner of all forms, not their parent. Owned
windows do get WM_QUERYENDSESSION.

--
Peter Below (TeamB)  
Use the newsgroup archives :
http://www.mers.com/searchsite.html
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be

Re:Detecting Windows Shutdown


On Fri, 28 Oct 2005 23:41:09 +0200, Peter Below (TeamB)  

Quote
<100113.1...@compuXXserve.com> wrote:
>> > Actually any window that is not a child of another window will get the
>> > message

>> that's my problem. afaik, in a usual delphi program, there is no such
>> window, only the one in application.handle

> No, you are confusing child windows with owned windows.

oh. that makes sense :)
thanks for clearing up

Other Threads