【问题标题】:EN_UPDATE works unreliably?EN_UPDATE 工作不可靠?
【发布时间】:2019-01-08 21:35:28
【问题描述】:

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

【问题讨论】:

  • 我不认为有任何特定的理由期望每次按键都得到通知。如果输入的到达速度快于处理速度,则控件合并通知是有意义的。

标签: c++ winapi richedit


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 2021-10-28
    相关资源
    最近更新 更多