MFC CEdit Control не обрабатывает нажатие клавиш после добавления в ускоритель - PullRequest
1 голос
/ 21 октября 2019

У меня проблема с ключом del в моем приложении MFC.

Я определил запись ускорителя для использования клавиши del в моем CTreeView.

моем приложениииспользует разделенное представление. CTreeView находится на левой панели, а CEdit Control - на правой панели внутри CFormView.

Запись определяется следующим образом:

VK_DELETE,      ID_EDIT_DELETE,         VIRTKEY, NOINVERT

The *Событие 1016 * обрабатывается внутри CTreeView.

После того, как я его добавил, ключ del перестал работать внутри элементов управления CEdit.

Что нужно сделать, чтобы восстановитьфункциональность в CEdit Control? Должен ли я добавить что-то вроде:

ON_COMMAND(ID_EDIT_DELETE, &StationView::OnDelete)

к каждой панели, которая содержит CEdit Control? А затем вручную реализовать функцию удаления символов? Или есть более простой способ передать событие del Key в CEdit Control?

ОБНОВЛЕНИЕ:

Я переписал метод PreTranslateMessage внутри класса CFormView иDel Key Press пойман. Но как мне продолжить дальше?

ОБНОВЛЕНИЕ V2:

Как указано здесь, Код для создания сплиттера:

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 ]

1 голос
/ 04 ноября 2019

От MSDN :

MFC имеет реализацию по умолчанию для обработчиков меню и клавиш ускорения, которую AppWizard добавляет в ваше приложение для обработки этих функций. Эти обработчики меню получают нажатия клавиш акселератора вместо вашего элемента управления редактированием.

Решение состоит в том, чтобы загрузить таблицу акселераторов и отправить сообщение вашему элементу управления редактированием в случае необходимости.

Здесьэто код:

  1. В ваш CFormView производный класс добавьте HACCEL m_hAccelTable member.
  2. Загрузите ускоритель в переопределенном OnInitialUpdate:

    void CFormRight::OnInitialUpdate()
    {
        CFormView::OnInitialUpdate();
    
        m_hAccelTable = ::LoadAccelerators(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
    }
    
  3. Переопределите функцию PreTranslateMessage в производном классе CFormView. Нам нужно проверить, является ли это ключевым сообщением, является ли сфокусированное окно контролем редактирования и имеется ли ускоритель.

    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. Наконец, уничтожьте ускоритель.

    void CFormRight::OnDestroy()
    {
        CFormView::OnDestroy();
    
        ::DestroyAcceleratorTable(m_hAccelTable);   
    }
    
0 голосов
/ 05 ноября 2019

Другой подход заключается в обработке ON_UPDATE_COMMAND_UI:

ON_UPDATE_COMMAND_UI(ID_EDIT_DELETE, &StationView::OnDelete)

и

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

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

Однако я не пробовал этого. Вы попробуйте:)

PS Как реализовать IsEdit (взято из предыдущего поста):

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...