问题
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.
回答1:
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.
回答2:
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
来源:https://stackoverflow.com/questions/4570069/how-to-make-child-control-handle-accelerator-command-of-parent-cview