【发布时间】: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 的特定工作方式?当用户输入太快时,它可能会累积变化。
【问题讨论】:
-
我不认为有任何特定的理由期望每次按键都得到通知。如果输入的到达速度快于处理速度,则控件合并通知是有意义的。