EN_UPDATE 工作不可靠?

EN_UPDATE works unreliably?

我需要拦截 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的特定工作方式?就像当用户输入太快时它可能会累积变化。

EN_UPDATE 在控件即将重绘自身时发送。这并不意味着控件必须在每个 WM_KEYDOWN 之后更新,例如,控件可能有一些缓存机制来延迟更新,当键在一个小范围内下降时。

这不是每个控件的标准,您可能有一个在每次按键时更新的控件,即使按键之间有 1 毫秒的延迟,并且您可能有一个每秒更新的控件,无论它有多少键得到。这取决于控件。

因此,如果你真的想得到每个键的通知,你必须使用WM_KEYDOWN。 EN_UPDATE 通常用于获取控件的当前状态并更新另一个控件。