我需要在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。我迅速按下了许多按钮(通常是“ d”,“ f”等“ char”按钮,没有特殊键),发现当我输入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的特定工作方式?可能是当用户输入速度太快时,它会累积更改。
答案 0 :(得分:2)
EN_UPDATE在控件将要重绘时发送。这并不意味着该控件必须在每个WM_KEYDOWN之后进行更新,例如,该控件可能具有某种缓存机制来更新当键在很小范围内按下时的延迟。
这不是每个控件的标准,即使每个键之间有1 ms的延迟,您也可能有一个在每次按键时更新的控件,并且您可能有一个每秒更新的控件,无论它获得多少键。这取决于控件。
因此,如果您真的想获得每个键的通知,则必须使用WM_KEYDOWN。 EN_UPDATE通常用于获取控件的当前状态并更新另一个控件。