Allowing CView Classes to Handle Tab Navigation

Posted by Matt | Filed under , , ,

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.

Comments are closed