【问题标题】:How to make child control handle accelerator command of parent CView如何使子控件处理父CView的加速器命令
【发布时间】:2011-06-01 23:42:40
【问题描述】:

我有一个 CFormView 和一个子 CListCtrl 控件。我能应付 加速器事件,如 CFormView 中的 Ctrl+C、Ctrl+V ... 问题,通过定义下面的消息处理程序:

    ON_COMMAND(ID_EDIT_COPY, &CMyFormView::OnEditCopy) 

现在我希望我的 CListCtrl 以不同的方式处理这些命令。我想要 在 CListCtrl 类中实现 OnEditCopy,而不是实现逻辑 在视图类中。如何将加速器事件从 CView 传递到 子控件,当 CListCtrl 处于焦点时?我试过了:

    ON_CONTROL_REFLECT(ID_EDIT_COPY, &CMyListCtrl::OnEditCopy) 

但它不起作用。

【问题讨论】:

    标签: c++ visual-c++ mfc


    【解决方案1】:

    您可以覆盖 CMyListCtrl 上的 PreTranslateMessage() 并调用 TranslateAccelerator()

    BOOL CMyListCtrl::PreTranslateMessage(MSG* pMsg)
    {
           if (m_hAccelTable)
           {
              if (::TranslateAccelerator(m_hWnd, m_hAccelTable, pMsg))
                 return(TRUE);
           }
           return CListCtrl::PreTranslateMessage(pMsg);
    }
    

    它需要访问大型机上的全局加速器资源,或者您需要重新加载加速器。然后您的 CMyListCtrl 将收到在快捷键表中指定的 WM_COMMAND 消息。

    http://support.microsoft.com/kb/222829

    【讨论】:

    • 可惜支持链接不再有效。
    【解决方案2】:

    在 CMyListCtrl 中使用相同的 ON_COMMAND 宏。

      ON_COMMAND(ID_EDIT_COPY, &CMyListCtrl::OnEditCopy)  
    

    您所要做的就是覆盖 OnCmdMsg 方法。

    BOOL CMyFormView::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
    {
        if (GetFocus() == m_myListCtrl
            && m_myListCtrl->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
            return TRUE;
        return CMyFormView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
    }
    

    (m_myListCtrl 是 CMyListCtrl 实例指针。)

    如果它是焦点窗口,这会使所有 WM_COMMAND 消息首先在 m_myListCtrl 中处理。

    【讨论】:

    • 这正是我所期望的。谢谢!
    • 您想通过描述 ::OnCommand() 方法在这种情况下扮演什么角色(如果有)来扩展答案吗?为什么ID_EDIT_COPY这么特殊,需要在父类中修改消息分发机制?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    相关资源
    最近更新 更多