EN_UPDATE工作不可靠



我需要在RichEdit框中拦截按键和其他用户操作。我发现在WM_KEYDOWN或WM_CHAR中拦截用户输入太复杂了,因为有些按键会触发WM_CHAR,有些按键不会,而且还有一些其他问题。

所以我决定监听EN_UPDATE消息,因为据说每次更改都会触发此事件,而且就在RichEdit控件开始重新绘制自己之前(https://learn.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通常用于获取控件的当前状态并更新另一个控件。

最新更新