I have been confronted with unexpected behavior using

MsgWaitForMultipleObjects().

This function sits in a modeless dialog callback function, waiting for either a special set of events or a windows message.

Now what I expected is that once this function is called, your standard message loop is no longer accessible thus you have to create a mini message loop here to handle windows message. If you didn't, the system would deadlock.

So what one does is when the function exits due to a windows message, you call the Translate and Dispatch functions and return to the MWFMO() function. Its all in an infinte while loop, which in my case is only exited when one of my 'events' occur.

With the loop set up like this, all the buttons and controls in the dialog box still function. One of the buttons is to exit.

So I thought I would catch this attempt by looking for the WM_COMMAND with wParam equal to IDCANCEL message in my mini message loop.

BUT I didn't get the message! Using the debugger I found that after clicking the exit button, the debugger stopped on the case statement for IDCANCEL in my callback; not the mini message loop! Blahh!!

The only way I can think that this can happen is that windows controls skip the message queue and call my callback directly. When I click on the button, my mini message loop sends that message to the control, but the control does not send the WM_COMMAND message to my callback via the queue, but by directly calling my callback. That means I can't trap it.

Why do I want to trap it? Because I want to break out of the MWFMO() function if the user clicks on the exit button (or the system 'X' button in the upper right corner) before actually exiting.

What happens now is that the MWFMO() functions sends a WAIT_FAILED message after the dialog box is closed down. That's not good since I do not know the state of the variables in that dialgbox callback anymore.

Here is the "while" loop in the callback
Code:
     while((index = MsgWaitForMultipleObjects(1, hevent,
					FALSE, INFINITE, QS_ALLINPUT)) != WAIT_OBJECT_0)
	{
		DSCMain->WriteText("M", 1);
		if(index == WAIT_FAILED)
		{
			teststate = 6;		// Indicate error in the wait function
			break;
		}
		while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if(msg.hwnd == hwindow &&
				   (msg.message == WM_DESTROY ||
				   (msg.message == WM_COMMAND && (LOWORD(wParam) == IDOK ||
												  LOWORD(wParam) == IDCANCEL))))
			{
				SetEvent(hevent);
			}
			DSCMain->WriteText("W", 1);
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}
Does anyone know what Windows is doing here?

How can I trap that message and close the MWFMO() loop cleanly before the dialog box actually closes so the loop doesn't exit with a failed message (resulting in who knows what kind of undefined behavior)?

Thanks for any insight into what is going on here!

Brian