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.
> 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.
Ohhhh.. I forgot this.. Thanks ! Il try adding the procedure that was added by "qyte"! :D Thanks! :D
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
You fail to return a message result of 1 (<> 0) from your message handler.
> 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!
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...
>> 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 :)
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>...
>> 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;
...
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.
>> > 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