MFC 中的消息循环

Posted

技术标签:

【中文标题】MFC 中的消息循环【英文标题】:Message loop in MFC 【发布时间】:2014-09-22 10:51:03 【问题描述】:

我学过一点Win32 API,但现在想学MFC。在我的电子书中,他们说CWinApp 类管理应用程序的主线程,但我在此类中找不到类似GetMessageDispatchMessage 的函数。那么它如何开始消息循环呢?

请有人为我解释一下。抱歉,我是 MFC 的新手,我的英语很差。 在哪里可以找到一些关于 Visual Studio 中 MFC 的电子书/教程?

【问题讨论】:

【参考方案1】:

这一切都在CWinApp:Run 部分完成。

InitInstance 返回 true 后,CWinApp:Run 启动,消息循环开始发挥作用。这个消息循环很棘手,因为它还会在应用程序无事可做时处理OnIdle 调用。

只需查看源代码。

【讨论】:

【参考方案2】:

MFC 使用消息映射简化了消息处理,程序员大多不需要关心消息循环如何运行、消息如何传递以及映射消息如何映射到用户定义的函数。我建议您摆弄CWnd 派生类(如框架、对话框),并查看映射消息如何调用您的函数。

WM_MOUSEMOVE 正在调用您的 OnMouseMove,前提是您输入了一个条目 ON_WM_MOUSEMOVE - 这很有趣,您应该会发现它是如何工作的。玩弄CWinApp-派生类不是个好主意。

【讨论】:

【参考方案3】:

MFC 有点像 Win32 上的包裹层。消息循环包含在名为 Run 的 CWinThread 成员中。应用程序类是从 CWinApp 派生的,而 CWinApp 又是从 CWinThread 派生的。此方法通常不会被覆盖。如果要读取消息循环代码,则应覆盖此方法,并且在调试时可以看到代码。它也处理空闲消息

int CWinThread::Run()

    ....

    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())
                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));
    

【讨论】:

以上是关于MFC 中的消息循环的主要内容,如果未能解决你的问题,请参考以下文章

工作线程没有消息循环(MFC、windows)。我们可以让它接收消息吗?

MFC非模态添加进程控件方法一(线程方法)

MFC框架程序及消息映射

QT事件循环

MFC_消息处理

MFC 在 for 循环中绘图