WinAPI:如何在自定义编辑控件中处理键盘输入

时间:2011-04-30 21:25:07

标签: c++ winapi controls

所以我使用windows API在C ++中创建自己的编辑控件(多行文本框)。这很顺利,但我对一件事感到有些困惑。

首先,构建控件以便能够处理unicode,并且所有输入都将转换为unicode。换句话说,所有输入都将存储为wchar_t。

我感到困惑的是要处理键盘输入的消息。 MSDN具有以下窗口通知:

WM_CHAR
WM_KEYDOWN
WM_UNICHAR

和其他人一样,但我相信这是我需要处理的三个中的一个。我的猜测是WM_UNICHAR,但文档有点不清楚。另外,在查看VKcodes时,我看到了:

  

VK_PACKET
  0xE7
  用于传递Unicode字符,就像它们是击键一样。 VK_PACKET键是用于非键盘输入方法的32位虚拟键值的低位字。有关更多信息,请参阅KEYBDINPUT,SendInput,WM_KEYDOWN和WM_KEYUP中的备注。

对不起,如果这是一个愚蠢的问题,但我只是想确定这一点。

2 个答案:

答案 0 :(得分:4)

如果您的控件创建为unicode窗口(使用CreateWindowW),那么 在WM_CHAR中,您将获得开箱即用的宽字符。

如果您想提供控件的非unicode版本,那么您需要处理 WM_INPUTLANGCHANGE,类似这样:

case WM_INPUTLANGCHANGE:
{
              HKL NewInputLocale = (HKL) lParam ;
              g_InputCodePage = LangToCodePage( LOWORD(NewInputLocale) ) ; 
}

所以你的WM_CHAR处理程序应如下所示:

 case WM_CHAR:
     {
        unsigned char c = (byte)wParam;
        if(!::IsWindowUnicode(hwnd))
          MultiByteToWideChar(g_InputCodePage , 0, (LPCSTR) &c, 1, (LPWSTR) &wParam, 1) ;
     }

不要忘记WM_IME_CHAR和朋友。 然而关于RTL输入。

答案 1 :(得分:2)

当按下非系统键时,WM_KEYDOWN被发送到具有焦点的窗口。当TranslateMessage函数转换消息时,WM_CHAR消息将发送到窗口。 WM_CHAR使用UTF-16。 WM_UNICHAR与WM_CHAR类似,不同之处在于它使用UTF-32。它的目的是将Unicode字符发送/发布到ANSI窗口。如果窗口是ANSI(使用CreateWindowA创建),则生成WM_CHAR。如果是Unicode(使用CreateWindowW创建),则生成WM_UNICHAR。所以你的控制应该可以处理两者。

另请参阅此讨论Why is my WM_UNICHAR handler never called?