MFC编程实例:MFC消息处理流程概述
小职 2017-09-05 来源 :网络 阅读 883 评论 0

摘要:本文将为大家讲解关于MFC编程实例中MFC消息处理流程,通过MFC编程实例的内容让你对相关知识点有进一步的认识和理解!

    本文将为大家讲解关于MFC编程实例中MFC消息处理流程,通过MFC编程实例的内容让你对相关知识点有进一步的认识和理解!


    摘要: Win32下的消息流程清晰明了,但在MFC下,由于封装的缘故,隐藏的有点深,对一般的开发人员而言,就不甚明了喽。本文试图粗略展示出MFC下消息处理的基本流程。   一、先看一下Win32下的消息处理流程   每一个线程都对应有一个消息队列,利用API函数GetMessage从消息队列中获取消息,然后利用TranslateMessage翻译消息(主要是一些键盘消息),再利用DispatchMessage将消息分发给对应的窗口过程函数处理。


    Win32下的消息流程清晰明了,但在MFC下,由于封装的缘故,隐藏的有点深,对一般的开发人员而言,就不甚明了喽。本文试图粗略展示出MFC下消息处理的基本流程。


一、先看一下Win32下的消息处理流程

    每一个线程都对应有一个消息队列,利用API函数GetMessage从消息队列中获取消息,然后利用TranslateMessage翻译消息(主要是一些键盘消息),再利用DispatchMessage将消息分发给对应的窗口过程函数处理。


    一般我们在WinMain函数中利用如下代码来处理消息:

 

[cpp] view plaincopyprint?

1. while (GetMessage(&msg, NULL, 0, 0))  

2. {  

3.     TranslateMessage(&msg);  

4.     DispatchMessage(&msg);  

5. }  

while (GetMessage(&msg, NULL, 0, 0))

{

    TranslateMessage(&msg);

    DispatchMessage(&msg);

}

    很显然,整个消息循环很清楚。

 

二、MFC下的消息处理流程

 

1、MFC下的消息处理流程由thrdcore.cpp中的AfxInternalPumpMessage开始:

 

[cpp] view plaincopyprint?

1. BOOL AFXAPI AfxInternalPumpMessage()  

2. {  

3.     MSG msg;  

4.     ::GetMessage(&msg, NULL, NULL, NULL);  

5.     if (!AfxPreTranslateMessage(&msg))  

6.     {  

7.         ::TranslateMessage(&msg);  

8.  ::DispatchMessage(&msg);  

9.     }  

10.     return TRUE;  

11. }  

    BOOL AFXAPI AfxInternalPumpMessage()

    {

        MSG msg;

        ::GetMessage(&msg, NULL, NULL, NULL);

        if (!AfxPreTranslateMessage(&msg))

        {

            ::TranslateMessage(&msg);

    ::DispatchMessage(&msg);

        }

        return TRUE;

    }

 

注:以上代码为示意代码,具体请参照MFC的源码。

    很显然,其消息处理流程也类似<一>中Win32下的消息处理,只不过在调用TranslateMessage、DispatchMessage处理消息前增加了类似过滤的函数AfxPreTranslateMessage。该函数会调用CWnd类的PreTranslateMessage函数,函数返回True则消息将不会被处理。我们经常会通过重载CWnd类的PreTranslateMessage来改变MFC的消息控制流程。

2、窗口过程函数

    通过调用DispatchMessage将消息分发给了具体的窗口过程函数处理。MFC下的所有窗口都拥有公用的窗口过程函数AfxWndProc。该函数的示意代码如下:

 

[cpp] view plaincopyprint?

1. LRESULT CALLBACK AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)  

2. {  

3.         CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);  //从HWND获取对应的CWnd*   

4.         if (pWnd == NULL || pWnd->m_hWnd != hWnd)  

5.                 return ::DefWindowProc(hWnd, nMsg, wParam, lParam);  

6.         else      

7.                 return pWnd->WindowProc(nMsg, wParam, lParam);  

8. }  

LRESULT CALLBACK AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)

{

        CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);  //从HWND获取对应的CWnd*

        if (pWnd == NULL || pWnd->m_hWnd != hWnd)

                return ::DefWindowProc(hWnd, nMsg, wParam, lParam);

        else

                return pWnd->WindowProc(nMsg, wParam, lParam);

}

    很显然,调用了CWnd类的虚函数virtual CWnd::WindowProc处理。

[cpp] view plaincopyprint?

1. LRESULT CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)  

2. {  

3.     // OnWndMsg does most of the work, except for DefWindowProc call   

4.     LRESULT lResult = 0;  

5.     if (!OnWndMsg(message, wParam, lParam, &lResult))  

6.         lResult = DefWindowProc(message, wParam, lParam);  

7.     return lResult;  

8. }  

LRESULT CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)

{

// OnWndMsg does most of the work, except for DefWindowProc call

LRESULT lResult = 0;

if (!OnWndMsg(message, wParam, lParam, &lResult))

lResult = DefWindowProc(message, wParam, lParam);

return lResult;

}

    WindowProc函数又调用了CWnd类的虚函数virtual CWnd::OnWndMsg处理。

 

 

[cpp] view plaincopyprint?

1. BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)  

2. {  

3.     LRESULT lResult = 0;  

4.     union MessageMapFunctions mmf;  

5.     mmf.pfn = 0;  

6.     CInternalGlobalLock winMsgLock;  

7.     // special case for commands   

8.     if (message == WM_COMMAND)  

9.     {  

10.         if (OnCommand(wParam, lParam))  

11.         {  

12.             lResult = 1;  

13.             goto LReturnTrue;  

14.         }  

15.         return FALSE;  

16.     }  

17.   

18.     // special case for notifies   

19.     if (message == WM_NOTIFY)  

20.     {  

21.         NMHDR* pNMHDR = (NMHDR*)lParam;  

22.         if (pNMHDR->hwndFrom != NULL && OnNotify(wParam, lParam, &lResult))  

23.             goto LReturnTrue;  

24.         return FALSE;  

25.     }  

26.       

27.     ......  

28.   

29.     return TRUE;  

30. }  

BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)

{

LRESULT lResult = 0;

union MessageMapFunctions mmf;

mmf.pfn = 0;

CInternalGlobalLock winMsgLock;

// special case for commands

if (message == WM_COMMAND)

{

if (OnCommand(wParam, lParam))

{

lResult = 1;

goto LReturnTrue;

}

return FALSE;

}

 

// special case for notifies

if (message == WM_NOTIFY)

{

NMHDR* pNMHDR = (NMHDR*)lParam;

if (pNMHDR->hwndFrom != NULL && OnNotify(wParam, lParam, &lResult))

goto LReturnTrue;

return FALSE;

}


......

 

return TRUE;

}

    在OnWndMsg函数中会根据具体的消息类型,在MFC的消息映射表中找到对应的函数处理。

以上就是MFC处理消息的大致流程。


    希望这篇MFC编程文章可以帮助到你。总之,同学们,你想要的职坐标MFC频道都能找到!

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程