Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Detecting Windows Shutdown

334 views
Skip to first unread message

m0rt3n

unread,
Oct 25, 2005, 6:15:01 AM10/25/05
to

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.

qyte

unread,
Oct 25, 2005, 6:38:15 AM10/25/05
to

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.

krisztian pinter

unread,
Oct 25, 2005, 6:47:29 AM10/25/05
to
On 25 Oct 2005 03:15:01 -0700, m0rt3n <m0r...@epost.no> wrote:


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

m0rt3n

unread,
Oct 25, 2005, 7:09:09 AM10/25/05
to

"krisztian pinter" <pint...@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

Peter Below (TeamB)

unread,
Oct 25, 2005, 2:11:42 PM10/25/05
to
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


Peter Below (TeamB)

unread,
Oct 25, 2005, 2:11:43 PM10/25/05
to
In article <435e05a5$1...@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.

Krisztian Pinter

unread,
Oct 25, 2005, 2:34:08 PM10/25/05
to
On Tue, 25 Oct 2005 20:11:42 +0200, Peter Below (TeamB)
<10011...@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!

Peter Below (TeamB)

unread,
Oct 26, 2005, 2:24:04 PM10/26/05
to
In article <opsy7si6...@catv-5062d8e0.catv.broadband.hu>, Krisztian
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...

krisztian pinter

unread,
Oct 27, 2005, 3:19:48 AM10/27/05
to
On Wed, 26 Oct 2005 20:24:04 +0200, Peter Below (TeamB)
<10011...@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?

> 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 :)

Peter Below (TeamB)

unread,
Oct 27, 2005, 2:23:23 PM10/27/05
to
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.

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


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

Krisztian Pinter

unread,
Oct 27, 2005, 4:30:30 PM10/27/05
to
On Thu, 27 Oct 2005 20:23:23 +0200, Peter Below (TeamB)
<10011...@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;
...

Peter Below (TeamB)

unread,
Oct 28, 2005, 5:41:09 PM10/28/05
to
In article <opszbm84...@catv-5062d8e0.catv.broadband.hu>, Krisztian
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.

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

krisztian pinter

unread,
Oct 29, 2005, 6:52:44 AM10/29/05
to
On Fri, 28 Oct 2005 23:41:09 +0200, Peter Below (TeamB)
<10011...@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

0 new messages