none
求教:解说CCmdTarget这个类中的“分发消息映射”,“分发”二字该怎么理解 RRS feed

答案

  • 你可以跟踪一下代码。
    每个窗口都有消息映射表内容,当CCmdTarget使这个消息映射表的最上面的那个表,CCmdTarget通过系统消息队列获得消息后,会遍历映射表,选择执行映射的函数指针。
    BOOL CCmdTarget::OnCmdMsg(UINT nID, int nCode, void* pExtra,
    AFX_CMDHANDLERINFO* pHandlerInfo)
    {
    ...
    // look through message map to see if it applies to us
    for (pMessageMap = GetMessageMap(); pMessageMap != NULL;
    pMessageMap = pMessageMap->pBaseMap)
    {
    lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries, nMsg, nCode, nID);
    if (lpEntry != NULL)
    {
    // found it
    return DispatchCmdMsg(this, nID, nCode,
    lpEntry->pfn, pExtra, lpEntry->nSig, pHandlerInfo);
    }
    }
    return FALSE; // not handled
    }
    static BOOL DispatchCmdMsg(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
    ...
    switch (nSig)
    {
    case AfxSig_vv:
    // normal command or control notification
    (pTarget->*mmf.pfn_COMMAND)();
    break;
    case AfxSig_bv:
    // normal command or control notification
    bResult = (pTarget->*mmf.pfn_bCOMMAND)();
    break;
    case AfxSig_vw:
    // normal command or control notification in a range
    (pTarget->*mmf.pfn_COMMAND_RANGE)(nID);
    break;
    case AfxSig_bw:
    // extended command (passed ID, returns bContinue)
    bResult = (pTarget->*mmf.pfn_COMMAND_EX)(nID);
    break;

    default: // illegal
    ASSERT(FALSE);

    return 0;
    }
    return bResult;
    }


    麻烦把正确答案设为解答。
    • 已标记为答案 abloaa 2009年10月9日 5:53
    2009年9月27日 14:48
    版主