1
votes

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;
}
2
Where is your CEdit control? Does it belong to the Tree?EylM
I use a splitter panel so the tree view is on the left panel and the edit controls are on the right panel. I have updated the question.Kevin
I overwrote the PreTranslateMessage Method inside the CFormView Class and the Del Key Press gets catched. But how do i proceed further?Kevin
Can you add some code how you create the splitter view?EylM
Added the Code to the Question.Kevin

2 Answers

1
votes

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);   
    }
    
0
votes

Another approach is to handle ON_UPDATE_COMMAND_UI:

ON_UPDATE_COMMAND_UI(ID_EDIT_DELETE, &StationView::OnDelete)

and

void StationView::OnDelete(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here

    pCmdUI->Enable(! IsEdit(GetFocus())); // see previous post for IsEdit method
}

However, I didn't tried this. You try :)

P.S. How to implement IsEdit (taken from previous post):

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;
}