在win32,WM_CHAR或WM_KEYDOWN/WM_KEYUP中处理键盘输入?

dev*_*roy 20 c++ winapi

所以在我一直在研究的文本编辑器程序中,我使用了WM_CHAR来处理来自键盘的输入.但是,我发现一些角色消息没有被记录下来.例如,如果我使用[shift] +数字键输入符号,例如%或&,则会记录一些符号,而其他字符如[shift] +9(导致')')则不会被记录.所以,我想知道我是否应该使用WM_KEYDOWN/WMKEYUP对来处理键盘输入.我曾经在汇编中编写了一个键盘记录器(实际上它只是我正在尝试的一个教程)并且使用了WM_KEYDOWN/WM_KEYUP对并且效果非常好.那么,我应该继续这个,还是我的程序发生了不寻常的事情?

谢谢,

Devjeet

Bre*_*McK 62

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

这里要理解的核心问题是键和字符并不完全相同.一些(但不是全部)键生成字符; 某些键根据移位或其他键盘状态生成不同的字符.要实现编辑器,您需要处理文本输入和非文本键盘输入,如箭头键.现在是冗长的版本,从似乎不正确的假设中挑选出来:

显然,Windows以非常奇怪的方式工作.[...]当你按[shift] +9时,windows似乎在消息WM_CHAR的wParam中发送了一个VK_LEFT

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

事情是WM_CHAR和WM_KEYDOWN都给你整个输入图片的两个部分 - 但你真的必须处理两个部分才能获得完整的图片.并且必须要注意,在两种情况下,wParam都是一个非常不同的东西.它是WM_CHAR的字符代码,但是WM_KEYDOWN的VK_代码.不要混淆两者.

为了使事情更加混乱,VK_值与有效字符共享相同的值.打开WinUser.h(它位于编译器安装目录下的include dir中),然后查找VK_LEFT:

#define VK_LEFT           0x25
Run Code Online (Sandbox Code Playgroud)

事实证明,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.)

因此将所有这些结合在一起,处理键盘的典型方法是使用以下所有方法:

  • 使用WM_CHAR处理文本输入:实际文本键.wParam是您要附加到字符串的字符,或者执行其他任何操作的字符.这将为您完成所有班次处理.

  • 使用WM_KEYDOWN处理'meta'键 - 如箭头键,home,end,page up等.传递所有AZ/0-9值,默认处理将它们转换为WM_CHAR,您可以在WM_CHAR处理程序中处理它们.(如果你想将它们用于特殊功能,你也可以在这里处理小键盘;否则它们会"落后"以数字WM_CHAR结束,具体取决于numlock状态.Windows会处理这个问题,就像它处理移位状态一样字母键.)

  • 如果你想显式处理ALT-组合(而不是使用加速器表),你将通过WM_SYSKEYDOWN得到它们.

我认为有些键可能会出现在两者中 - Enter可能同时显示为VK_RETURN的WM_KEYDOWN和\ r或\n \n WM_CHAR - 但我的偏好是在WM_KEYDOWN中处理它,以便将编辑键处理分开从文本键.

  • 谢啦!这解释了一切。我有点困惑为什么 VK_LEFT 与 a 相同。现在你的回答让一切都​​清楚了。非常感谢大佬!非常详尽的回答! (2认同)

Jon*_*art 5

Spy++将向您显示发送到窗口的消息,因此您可以进行试验并查看哪些消息适合您的应用程序。

如果你安装了 Visual Studio,它应该在你的开始菜单中,在 Programs -> Microsoft Visual Studio -> Visual Studio Tools -> Spy++ 下。