2011-04-30 32 views
2

因此,我使用Windows API在C++中创建了自己的编辑控件(多行文本框)。这很好,但我对一件事有点困惑。WinAPI:如何在自定义编辑控件中处理键盘输入

首先,控件的构建是为了能够处理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

你是出于好奇,还是因为你不喜欢/不提供的标准编辑控件?我只问,因为编辑框中有很多功能。 – Skizz 2011-04-30 21:55:01

+0

控件必须能够处理大量文本而不会冻结或滞后。另外,我还需要支持多种颜色的文本和粗体/斜体。我知道RichEdit控件处理后两种,但不是第一种。是的,有很多东西都可以用来制作这样的东西,但是它也有很多乐趣和很棒的学习体验。^ _^ – Gogeta70 2011-04-30 21:58:31

回答

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输入。

+0

非常好,谢谢。我会给这个镜头^ _^ – Gogeta70 2011-04-30 21:44:26

+0

To Gogeta70:这是我在我的HTMLayout和Sciter引擎中做的 - 到目前为止它的工作原理。 – 2011-04-30 21:47:36

2

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

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