1
votes

I have a CFormView, and a child CListCtrl control. I can handle accelerator events, like Ctrl+C, Ctrl+V ... in CFormView without problem, by defining below message handler:

    ON_COMMAND(ID_EDIT_COPY, &CMyFormView::OnEditCopy) 

Now I want my CListCtrl handle these commands differently. I want to implement OnEditCopy in CListCtrl class, rather than implement logic in the view class. How can I pass the accelerator events from CView to child control, when CListCtrl is on focus? I tried like:

    ON_CONTROL_REFLECT(ID_EDIT_COPY, &CMyListCtrl::OnEditCopy) 

But it doesn't work.

2

2 Answers

5
votes

Alternative you can override PreTranslateMessage() on CMyListCtrl and call TranslateAccelerator()

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

It requires acccess to the global accelerator-resource on the mainframe, or that you load the accelerator again. Then your CMyListCtrl will receive the WM_COMMAND messages specified in the accelerator table.

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

4
votes

Use same ON_COMMAND macro in CMyListCtrl.

  ON_COMMAND(ID_EDIT_COPY, &CMyListCtrl::OnEditCopy)  

All you have to do is overriding OnCmdMsg method.

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 is the CMyListCtrl instance pointer.)

This make all WM_COMMAND message first handled in m_myListCtrl if its the focus window.