EN_UPDATE работает ненадежно? - PullRequest
0 голосов
/ 08 января 2019

Мне нужно перехватывать нажатия клавиш и другие действия пользователя в моем окне RichEdit. Мне показалось слишком сложным перехватывать пользовательский ввод в WM_KEYDOWN или WM_CHAR, поскольку некоторые нажатия клавиш запускают WM_CHAR, а некоторые - нет, а также есть некоторые другие проблемы.

Поэтому я решил прослушать сообщения EN_UPDATE, потому что сказано, что это событие срабатывает при каждом изменении и непосредственно перед тем, как элемент управления RichEdit начинает перерисовывать себя (https://docs.microsoft.com/en-us/windows/desktop/controls/en-update). Ну, это звучит как надежный механизм, который позволяет перехватить все изменения.

Но я обнаружил, что не каждый WM_KEYDOWN вызывает срабатывание EN_UPDATE. Я быстро нажал много кнопок (обычные кнопки "char", такие как "d", "f" и т. Д., Без специальных клавиш) и обнаружил, что когда я ввел 100 символов, WM_KEYDOWN также сработал 100 раз, но EN_UPDATE сработал только 96 раз (количество активаций EN_UPDATE варьируется, иногда оно равно количеству нажатий клавиш, не знаю, от чего оно зависит). Количество WM_KEYDOWN и количество введенных символов, конечно, всегда равны.

Вот код:

BOOL CEditorView::OnCommand( WPARAM wParam, LPARAM lParam )
{

    static long count = 0;

    if( HIWORD( wParam) == EN_UPDATE )
    {

        if( (HWND)lParam == g_hwnd_RE )
        {

            if( g_allowProcessing )
            {
                count++;

            }
        }
    }

    return CDockablePane::OnCommand( wParam, lParam );
}



///// and WM_KEYDOWN

case WM_KEYDOWN:
{

    g_testCount++;
    return DefSubclassProc( hwnd, msg, wp, lp );

    break;
}

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

1 Ответ

0 голосов
/ 08 января 2019

EN_UPDATE отправляется, когда элемент управления собирается перерисовать себя. Это не означает, что элемент управления должен обновляться после каждого WM_KEYDOWN, элемент управления может иметь некоторый механизм кэширования, чтобы обновлять задержку, например, когда ключи находятся в небольшом поле.

Это не стандартно для каждого элемента управления, у вас может быть элемент управления, который обновляется при каждом нажатии клавиши, даже если между клавишами имеется задержка в 1 мс, и у вас может быть элемент управления, который обновляется каждую секунду, независимо от того, сколько ключей он получает. Это зависит от контроля.

Поэтому, если вы действительно хотите получать уведомления о каждом ключе, вы должны использовать WM_KEYDOWN. EN_UPDATE обычно используется для получения текущего состояния элемента управления и обновления другого элемента управления.

...