kpcnatraj


Hello,
We have created a VC++ application that has 2 menu options.
- submenu 1 opens the VBA IDE
- submenu 2 opens a Modal Dialog to execute a functionality (say FUNC1)

Whenever we directly select submenu 2 the application executes properly.

But the application hangs whenever we select submenu 1 (opening the VBA IDE) and then select submenu 2 (having the VBA IDE still open)

On debugging we find that in the problematic case (in which the application hangs), the control fails to come out of an infinite loop inside the mfc source code wincore.cpp

The details of the code flow are given below for this problematic case:

The modal dialog is created using the function INT_PTR CDialog::DoModal() (present in mfc source code dlgcore.cpp) which inturn calls int CWnd::RunModalLoop(DWORD dwFlags) present in the mfc source code wincore.cpp (elaborated at the end of this message). The control gets struck in this function (which has an infinite loop inside it) thereby causing the application to hang.

We are unable to understand the reason for this code behaviour and would like to clarify whether there is any bug in the MFC source due to which this occurs.

Has anyone faced such similar problems while creating Modal Dialogs . If there is any work around to tackle this problem we would be glad to know.

Thanks in advance,
Ravi.

---------------------------------------------------------------
(source code details of function RunModalLoop present in wincore.cpp,
Courtesy : Microsoft corp.)


int CWnd::RunModalLoop(DWORD dwFlags)
{
ASSERT(::IsWindow(m_hWnd)); // window must be created
ASSERT(!(m_nFlags & WF_MODALLOOP)); // window must not already be in modal state

// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
BOOL bShowIdle = (dwFlags & MLF_SHOWONIDLE) && !(GetStyle() & WS_VISIBLE);
HWND hWndParent = ::GetParent(m_hWnd);
m_nFlags |= (WF_MODALLOOP|WF_CONTINUEMODAL);
MSG *pMsg = AfxGetCurrentMessage();

// acquire and dispatch messages until the modal state is done
for (;;) <---- (the application fails to exit this infinite loop)
{
ASSERT(ContinueModal());

// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
{
ASSERT(ContinueModal());

// show the dialog when the message queue goes idle
if (bShowIdle)
{
ShowWindow(SW_SHOWNORMAL);
UpdateWindow();
bShowIdle = FALSE;
}

// call OnIdle while in bIdle state
if (!(dwFlags & MLF_NOIDLEMSG) && hWndParent != NULL && lIdleCount == 0)
{
// send WM_ENTERIDLE to the parent
::SendMessage(hWndParent, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)m_hWnd);
}
if ((dwFlags & MLF_NOKICKIDLE) ||
!SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++))
{
// stop idle processing next time
bIdle = FALSE;
}
}

// phase2: pump messages while available
do
{
ASSERT(ContinueModal());

// pump message, but quit on WM_QUIT
if (!AfxPumpMessage())
{
AfxPostQuitMessage(0);
return -1;
}

// show the window when certain special messages rec'd
if (bShowIdle &&
(pMsg->message == 0x118 || pMsg->message == WM_SYSKEYDOWN))
{
ShowWindow(SW_SHOWNORMAL);
UpdateWindow();
bShowIdle = FALSE;
}

if (!ContinueModal())
goto ExitModal;

// reset "no idle" state after pumping "normal" message
if (AfxIsIdleMessage(pMsg))
{
bIdle = TRUE;
lIdleCount = 0;
}

} while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE));
}

ExitModal:
m_nFlags &= ~(WF_MODALLOOP|WF_CONTINUEMODAL);
return m_nModalResult;
}
--------------------------------------------------------------



Re: Problem with CWnd::RunModalLoop(DWORD dwFlags) in wincore.cpp

Derek Smyth


Hi there,

Just looking at the code and it looks like the for loop is exited by the goto statement here.

if (!ContinueModal())
goto ExitModal;

Not an ideal programming approach but it's there never the less, whats happening in the ContinueModal() method







Re: Problem with CWnd::RunModalLoop(DWORD dwFlags) in wincore.cpp

kpcnatraj

The code for ContinueModal( ) is present in wincore.cpp present in the install directory of VC++ .NET edition viz. <VC Install dir>\vc\atlmfc\src\mfc> and is reproduced here.:


BOOL CWnd::ContinueModal()
{
return m_nFlags & WF_CONTINUEMODAL;
}


But I am unsure when the condition for exiting the loop is satisfied since it is determined by m_nFlags (mfc variable). I suppose mfc programmers would be able to throw more light on this.





Re: Problem with CWnd::RunModalLoop(DWORD dwFlags) in wincore.cpp

Derek Smyth

Hi again,

Is m_nFlags a global variable, could be you need to set its value in order to break the infinite look. I'm not that versed in MFC.






Re: Problem with CWnd::RunModalLoop(DWORD dwFlags) in wincore.cpp

DFlatGuy

I'm having the same problem in my project. Could anybody identify this problem and give some solution (or even workarounds)





Re: Problem with CWnd::RunModalLoop(DWORD dwFlags) in wincore.cpp

PaloMisik

I encounter with the same problem.

In my case solution was in change SendMessage to PostMessage.