MFC消息的路由

首先消息分三类,分别是窗口消息,命令消息,通告消息。其中窗口消息的“流动”是很规则的,只是纵向流动,只能从派生类流到基类,最终“流到”基类CCmdTarget...绝无“旁逸斜出”的可能。命令消息和通告消息则不同。下面以命令消息来讲述命令消息的“路由”。


当dispatch一个消息时,消息首先由AfxWndProc分发,在经由AfxCallWndProc保存消息,最终调用对应的WindowProc.在WindowProc中判断是否是命令消息或者通告消息,是的话,分别交由OnCommand和OnNotify处理。不是的话最后交给窗口过程处理。下面讨论命令消息的路由。

 不妨假设调用了CFrameWnd::OnCmdMsg,

BOOL CFrameWnd::OnCmdMsg(UINT nID, int nCode)

{

... ...

 CView* pView = GetActiveView();

 if (pView->OnCmdMsg(nID, nCode))//(1)

return TRUE;

... ...

 if (CWnd::OnCmdMsg(nID, nCode))//(4)

return TRUE;

... ...

 CWinApp* pApp = AfxGetApp();

 if (pApp->OnCmdMsg(nID, nCode))//(5)

return TRUE;

 return FALSE;

}

由于在CFrameWnd中有CView* m_pViewActive; GetActiveView函数返回的就是与这个框架窗口关联的视类对象。流程转到(1),

(1):pView->OnCmdMsg,于是

BOOL CView::OnCmdMsg(UINT nID, int nCode)

{

... ...

 if (CWnd::OnCmdMsg(nID, nCode)) //(2)

return TRUE;

 BOOL bHandled = FALSE;

 bHandled = m_pDocument->OnCmdMsg(nID, nCode);//(3)

return bHandled;

}

消息最终由视类中的OnCmdMsg处理,而视类的OnCmdMsg并没有改写,所以最终调用CCmdTarge::OnCmdMsg(),这个函数最终会调用_AfxDispatchCmdMsg[文章的最好附注该函数的定义]对命令消息进行分发处理[其他的分析和这个类似。],如果没处理,再交由(3),由与这个视类关联的文档类处理。其中CDocument* m_pDocument;是CView的成员变量。如果(2),(3)都没处理,则流程返回(4),由框架类处理,如果框架类也没处理,则转到(5),由应用程序类处理。这就是命令消息的处理流程。


AFX_STATIC BOOL AFXAPI _AfxDispatchCmdMsg(CCmdTarget* pTarget, UINT nID, int nCode,

AFX_PMSG pfn, void* pExtra, UINT nSig, AFX_CMDHANDLERINFO* pHandlerInfo)

// return TRUE to stop routing

{

ASSERT_VALID(pTarget);

UNUSED(nCode);// unused in release builds

union MessageMapFunctions mmf;

mmf.pfn = pfn;

BOOL bResult = TRUE; // default is ok

if (pHandlerInfo != NULL)

{

// just fill in the information, don't do it

pHandlerInfo->pTarget = pTarget;

pHandlerInfo->pmf = mmf.pfn;

return TRUE;

}

switch (nSig)

{

case AfxSig_vv:

// normal command or control notification

ASSERT(CN_COMMAND == 0);// CN_COMMAND same as BN_CLICKED

ASSERT(pExtra == NULL);

(pTarget->*mmf.pfn_COMMAND)();

break;

case AfxSig_bv:

// normal command or control notification

ASSERT(CN_COMMAND == 0);// CN_COMMAND same as BN_CLICKED

ASSERT(pExtra == NULL);

bResult = (pTarget->*mmf.pfn_bCOMMAND)();

break;

case AfxSig_vw:

// normal command or control notification in a range

ASSERT(CN_COMMAND == 0);// CN_COMMAND same as BN_CLICKED

ASSERT(pExtra == NULL);

(pTarget->*mmf.pfn_COMMAND_RANGE)(nID);

break;

case AfxSig_bw:

// extended command (passed ID, returns bContinue)

ASSERT(pExtra == NULL);

bResult = (pTarget->*mmf.pfn_COMMAND_EX)(nID);

break;

case AfxSig_vNMHDRpl:

{

AFX_NOTIFY* pNotify = (AFX_NOTIFY*)pExtra;

ASSERT(pNotify != NULL);

ASSERT(pNotify->pResult != NULL);

ASSERT(pNotify->pNMHDR != NULL);

(pTarget->*mmf.pfn_NOTIFY)(pNotify->pNMHDR, pNotify->pResult);

}

break;

case AfxSig_bNMHDRpl:

{

AFX_NOTIFY* pNotify = (AFX_NOTIFY*)pExtra;

ASSERT(pNotify != NULL);

ASSERT(pNotify->pResult != NULL);

ASSERT(pNotify->pNMHDR != NULL);

bResult = (pTarget->*mmf.pfn_bNOTIFY)(pNotify->pNMHDR, pNotify->pResult);

}

break;

case AfxSig_vwNMHDRpl:

{

AFX_NOTIFY* pNotify = (AFX_NOTIFY*)pExtra;

ASSERT(pNotify != NULL);

ASSERT(pNotify->pResult != NULL);

ASSERT(pNotify->pNMHDR != NULL);

(pTarget->*mmf.pfn_NOTIFY_RANGE)(nID, pNotify->pNMHDR,

pNotify->pResult);

}

break;

case AfxSig_bwNMHDRpl:

{

AFX_NOTIFY* pNotify = (AFX_NOTIFY*)pExtra;

ASSERT(pNotify != NULL);

ASSERT(pNotify->pResult != NULL);

ASSERT(pNotify->pNMHDR != NULL);

bResult = (pTarget->*mmf.pfn_NOTIFY_EX)(nID, pNotify->pNMHDR,

pNotify->pResult);

}

break;

case AfxSig_cmdui:

{

// ON_UPDATE_COMMAND_UI or ON_UPDATE_COMMAND_UI_REFLECT case

ASSERT(CN_UPDATE_COMMAND_UI == (UINT)-1);

ASSERT(nCode == CN_UPDATE_COMMAND_UI || nCode == 0xFFFF);

ASSERT(pExtra != NULL);

CCmdUI* pCmdUI = (CCmdUI*)pExtra;

ASSERT(!pCmdUI->m_bContinueRouting);// idle - not set

(pTarget->*mmf.pfn_UPDATE_COMMAND_UI)(pCmdUI);

bResult = !pCmdUI->m_bContinueRouting;

pCmdUI->m_bContinueRouting = FALSE;// go back to idle

}

break;

case AfxSig_cmduiw:

{

// ON_UPDATE_COMMAND_UI case

ASSERT(nCode == CN_UPDATE_COMMAND_UI);

ASSERT(pExtra != NULL);

CCmdUI* pCmdUI = (CCmdUI*)pExtra;

ASSERT(pCmdUI->m_nID == nID);// sanity assert

ASSERT(!pCmdUI->m_bContinueRouting);// idle - not set

(pTarget->*mmf.pfn_UPDATE_COMMAND_UI_RANGE)(pCmdUI, nID);

bResult = !pCmdUI->m_bContinueRouting;

pCmdUI->m_bContinueRouting = FALSE;// go back to idle

}

break;

// general extensibility hooks

case AfxSig_vpv:

(pTarget->*mmf.pfn_OTHER)(pExtra);

break;

case AfxSig_bpv:

bResult = (pTarget->*mmf.pfn_OTHER_EX)(pExtra);

break;

default:// illegal

ASSERT(FALSE);

return 0;

}

return bResult;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容