Working on a recent project, I wanted to give my CView-derived view class Tab navigation (like CFormView has). By default, if you add CEdit and other controls to your CView-derived view, pressing Tab will do nothing. Also, adding CStatic with & accelerators are ignored.
Doing some Googling, I found the following solution. Add the following function to your CView-derived class:
BOOL CMyView::PreTranslateMessage(MSG* pMsg)
{
if(IsDialogMessage(pMsg))
return TRUE;
else
return CWnd::PreTranslateMessage(pMsg);
}
At first, it was working great. However, I noticed that my overall application accelerators were not working.
Looking deeper into CFormView, I found the solution. The above code is not enough. The following is a more complete solution.
BOOL CMyView::PreTranslateMessage(MSG* pMsg)
{
ASSERT(pMsg != NULL);
ASSERT_VALID(this);
ASSERT(m_hWnd != NULL);
// allow tooltip messages to be filtered
if (CView::PreTranslateMessage(pMsg))
return TRUE;
// don't translate dialog messages when in Shift+F1 help mode
CFrameWnd* pFrameWnd = GetTopLevelFrame();
if (pFrameWnd != NULL && pFrameWnd->m_bHelpMode)
return FALSE;
// since 'IsDialogMessage' will eat frame window accelerators,
// we call all frame windows' PreTranslateMessage first
pFrameWnd = GetParentFrame(); // start with first parent frame
while (pFrameWnd != NULL)
{
// allow owner & frames to translate before IsDialogMessage does
if (pFrameWnd->PreTranslateMessage(pMsg))
return TRUE;
// try parent frames until there are no parent frames
pFrameWnd = pFrameWnd->GetParentFrame();
}
// don't call IsDialogMessage if form is empty
if (::GetWindow(m_hWnd, GW_CHILD) == NULL)
return FALSE;
// filter both messages to dialog and from children
return PreTranslateInput(pMsg);
}
I will admit, this code came directly from CFormView in the MFC source for Visual Studio 2008 (give credit where credit is due).
After including this code in my class, tab navigation is working as well as overall application accelerators.