摘要:本文将为大家讲解关于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频道都能找到!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号