Определить горячую клавишу клавиатуры внутри элемента управления редактирования CComboBox

У меня есть этот код:

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

Изначально у меня было 3 CEdit элементы управления в моем диалоге. Когда вы нажали эту клавишу, она выполнила действие, описанное выше, для выбора в элементах управления редактирования.

Я изменил управление с CEdit в CComboBox, Они редактируемого типа. Я настроил EncodeText использовать GetEditSel а также SetEditSel,

Единственная проблема сейчас, когда я редактирую текст в поле со списком. Я выбираю часть текста и нажимаю CTRL + I, и ничего не происходит. PTM моего диалога не перехватывается.

Визуальный пример

В этом CEdit контролировать я могу выбрать текст:

Выберите текст

Затем я использую одну из горячих клавиш, например: CTRL + B, и она все еще работает:

Результаты для CEdit

Но когда я выбираю какой-то текст в редактируемый CComboBox и используйте ту же горячую клавишу:

Используйте горячую клавишу на CComboBox

В этом случае это не работает.

Я предположил, что это потому, что технически я нахожусь внутри встроенного элемента управления "Редактировать" комбо. Как мне по-прежнему определять горячие клавиши сейчас, когда я использую выделенный текст внутри комбо?

2 ответа

Решение

Я закончил тем, что создал новый класс CEncodedCombBox, происходит от CComboBox, как это:

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

Как видите, он включает в себя PreTranslateMessage и это работает:

Горячие клавиши теперь работают

Если есть лучший способ, тогда я приветствую ваши комментарии или ответ.

Обновить

Я должен был проверить на ручку управления редактирования, а не на ручку комбинированного окна для моего собственного CDialog работать:

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

Больше не требуется производный комбо-класс.

Не уверен, что мне нравится WM_KEYDOWN хак. Если у вас есть настоящие горячие клавиши, я предлагаю вам правильно их обработать:

BEGIN_MESSAGE_MAP(CEncodedCombBox, CCombBox)
    ON_WM_HOTKEY()
END_MESSAGE_MAP()

void CEncodedCombBox::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
{
    if (nHotKeyId == idForHotKey_I)
        HandleCode(_T("i"));
    else if (nHotKeyId == idForHotKey_B)
        HandleCode(_T("b"));
}

void CEncodedCombBox::HandleCode(CString strCode)
{
    DWORD dwSel = GetEditSel();

    CMeetingScheduleAssistantApp::EncodeText(strText, strCode, LOWORD(dwSel), HIWORD(dwSel));
    SetWindowText(strText);
    SetEditSel(LOWORD(dwSel), HIWORD(dwSel) + 7);
}
Другие вопросы по тегам