CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Apr 2004
    Posts
    56

    Make TimedMessageBox stays in MFC

    I put TimedMessageBox code from MSDN in my code. When the MessageBox disappears, so is the MFC application, while it stays in place (does not quit MFC) if I replace it with ordinary MessageBox. How can I make the MFC application stay in place using this TimedMessageBox ?

    This is the code:

    //////////////////////////////////
    //// MessageBoxTimer From MSDN
    //////////////////////////////////

    void CALLBACK
    MessageBoxTimer(HWND hwnd, UINT uiMsg, UINT idEvent, DWORD dwTime)
    {
    PostQuitMessage(0);
    }

    UINT TimedMessageBox( HWND hwndParent,LPCTSTR ptszMessage,LPCTSTR ptszTitle,
    UINT flags, DWORD dwTimeout)
    {
    UINT idTimer;
    UINT uiResult;
    MSG msg;

    idTimer = SetTimer(NULL, 0, dwTimeout, (TIMERPROC)MessageBoxTimer);

    uiResult = MessageBox(hwndParent, ptszMessage, ptszTitle, flags);

    KillTimer(NULL, idTimer);

    /* See if there is a WM_QUIT message in the queue. */

    if (PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE))
    {
    uiResult = 0;
    }

    return uiResult;
    }

  2. #2
    Join Date
    Jun 2002
    Posts
    395
    PostQuitMessage() posts a WM_QUIT message to the thread, which causes GetMessage() to return with a zero.

    In an MFC app, this causes the event loop in CWinApp::Run() (actually the guts are in CWinThread::Run() ) to exit, which causes your app to exit.

    To fix this, you could create your own dialog class and send a user-defined message when the timer expires, but of course this is what you are trying to avoid.

    The only other solution I see is maybe to override CWinApp::Run() in you app class, copy the guts from CWinThread::Run(), and add in the intelligence to not quit if a timed message box is open when the WM_QUIT is received. I don't know for sure if this will work though, it might have other side effects.

    Code:
    CMyApp::Run()
    {
    	ASSERT_VALID(this);
    	_AFX_THREAD_STATE* pState = AfxGetThreadState();
    
    	// for tracking the idle time state
    	BOOL bIdle = TRUE;
    	LONG lIdleCount = 0;
    
    	// acquire and dispatch messages until a WM_QUIT message is received.
    	for (;;)
    	{
    		// phase1: check to see if we can do idle work
    		while (bIdle &&
    			!::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE))
    		{
    			// call OnIdle while in bIdle state
    			if (!OnIdle(lIdleCount++))
    				bIdle = FALSE; // assume "no idle" state
    		}
    
    		// phase2: pump messages while available
    		do
    		{
    			// pump message, but quit on WM_QUIT
    			if (!PumpMessage()) {
    				if (!isTimedMessageWindowOpen()) // <====== check if timed msg window is open
    					return ExitInstance();
                                                    }
    
    			// reset "no idle" state after pumping "normal" message
    			//if (IsIdleMessage(&m_msgCur))
    			if (IsIdleMessage(&(pState->m_msgCur)))
    			{
    				bIdle = TRUE;
    				lIdleCount = 0;
    			}
    
    		} while (::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE));
    	}
    }

  3. #3
    Join Date
    Apr 2004
    Posts
    56
    Wayside, thanks. Looks like there is no easier way ... At first I thought we can trick the PostMessageQuit not to quit MFC.

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