MFC编程实例:MFC消息处理流程概述

本文将为大家讲解关于MFC编程实例中MFC消息处理流程,通过MFC编程实例的内容让你对相关知识点有进一步的认识和理解! 摘要:Win32下的消息流程清晰明了,但在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.BOOLAFXAPIAfxInternalPumpMessage()

2.{

3.MSGmsg;

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

5.if(!AfxPreTranslateMessage(&msg))

6.{

7.::TranslateMessage(&msg);

8.::DispatchMessage(&msg);

9.}

10.returnTRUE;

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.LRESULTCALLBACKAfxWndProc(HWNDhWnd,UINTnMsg,WPARAMwParam,LPARAMlParam)

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.returnpWnd->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.LRESULTCWnd::WindowProc(UINTmessage,WPARAMwParam,LPARAMlParam)

2.{

3.//OnWndMsgdoesmostofthework,exceptforDefWindowProccall

4.LRESULTlResult=0;

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

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

7.returnlResult;

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.BOOLCWnd::OnWndMsg(UINTmessage,WPARAMwParam,LPARAMlParam,LRESULT*pResult)

2.{

3.LRESULTlResult=0;

4.unionMessageMapFunctionsmmf;

5.mmf.pfn=0;

6.CInternalGlobalLockwinMsgLock;

7.//specialcaseforcommands

8.if(message==WM_COMMAND)

9.{

10.if(OnCommand(wParam,lParam))

11.{

12.lResult=1;

13.gotoLReturnTrue;

14.}

15.returnFALSE;

16.}

17.

18.//specialcasefornotifies

19.if(message==WM_NOTIFY)

20.{

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

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

23.gotoLReturnTrue;

24.returnFALSE;

25.}

26.

27.......

28.

29.returnTRUE;

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频道都能找到!

以上的相关游戏回复就是MFC编程实例:MFC消息处理流程概述这方面的内容介绍,字数约5134字,也希望大家能够和我在一起进行分享。屹东网往后会继续推荐MFC编程实例:MFC消息处理流程概述相关内容。