|
-
May 4th, 2004, 10:56 AM
#1
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;
}
-
May 4th, 2004, 11:42 AM
#2
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));
}
}
-
May 4th, 2004, 09:02 PM
#3
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|