tags:

views:

279

answers:

2

There are a few options here, probably, but what would you suggest to be the safest way to accomplish the following:

I've got a child CFrameWnd with a parent = NULL (so that it can live a separate life from the main application, while the app is running, at least). I've got all those windows stored in a list. When the main app is closing (MainFrame getting an OnClose), I go through the array and issue a PostMessage(WM_CLOSE) to all. However, the problem is that each of them has to do stuff before closing down. So, I need to wait for them. But we're all on the same thread... So, how can I wait for the children to close, without blocking their own processing in a single-threaded application?

Or should I launch a worker thread to take care of that? Would it be easier?

Thanks in advance!

+2  A: 

Use SendMessage() instead of PostMessage().

Edit: Another option might be to simply handle WM_DESTROY in your child windows (depending on your code of course).

Peter Ruderman
Yes, of course... WM_DESTROY is too late for me, but SendMessage is what I need - sometimes obvious things lie in front of you :) Thanks.
dennisV
+1  A: 

Well you certainly can't just wait for them to close, you need to at least pump messages so that they would receive and handle the WM_CLOSE. How you do that is up to you I guess. But I see you are doing PostMessage. Why not do SendMessage instead - this will run the close synchronously in the window procedure for the window. Or are you trying to quit the app? Then you should really use PostQuitMessage then pump messages in the normal fashion until GetMessage returns 0. Lots of options.

Pumping messages means to have a loop in your code that looks like this. You don't have to call AfxPumpMessages, but that would probably do something similar. There are in fact many different ways to pump messages depending on what you want to do. In addition there are quite a few functions that pump messages for you.

BOOL bRet;

// note that GetMessage returns 0 when WM_QUIT is received - this is how PostQuitMessage
// would work to get us to shut down
// We are passing NULL for the hWnd parameter - this means receive all window and
// thread messages for this thread
while( (bRet = GetMessage( &msg, NULL /* hWnd */, 0, 0 )) != 0)
{ 
    if (bRet == -1)
    {
        // handle the error and possibly exit
    }
    else
    {
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    }
}

If you post the message to a window or windows, then you need to pump messages. What happens is that the message goes into a queue for the thread associated with that window (this thread) - the message pump extracts them out and dispatches them off to the correct window procedure.

If you had sent the message instead of posting it, then the window procedure for the window is called directly - rather than going into a queue. You wouldn't need to pump messages because once SendMessage returns the message is fully handled.

The way PostQuitMessage works is by setting a flag on the message queue indicating that the application should quit. The WM_QUIT message isn't really a window message that you would send - what happens is that GetMessage will check this flag after all the other posted window messages are processed and returns 0 if it is set. This will cause all windows to correctly close, and you don't need to send it to the windows themselves.

1800 INFORMATION
Yes, I could use AfxPumpMessage, but that won't work on a single thread. SendMessage seems the best way to go. Yes, I'm quitting the app and PostQuitMessage is a good idea - but I didn't understand exactly how I can PostQuitMessage, then pump messages while a GetMessage returns 0 - is that GetMessage in the main window? It can returns 0 at many other times. Not really sure what you mean there. Thanks!
dennisV
I've added some more detail on how message pumps work and the secret behaviour of PostQuitMessage. You should really check it out since you seem to have some basic misunderstandings on message handling
1800 INFORMATION
I understand the difference between Post and Send, but thanks for the code snippet - it may prove useful in some other instance! SendMessage works well, so I'll stick to using that, unless there's a reason not to.
dennisV
GetMessage only returns 0 if WM_QUIT is received, in all other circumstances it returns something other than 0. This is well documented in MSDN http://msdn.microsoft.com/en-us/library/ms644936(VS.85).aspx.
1800 INFORMATION