c++windowsmfctreevieweditbox

MFC CEdit Control does not handle Key Pressed after added to Accelerator


I have a Problem with the del Key in my MFC Application.

I have defined an Accelerator entry to use the del key in my CTreeView.

My Application uses a split view. The CTreeView is on the left panel and the CEdit Control is on the right Panel inside a CFormView.

The Entry is defined like this:

VK_DELETE,      ID_EDIT_DELETE,         VIRTKEY, NOINVERT

The ID_EDIT_DELETE event is handled inside the CTreeView.

After i added it, the del Key stopped working inside the CEdit Controls.

What do I have to do to restore the functionality in CEdit Control? Do i have to add something like:

ON_COMMAND(ID_EDIT_DELETE, &StationView::OnDelete)

to every Panel which contains an CEdit Control? And then manually implement the delete Character Functionality? Or is there an easier way to pass the del Key event to the CEdit Control?

UPDATE:

I overwrote the PreTranslateMessage Method inside the CFormView Class and the Del Key Press gets catched. But how do i proceed further?

UPDATE V2:

As asked here the Code for the Splitter Creation:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext) {

    // create splitter window
    if (!m_wndSplitter.CreateStatic(this, 1, 2)) {
        return FALSE;
    }

    if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftView), CSize(250, 1000), pContext) ||
        !m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CLineSyncView), CSize(500, 1000), pContext)) {
        m_wndSplitter.DestroyWindow();
        return FALSE;
    }

    return TRUE;
}

Solution

  • From MSDN:

    MFC has default implementation for menu handlers and accelerator keys that AppWizard adds to your application to handle these functions. These menu handlers get the accelerator keystrokes instead of your edit control.

    The solution is to load the accelerator table and send the message to your edit control in case it's needed.

    Here is the code:

    1. In your CFormView derived class, add HACCEL m_hAccelTable member.
    2. Load the accelerator in overridden OnInitialUpdate:

      void CFormRight::OnInitialUpdate()
      {
          CFormView::OnInitialUpdate();
      
          m_hAccelTable = ::LoadAccelerators(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
      }
      
    3. Override the PreTranslateMessage function in your CFormView derived class. We need to check there if this is a key message, if the focused window is edit control and if the has an accelerator.

      BOOL CFormRight::PreTranslateMessage(MSG* pMsg)
      {
          if (m_hAccelTable)
          {
              // cheaper to check the message range then TranslateAccelerator
              if (WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST)
              {
                  CWnd* pWnd = GetFocus();
                  if (IsEdit(pWnd) && ::TranslateAccelerator(m_hWnd, m_hAccelTable, pMsg))
                  {
                      pWnd->SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
                      return FALSE;
                  }
              }
          }
          return CFormView::PreTranslateMessage(pMsg);    
      }
      
      BOOL CFormRight::IsEdit(CWnd* pWnd)
      {
          ASSERT(pWnd != NULL);
          HWND hWnd = pWnd->GetSafeHwnd();
          if (hWnd == NULL)
              return FALSE;
      
          TCHAR szClassName[6];
          return ::GetClassName(hWnd, szClassName, 6) &&
              _tcsicmp(szClassName, _T("Edit")) == 0;
      }
      
    4. Finally, destroy the accelerator.

      void CFormRight::OnDestroy()
      {
          CFormView::OnDestroy();
      
          ::DestroyAcceleratorTable(m_hAccelTable);   
      }