mfcccombobox

Detect keyboard hotkey inside edit control of CComboBox


I have this code:

BOOL CChristianLifeMinistryStudentMaterialDlg::PreTranslateMessage(MSG* pMsg)
{
    BOOL    bNoDispatch, bDealtWith;

    bDealtWith = FALSE;

    if (IsCTRLpressed() &&
        pMsg->message == WM_KEYDOWN && pMsg->wParam == _TINT(_T('I')))
    {
        if (EncodeText(pMsg->hwnd, _T("i")))
        {
            // Eat it.
            bNoDispatch = TRUE;
            bDealtWith = TRUE;
        }
    }
    else if (IsCTRLpressed() &&
        pMsg->message == WM_KEYDOWN && pMsg->wParam == _TINT(_T('B')))
    {
        if (EncodeText(pMsg->hwnd, _T("b")))
        {
            // Eat it.
            bNoDispatch = TRUE;
            bDealtWith = TRUE;
        }
    }

    if (!bDealtWith)
        bNoDispatch = CDialogEx::PreTranslateMessage(pMsg);

    return bNoDispatch;
}

Originally, I had 3 CEdit controls on my dialog. When you used this key press it performed an action as above on the selection in the edit controls.

I changed the controls from CEdit to CComboBox. They are editable type. I adjusted EncodeText to use GetEditSel and SetEditSel.

Only problem is now when I am editing text in the combo box. I select some of the text and press CTRL + I and nothing happens. The PTM of my dialog is not getting intercepted.

Visual Example

In this CEdit control I can select text:

Select Text

Then I use one of the hot keys, eg: CTRL + B and it still works:

Results for CEdit

But, when I select some text in the editable CComboBox and use the same hot key:

Use hot key on CComboBox

In this case it is not working.

I have assumed it is because technically I am inside a embedded "Edit" control of the combo. How do I still detect the hot keys now that I am using selected text inside a combo?


Solution

  • I ended up creating a new class CEncodedCombBox, derived from CComboBox, like this:

    // EncodedComboBox.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "Meeting Schedule Assistant.h"
    #include "EncodedComboBox.h"
    
    
    // CEncodedComboBox
    
    IMPLEMENT_DYNAMIC(CEncodedComboBox, CComboBox)
    
    CEncodedComboBox::CEncodedComboBox()
    {
    
    }
    
    CEncodedComboBox::~CEncodedComboBox()
    {
    }
    
    
    BEGIN_MESSAGE_MAP(CEncodedComboBox, CComboBox)
    END_MESSAGE_MAP()
    
    
    
    // CEncodedComboBox message handlers
    
    
    BOOL CEncodedComboBox::PreTranslateMessage(MSG* pMsg)
    {
        BOOL    bNoDispatch, bDealtWith;
        DWORD   dwSel = GetEditSel();
        CString strCode = _T(""), strText;
    
        GetWindowText(strText);
    
        bDealtWith = FALSE;
    
        if (IsCTRLpressed() &&
            pMsg->message == WM_KEYDOWN && pMsg->wParam == _TINT(_T('I')))
        {
            strCode = _T("i");
    
            bNoDispatch = TRUE;
            bDealtWith = TRUE;
        }
        else if (IsCTRLpressed() &&
            pMsg->message == WM_KEYDOWN && pMsg->wParam == _TINT(_T('B')))
        {
            strCode = _T("b");
    
            bNoDispatch = TRUE;
            bDealtWith = TRUE;
        }
    
        if (bDealtWith)
        {
            CMeetingScheduleAssistantApp::EncodeText(strText, strCode, LOWORD(dwSel), HIWORD(dwSel));
            SetWindowText(strText);
            SetEditSel(HIWORD(dwSel) + 7, HIWORD(dwSel) + 7);
        }
    
        if (!bDealtWith)
            bNoDispatch = CComboBox::PreTranslateMessage(pMsg);
    
        return bNoDispatch;
    }
    

    As you can see, it includes a PreTranslateMessage and it works:

    Hot keys now work

    If there is a better way then I welcome your comments or answer.

    Update

    I had to test against the edit control handle and not to combo box handle for my own CDialog to work:

    if (::GetParent(hWnd) == m_cbMaterialAssignment1.GetSafeHwnd())
    

    No derived combo class needed any more.