CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Dec 2002
    Location
    Candia, NH
    Posts
    374

    MsgWaitForMultipleObjects()

    I give up!

    I have tried everything to try and handle this function inside a modeless dialog box callback function (maybe that's not possible)?

    Here is the code. Its in a radio button case statement.

    Code:
    				if(wParam == RADIO_TIMER_TO_SIGNAL)
    				{
    					teststate = 5;
    					transceiver->SetDetectOnly(2, SIGNAL);		// Set to look for a signal
    					hevent[0] = transceiver->GetEventHandle(2);
    					while((MsgWaitForMultipleObjects(1, hevent,
    									FALSE, INFINTE, QS_ALLINPUT)) != WAIT_OBJECT_0)
    					{
    						DSCMain->WriteText("M", 1);      // diagnostic printout of "M" 
    						while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    						{
    							DSCMain->WriteText("W", 1);     // diagnostic printout of "W"
     							TranslateMessage(&msg);
    							DispatchMessage(&msg);
    						}
    					}
    					DSCMain->WriteText("F", 1);     // diagnostic printout of "F"
    					transceiver->SetDetectOnly(2, NORMAL);
    					RedrawRadioButton(&radio_testsignal, RADIO_TESTOFF);
    					EnableWindow(GetDlgItem(hwindow, RADIO_TIMER_TO_SIGNAL), FALSE);
    					teststate = 0;
    				}
    What the code does is wait for a radio signal to appear. Now if that happens, everything works fine; the wait function is signalled and the while loop ends and I get the "F" printed to a background window.

    However, if I try to break the loop by user input, there is no way I can stop it. I have tried to identify a message addressed to the callback like WM_DESTROY, or WM_COMMAND with wParam IDCANCEL and have even been able to stop on these conditions in the debugger. Then I try to break the while loop. A 'break' command fails (the dialog box goes away but the while loop with the wait function remains and continues to print out the "M" diagnostic. I have tried to SetEvent(hevent[0]) and that fails. I have tried to change the timeout on the fly from infinite to 1 and that fails. I have tried calling the dialog callback function directly and that fails. The dialog box goes away if I call the Dispatch function but the "M's" continue to print.

    The only way I have successfully been able to terminate that while loop with the MsgWaitFMO() function is by signalling the event from another thread.

    How can I have the user break this loop if no signal decides to come?

    Thanks,

    Brian

  2. #2
    Join Date
    Apr 2005
    Location
    Norway
    Posts
    3,934

    Re: MsgWaitForMultipleObjects()

    Is this what you want?
    Code:
    while((MsgWaitForMultipleObjects(1, hevent, FALSE, INFINTE, QS_ALLINPUT)) != WAIT_OBJECT_0)
    {
        DSCMain->WriteText("M", 1);      // diagnostic printout of "M" 
        while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == YOUR_MESSAGE)
                goto after_loop;
            DSCMain->WriteText("W", 1);     // diagnostic printout of "W"
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    after_loop:
    - petter

  3. #3
    Join Date
    Dec 2002
    Location
    Candia, NH
    Posts
    374

    Re: MsgWaitForMultipleObjects()

    Yes it is, or at least something like that. I tried that approach using many message combinations, and via the debugger got to stop on a message. But the "break" did not succeed in exiting the while loop.

    Somehow one of the multitude of messages must have restarted it.

    I think I will give up this approach and try a modal dialog box or even a thread isolated all by itself as it waits. Will need to have a user option to cancel the wait.

    Something dumb is happening that keeps restarting the while loop. I have exited sometimes by including the 'WAIT_FAILED' condition.

    Its clear there is too much stuff going on I don't understand. My own diagniostics are probably creating a mass of messages.

    The thread approach with a WFMO() function instead of the MWFMO() function appears much safer even though it is a lot more work.

    Brian

  4. #4
    Join Date
    Dec 2002
    Location
    Candia, NH
    Posts
    374

    Question Re: MsgWaitForMultipleObjects()

    I noted something else that surpised me. In the debugger I put a break in the message loop if the message was a WM_DESTROY or a WM_COMMAND and wParam IDCANCEL. THen I put another break in the WM_DESTROY message in the callback.

    TO my surprise, when I clicked on the cancel button, the debugger stopped on the WM_DESTROY message in the callback, and not the PeekMessage() loop handler after the MsgWait...() function.

    How did it do that? It must have gone through the main message loop instead of the wait function, but that's NOT how I understood things to work!

    I am confused. I thought the PeekMessage() loop would see it first before the DispatchMessage() function.

    Brian

  5. #5
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: MsgWaitForMultipleObjects()

    Quote Originally Posted by Gyannea
    .... I thought the PeekMessage() loop would see it first before the DispatchMessage() function.
    Brian
    That's the way I understand MsgWaitForMultipleObjects too.

    Maybe the fact that it's in a dialog is the difference. However, your dialog is modeless, so I don't see why it would.

    Note that the documentation for MsgWFMO states that you must clear out the message queue before it's called. See the example at http://msdn.microsoft.com/library/en...ssage_loop.asp . Could that be an issue for you?

    Mike

  6. #6
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: MsgWaitForMultipleObjects()

    Quote Originally Posted by Gyannea
    Yes it is, or at least something like that. I tried that approach using many message combinations, and via the debugger got to stop on a message. But the "break" did not succeed in exiting the while loop.
    Code:
     
    while((MsgWaitForMultipleObjects(1, hevent, FALSE, INFINTE, QS_ALLINPUT)) != WAIT_OBJECT_0)
    {
    	DSCMain->WriteText("M", 1);	  // diagnostic printout of "M"
    	MSG message; 
    	while(PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
    	{
    		// etc 
    	}
    }
    Looks like you are reusing the original msg structure. When I've done this kind of thing in the past, I've always declared a separate MSG variable.

    Arjay

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured