正在阅读:深入探讨MFC消息循环和消息泵深入探讨MFC消息循环和消息泵

2004-05-31 10:37 出处:CSDN 作者:enoloo 责任编辑:linjixiong



    UpdateWindow();
    bShowIdle = FALSE;
   }

   if (!ContinueModal())
    goto ExitModal;

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

  } while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE));
 } //无限循环

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

 先说说怎么退出这个无限循环,在代码中:


if (!ContinueModal())
 goto ExitModal;
  决定是否退出循环,消息循环函数返回也就是快要结束结束程序了。
BOOL CWnd::ContinueModal()
{
 return m_nFlags & WF_CONTINUEMODAL;
}

  NOTE: CWnd::ContinueModal()函数检查对话框是否继续模式。返回TRUE,表示现在是模式的;返回FALSE,表示对话框已经不是模式(将要结束)。

  如果要结束对话框,在内部最终会调用函数CWnd::EndModalLoop,它取消m_nFlags的模式标志(消息循环中的ContinueModal函数将返回FALSE,消息循环将结束,程序将退出);然后激发消息循环读取消息。也就是说,结束模式对话框是一个标志,改变这个标志就可以了。他的代码是:


//wincore.cpp
void CWnd::EndModalLoop(int nResult)
{
 ASSERT(::IsWindow(m_hWnd));

 // this result will be returned from CWnd::RunModalLoop
 m_nModalResult = nResult;

 // make sure a message goes through to exit the modal loop
 if (m_nFlags & WF_CONTINUEMODAL)
 {
  m_nFlags &= ~WF_CONTINUEMODAL;
  PostMessage(WM_NULL);
 }
}

  NOTE: PostMessage(NULL)是有用的。如果消息队列中没有消息的话,可能消息循环中的ContinueModal()不会马上执行,发送一个空消息是激发消息循环马上工作。

  下面说一下CWnd::RunModalLoop函数中的消息循环究竟干了些什么事情:
1,第一个内循环。首先从消息队列中查询消息,如果对话框空闲,而且消息队列中没有消息,他做三件事情,大家应到都能从字面上明白什么意思。最重要的是发送WM_KICKIDLE消息。为什么呢?第一部分讲到了,非对话框程序用OnIdle来更新用户界面(UI),比如工具栏,状态栏。那么,如果对话框中也有工具栏和状态栏呢,在哪里更新(网上有很多这样的程序)?可以处理WM_KICKIDLE消息:


察看评论详细内容 我要发表评论
作者笔名 简短内容 发表时间
:

键盘也能翻页,试试“← →”键

相关文章

关注我们

最新资讯离线随时看 聊天吐槽赢奖品