在win32,WM_CHAR或WM_KEYDOWN / WM_KEYUP处理键盘输入? [英] Handling keyboard input in win32, WM_CHAR or WM_KEYDOWN/WM_KEYUP?

查看:566
本文介绍了在win32,WM_CHAR或WM_KEYDOWN / WM_KEYUP处理键盘输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以在我一直在工作的文本编辑器程序,我使用WM_CHAR处理从键盘输入。但是,我发现一些字符信息不被记录。例如,如果我使用[shift] +数字键输入一个符号,如%或&某些重新录制,而其他如[shift] +9(这导致')'),不记录。所以,我想知道是否应该使用WM_KEYDOWN / WMKEYUP对来处理键盘输入。我曾经在汇编中写了一个键盘记录器(实际上它只是一个教程,我试图),并使用了WM_KEYDOWN / WM_KEYUP对,这是非常好的。那么,我应该继续这个,还是我的程序发生不寻常的事情?



感谢,



Devjeet

方案

这真的是对你上面评论的长时间回复,但把它放在一个答案,因为它太长的评论:)



核心问题要理解这里的是,键和字符是不一样的东西。一些(但不是全部)键生成字符;一些键根据移位或其他键盘状态产生不同的字符。为了实现一个编辑器,你需要处理文本输入和非文本键盘输入,如箭头键。现在的长期版本,从似乎是一个不正确的假设挑选:


显然,windows工作在真正奇怪的方式。 [...]看来当你按下[shift] +9,窗口发送一个VK_LEFT在wParam消息WM_CHAR

听起来像你可能在这里混合两件事。 WM_CHAR的东西是它给你的文本字符的字符代码:所以如果有人按9键,你会得到'9'。如果有人按SHIFT + 9,Windows将考虑移位状态 - 你会得到'('如果使用美国键盘),但你不会得到一个WM_CHAR箭头键,HOME,END等等,因为它们不是文本字符,另一方面,WM_KEYDOWN不处理字符,而是处理VK_代码;因此按9给你VK_9而不考虑移位状态;左箭头给你VK_LEFT - 再次移位状态的方位。 / p>

事情是,WM_CHAR和WM_KEYDOWN都给你两个部分的整体输入图片 - 但你真的必须处理这两个,以获得完整的图片。在这两种情况下wParam是一个非常不同的东西,它是一个WM_CHAR的字符代码,但是一个WM_KEYDOWN的VK_代码,不要混合两个。



使得事情更混乱,VK_值与有效字符共享相同的值。打开WinUser.h(它在编译器安装目录下的include dir中),然后查找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'字符相同 - 这使它看起来像chars和VK_是可互换的。但他们不是:小写'a',0x61的代码是VK_NUMPAD1! (所以WM_CHAR中的0x61意味着'a',WM_KEYDOWN表示NUMPAD1。如果用户在未移动状态下击中'A'键,你实际获得的是一个VK_A(与'A'相同的值)在WM_KEYDOWN,它被转换为'a'的WM_CHAR。)



所以把这一切结合在一起,处理键盘的典型方法是使用以下所有: / p>


  • 使用WM_CHAR处理文本输入:实际文本键。 wParam是要附加到字符串的字符,或者执行其他任何操作。


  • 使用WM_KEYDOWN来处理meta键 - 如箭头键,首页,结尾,页面向上等上。传递所有A-Z / 0-9值,默认处理将它们转换为WM_CHARs,您可以在您的WM_CHAR处理程序中处理。 (你也可以在这里处理数字键盘键,如果你想使用它们的特殊功能;否则它们落到最终作为数字WM_CHARs,取决于numlock状态。Windows照顾这,正如它处理shift状态为字母键。)


  • 如果您要明确处理ALT-组合(而不是使用加速表),您将通过WM_SYSKEYDOWN获得。 p>




我想有一些键可能会显示在两个 - Enter可能显示为一个WM_KEYDOWN VK_RETURN和\r或\\\
WM_CHAR - 但我的首选项将是在WM_KEYDOWN处理它,以保持编辑键处理与文本键分开。


So in the text editor program that i've been working on, I've used WM_CHAR to process input from the keyboard. However, I found that some of the character mesages are not recorded. For example, if I use [shift]+ number key to type a symbol such as % or &, some re recorded while others such as [shift]+9 (which results in ')'), are not recorded. So, I'm wondering if I should use WM_KEYDOWN/WMKEYUP pair to handle keyboard input. I once wrote a keylogger in assembly(actually it was just a tutorial that i was trying out) and had used WM_KEYDOWN/WM_KEYUP pairs and that worked out quite good. So, should I move on to this, or is it something unusual that is happening with my program?

Thanks,

Devjeet

解决方案

This is really a long reply to your comment above, but putting it in an answer because it's too long for a comment :)

The core issue to understand here is that keys and characters are not quite the same thing. Some (but not all) keys generate characters; some keys generate different characters depending on shift or other keyboard state. And to implement an editor, you need to handle both textual input and also non-textual keyboard input like arrow keys. Now the long-winded version, picking off from what seems to be an incorrect assumption:

Apparently, windows works in really strange ways. [...] It seems that when you press [shift]+9, windows sends a VK_LEFT in the wParam of message WM_CHAR

Sounds like you might be mixing two things up here. The thing with WM_CHAR is that it gives you character codes for textual characters: so if someone presses the 9 key, you'll get '9'. If someone presses SHIFT+9, Windows will take the shift state into account - and you get '(' (if using US keyboard). But you won't ever get a WM_CHAR for arrow keys, HOME, END, and so on, since they are not textual characters. WM_KEYDOWN, on the other hand, does not deal in characters, but in VK_ codes; so pressing 9 gives you VK_9 regardless of shift state; and left arrow gives you VK_LEFT - again regardles of shift state.

The things is that WM_CHAR and WM_KEYDOWN both give you two parts to the overall input picture - but you really have to handle both to get the full picture. And have to be aware that the wParam is a very different thing in both cases. It's a character code for WM_CHAR, but a VK_ code for WM_KEYDOWN. Don't mix the two.

And to make things more confusing, VK_ values share the same values as valid characters. Open up WinUser.h (it's in the include dir under the compiler installation dir), and look for VK_LEFT:

#define VK_LEFT           0x25

Turns out that 0x25 is also the code for the '%' character (see any ascii/unicode table for details). So if WM_CHAR gets 0x25, it means shift-5 was pressed (assuming US keyboard) to create a '%'; but if WM_KEYDOWN gets 0x25, it means left arrow (VK_LEFT) was pressed. And to add a bit more confusion, the Virtual Key codes for the A-Z keys and 0-9 keys happen to be the same as the 'A'-'Z' and '0'-'9' characters - which makes it seem like chars and VK_'s are interchangable. But they're not: the code for lower case 'a', 0x61, is VK_NUMPAD1! (So getting 0x61 in WM_CHAR does mean 'a', getting it in WM_KEYDOWN means NUMPAD1. And if a user does hit the 'A' key in unshifted state, what you actually get is first a VK_A (same value as 'A') in WM_KEYDOWN, which gets translated to WM_CHAR of 'a'.)

So tying all this together, the typical way to handle keyboard is to use all of the following:

  • Use WM_CHAR to handle textual input: actual text keys. wParam is the character that you want to append to your string, or do whatever else with. This does all the shift- processing for you.

  • Use WM_KEYDOWN to handle 'meta' keys - like arrow keys, home, end, page up, and so on. Pass all the A-Z/0-9 values through, the default handling will turn them into WM_CHARs that you can handle in your WM_CHAR handler. (You can also handle numpad keys here if you want to use them for special functionality; otherwise they 'fall through' to end up as numeric WM_CHARs, depending on numlock state. Windows takes care of this, just as it handles shift state for the alphabetic keys.)

  • If you want to handle ALT- combos explicitly (rather than using an accelerator table), you'll get those via WM_SYSKEYDOWN.

I think there are some keys that might show up in both - Enter might show up as both a WM_KEYDOWN of VK_RETURN and as either \r or \n WM_CHAR - but my preference would be to handle it in WM_KEYDOWN, to keep editing key handling separate from text keys.

这篇关于在win32,WM_CHAR或WM_KEYDOWN / WM_KEYUP处理键盘输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆