Intercept WM_CLOSE for cleanup operations
Asked Answered
U

4

5

I have an external application that calls my application and is supposed to end it when the job is done. The log from this external application claims it uses WM_CLOSE on my app.

How can I intercept the WM_CLOSE message in my application to do some cleanup operations? I tried at_exit() and wrapping it in a class, but I think I have the wrong approach.

Underskirt answered 2/1, 2012 at 8:41 Comment(3)
Do you use some kind of framework in your application? Does that have an OnClose function to override?Crain
Does your app have a message loop where you handle other Windows messages?Lactiferous
No, so far its only a consolse application.Underskirt
V
2

You could just handle WM_CLOSE in your message loop to do whatever cleanup is necessary, or even abort the close (by returning 1 instead of 0). See e.g. this: http://cboard.cprogramming.com/windows-programming/141438-handling-wm_close-wm_destroy.html#post1056273

Edit: for console applications, this may be of interest: http://support.microsoft.com/kb/178893

Volute answered 2/1, 2012 at 8:48 Comment(4)
Thanks for the links, i am interested in changing it into a hidden window application. Do you have any starting links for me?Underskirt
This is older, but the code under "Message Processing" should be sufficient for a minimal application: functionx.com/win32/Lesson01b.htmVolute
Ok, thanks for your support. I found a good tutorial: winprog.org/tutorialUnderskirt
If your console application is singlethreaded, you will have to pump your window message loop (call GetMessage,...) from time to time, and each time check if WM_CLOSE arrived. Other solution is to create window in seprate thread.Timely
E
5

The official solution for console applications is HandlerRoutine, a callback set by SetConsoleCtrlHandler. Windows will call your handler with a CTRL_CLOSE_EVENT argument in case of a WM_CLOSE exit.

When you're using a class method with SetConsoleCtrlHandler, it must be a static method - Windows won't provide you with a this pointer.

Extant answered 2/1, 2012 at 10:11 Comment(1)
Thanks for the addition, but I sucessfully changed it into a winapi application. If its not working out this way I might try your approach.Underskirt
T
2

You must create hidden window using winapi, and handle WM_CLOSE message in its message loop. Is your app using any gui elements?

Timely answered 2/1, 2012 at 8:46 Comment(1)
No its just a console application.Underskirt
V
2

You could just handle WM_CLOSE in your message loop to do whatever cleanup is necessary, or even abort the close (by returning 1 instead of 0). See e.g. this: http://cboard.cprogramming.com/windows-programming/141438-handling-wm_close-wm_destroy.html#post1056273

Edit: for console applications, this may be of interest: http://support.microsoft.com/kb/178893

Volute answered 2/1, 2012 at 8:48 Comment(4)
Thanks for the links, i am interested in changing it into a hidden window application. Do you have any starting links for me?Underskirt
This is older, but the code under "Message Processing" should be sufficient for a minimal application: functionx.com/win32/Lesson01b.htmVolute
Ok, thanks for your support. I found a good tutorial: winprog.org/tutorialUnderskirt
If your console application is singlethreaded, you will have to pump your window message loop (call GetMessage,...) from time to time, and each time check if WM_CLOSE arrived. Other solution is to create window in seprate thread.Timely
E
2

The easiest way I think is to call PeekMessage from time to time.

BOOL IsCloseEventReceived()
{
    MSG msg;
    return PeekMessage(&msg, NULL, WM_CLOSE, WM_CLOSE, PM_NOREMOVE);
}

This function should work to check if a WM_CLOSE message has been posted. It's not blocking, and you'll need to call it on a regular basis.

I might be wrong, but I think you don't need a hidden window to handle messages, a message queue is attached to your process the first time you call a messages-related function, like PeekMessage. However if you receive a WM_CLOSE message prior to your first call of this function it might be lost.

Esqueda answered 3/1, 2012 at 10:53 Comment(3)
Ok, but then i need to make a loop which checks every 200ms for the signal, right?Underskirt
Yes, or if you already have a loop in your code that's executed regularly you might insert it there (if the place gets executed too often you might add a counter and make a check once every 1000 times or something so you don't affect performace too much). That way you won't need to change your control flow.Esqueda
Tried it. Works great! I already had a loop running so it fitted in with minimal changes. Best of all, it didn't need a hidden Window.Ambrosia

© 2022 - 2024 — McMap. All rights reserved.