0
votes

I need to intercept key pressings and other user actions in my RichEdit box. I found it too complex to intercept user input in WM_KEYDOWN or WM_CHAR since some of the key pressings fire WM_CHAR, some of them not and also it has some other problems.

So I decided to listen EN_UPDATE messages, cuz it is said that this event fires on every change and just before RichEdit control starts to redraw itself ( https://docs.microsoft.com/en-us/windows/desktop/controls/en-update ). Well it sounds like trustworthy mechanism which allows to intercept all the changes.

But I found that not every WM_KEYDOWN causes firing of EN_UPDATE. I rapidly pressed many buttons (usual "char" buttons like "d", "f" and so on, no special keys), and found that when I inputed 100 chars, and WM_KEYDOWN also fired 100 times, but EN_UPDATE fired only 96 times (the number of activations of EN_UPDATE varies, sometimes it equals to the number of keypressings, don't know what it depends on). The number of WM_KEYDOWN and the number of characters entered are always equal of course.

Here's the code:

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

Am I doing something wrong or is it just specific working style of EN_UPDATE? Like may be it accumulates changes when user input is too fast.

1
I don't think there is any specific reason to expect to get notified of every keypress. Would make sense for the control to coalesce notifications if the input is arriving faster than it can be processed.David Heffernan

1 Answers

2
votes

EN_UPDATE is sent when the control is about to redraw itself. This does not imply that the control has to update after each WM_KEYDOWN, the control might have some caching mechanism to update delaying when keys are down within a little margin, for example.

This is not standard per control, you may have a control that updates on each keypress, even if there is 1 ms delay between keys, and you may have a control that updates each second, no matter how many keys it gets. It depends on the control.

Therefore, if you really want to get notified of every key, you have to use WM_KEYDOWN. EN_UPDATE is usually used to take the current state of the control and update another control.