2011-04-30 108 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?

相關問題