2011-11-17 50 views
16

因此,在我一直在處理的文本編輯器程序中,我用WM_CHAR來處理來自鍵盤的輸入。但是,我發現一些角色消息不被記錄。例如,如果我使用[SHIFT] +數字鍵鍵入符號如%或&,一些重新記錄而其他如[SHIFT] 9(其導致「)」),不會被記錄。所以,我想知道是否應該使用WM_KEYDOWN/WMKEYUP對來處理鍵盤輸入。我曾經在程序集中編寫過一個鍵盤記錄程序(實際上它只是一個我正在嘗試的教程),並且使用了WM_KEYDOWN/WM_KEYUP對,結果非常好。那麼,我應該繼續討論這個問題,還是我的計劃中發生了一些不尋常的事情?在win32,WM_CHAR或WM_KEYDOWN/WM_KEYUP中處理鍵盤輸入?

感謝,

Devjeet

+1

相信WM_CHAR消息被用於WM_KEYDOWN默認窗口過程自動生成。 –

+0

取決於這是否僅僅是爲個人使用或沒有,你可能還需要支持IME的,這樣用戶可以輸入語言,如日本,中國,韓國。除了重新開發垃圾之外,可能還是值得看看開源代碼編輯組件scintilla.org,看它是否滿足您的需求,或者看看它是如何處理這些問題的。請注意,即使是閃爍石也不能處理諸如希伯來文/阿拉伯文等雙向文本的問題。正確處理Unicode也有一些有趣的問題,因爲屏幕上的可顯示字符可映射到一個或多個WCHAR。 – BrendanMcK

+0

感謝您的評論,我解決了這個錯誤。顯然,Windows以非常奇怪的方式工作。我已經在一定的條件下處理箭頭鍵。我使用了SPY ++,然後分析了一切。然後,我縮小了這些條件(在switch語句中),然後將它們評論出來。有用。看起來,當你按下[shift] +9時,windows會在消息WM_CHAR的wParam中發送一個VK_LEFT。 – devjeetroy

回答

47

這的確是一個很長的回覆你上面的評論,但將它放在一個答案,因爲它太長了評論:)

的核心問題這裏要理解的是,鍵和字符不是完全相同的東西。一些(但不是全部)鍵生成字符;某些按鍵會根據移位或其他鍵盤狀態生成不同的字符。要實現一個編輯器,您需要處理文本輸入和非文本鍵盤輸入,如箭頭鍵。現在這個冗長的版本,從似乎是一個不正確的假設中剔除:

顯然,Windows以非常奇怪的方式工作。 [...]看起來,當你按下[shift] +9時,窗口在WM_CHAR消息的wParam中發送一個VK_LEFT

聽起來像你可能在這裏混合了兩件事。 WM_CHAR的事情是它爲你提供了文本字符的字符代碼:所以如果有人按下9鍵,你會得到'9'。如果有人按下SHIFT + 9,Windows將會考慮轉換狀態 - 並且你會得到'('(如果使用美式鍵盤)。但是你永遠不會得到WM_CHAR的箭頭鍵,HOME,END等等, 。因爲它們不是文本字符WM_KEYDOWN,而另一方面,不處理的字符,但在VK_碼,所以按下9給你VK_9不論移動狀態;而左箭頭給你VK_LEFT - 移動狀態再次regardles

的事情之一是,WM_CHAR和WM_KEYDOWN既給你兩個部分組成的整體輸入圖像 - 但你真的要同時處理,以獲得完整的圖片,並且必須意識到wParam爲一個非常不同的事情在這兩種情況下。它是爲WM_CHAR字符代碼,但對於一個WM_KEYDOWN代碼VK_不要混用兩種。

而到m更令人困惑的是,VK_值與有效字符共享相同的值。打開WinUser。H(它在包括編譯器安裝目錄下的目錄),並查找VK_LEFT:

#define VK_LEFT   0x25 

原來,0x25也是對「%」字符的代碼(詳見任何ASCII/Unicode編碼表) 。所以如果WM_CHAR得到0x25,就意味着shift-5被按下(假設用美式鍵盤)來創建'%';但如果WM_KEYDOWN得到0x25,則表示按下了左箭頭(VK_LEFT)。並且爲了增加更多的混淆,AZ鍵和0-9鍵的虛擬鍵碼恰好與'A' - 'Z'和'0' - '9'字符相同 - 這看起來像是字符和VK_可互換。但它們不是:小寫'a'的代碼0x61是VK_NUMPAD1! (因此獲得在WM_CHAR 0x61是否意味着「A」,得到它在WM_KEYDOWN意味着NUMPAD1。如果用戶沒有打在未移動狀態下的「A」鍵,你實際上得到的是第一個VK_A(相同的值「A」)在WM_KEYDOWN,它被翻譯成的「A」 WM_CHAR)

所以綁這一切在一起,來處理鍵盤的典型方式是使用以下所有條件:

  • 使用WM_CHAR處理文本輸入:實際的文本鍵。 wParam是你想追加到你的字符串的字符,或者做任何其他的事情。這爲你做了所有的換班處理。

  • 使用WM_KEYDOWN處理 '元' 鍵 - 像箭頭鍵,Home,End,Page Up,等等。傳遞所有A-Z/0-9值,默認處理將把它們變成WM_CHAR,你可以在你的WM_CHAR處理程序中處理它們。 (你也可以在這裏辦理小鍵盤上的按鍵,如果你想使用它們特殊的功能,否則他們「落空」,以最終成爲數字WM_CHARs,取決於上的NumLock狀態的Windows注意到了這一問題,只是因爲它可以爲移動狀態。字母鍵)。

  • 如果你想明確地處理ALT-組合(而不是使用加速表),你將通過WM_SYSKEYDOWN得到那些。

我覺得有一些鍵可能在兩種顯示 - 輸入可能會顯示爲既是VK_RETURN的WM_KEYDOWN和任何\ R或\ n WM_CHAR - 但我更傾向於將處理它在WM_KEYDOWN ,使編輯密鑰處理與文本密鑰分離。

+1

謝謝你!解釋了一切。對於爲什麼VK_LEFT與a相同,我有點困惑)。現在你的答案使一切都清楚了。非常感謝!非常詳盡的答案! – devjeetroy

+0

非常明確的答案,有這個相同的問題,現在這使得更多的意義。 – abelito

+0

同意,非常好的答案。 – Chungzuwalla

4

Spy++將顯示你的消息被髮送到一個窗口,所以你可以實驗,看看消息是適合您的應用程序。

如果你已經安裝了Visual Studio,它應該是在你的開始菜單,在程序 - >微軟的Visual Studio - > Visual Studio工具 - >間諜++。