所以我使用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中的备注。
对不起,如果这是一个愚蠢的问题,但我只是想确定这一点。
答案 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。所以你的控制应该可以处理两者。