MFC源码分析实战(五)——层层封装下的消息循环

本文深入剖析MFC框架下的消息循环机制,从CWnd::CreateEx后的GetMessage/PeekMessage开始,讲解CWinApp::Run、CWinThread::Run如何构成消息循环。重点讨论CWnd::OnWndMsg及其处理ON_COMMAND消息的过程,揭示CFrameWnd和CView类在OnCommand函数中的不同处理策略,以及OnCmdMsg在消息映射中的查找流程。
摘要由CSDN通过智能技术生成

消息循环

至此,我们还有最后一站——消息循环
为此,当程序调试运行到CWnd::CreateEx尾部时,对GetMessage/PeekMessage下条件断点,以窗口句柄为条件:
很快就断下来了:
这里写图片描述
在AfxWinMain中,InitInstance完成后,就开始执行Run函数:
这里写图片描述
Run又是一个虚函数,CWinApp类中override了它,因此进入CWinApp::Run:
这里写图片描述
在其中又调用了CWinThread::Run,其中调用了PeekMessage以PM_NONREMOVE的方式偷看消息队列,并在空闲时执行OnIdle虚函数;如果不空闲,则进入 CWinThread::PumpMessage()函数,该函数又调用了AfxInternalPumpMessage函数:

BOOL AFXAPI AfxInternalPumpMessage()
{
    _AFX_THREAD_STATE *pState = AfxGetThreadState();

    if (!::GetMessage(&(pState->m_msgCur), NULL, NULL, NULL))
    {
        return FALSE;
    }
  // process this message

    if (pState->m_msgCur.message != WM_KICKIDLE && !AfxPreTranslateMessage(&(pState->m_msgCur)))
    {
        ::TranslateMessage(&(pState->m_msgCur));
        ::DispatchMessage(&(pState->m_msgCur));
    }
  return TRUE;
}

基本上是一个标准的消息循环了。不过注意在GetMessage后有一个AfxPreTranslateMessage,并且可以根据其返回值决定是否翻译并分发消息(如果不分发消息的话,根本就没回到user32领空,因此AfxWndProc根本就收不到该消息)

BOOL __cdecl AfxPreTranslateMessage(MSG* pMsg)
{
  CWinThread *pThread = AfxGetThread();
  if( pThread )
    return pThread->PreTranslateMessage( pMsg );
  else
    return AfxInternalPreTranslateMessage( pMsg );
}

BOOL CWinThread::PreTranslateMessage(MSG* pMsg)
{
    ASSERT_VALID(this);
    return AfxInternalPreTranslateMessage(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值