使用Winapi键盘输入

时间:2012-06-22 11:58:59

标签: c winapi keyboard

我正在尝试用winapi制作一个简单的文本编辑器,它用于简单的字母,但不是大写字母或移位键。

char    keys[256];
int     x = 0;
while (1)
{
  for (x = 0; x <= 256; x++)
     {
        if (GetAsyncKeyState(x) == -32767)
           {
              char c[5];
              GetKeyboardState(keys);
              ToAscii(x, MapVirtualKey(x, 0), keys, c, 0);
              putchar(c[0]);
            }
      }
 }

3 个答案:

答案 0 :(得分:1)

键盘输入的行为远比你想象的复杂。您的方法不起作用,因为:

  1. GetAsyncKeyState可能会错过密钥。当用户在两次通话之间按键时会发生什么?
  2. 按住键时会发生什么?键盘重复怎么样?
  3. 最重要的是,您的代码假定键和字符之间的关系为1:1。您没有任何机制来处理移位/大写锁定状态或死锁等组合。
  4. 如果你试图解释你想要做什么会更好,你可以得到正确的方法来接近它。试图重新发明这种基本输入设备的行为并不是最好的方法。

答案 1 :(得分:1)

GetAsyncKeyState可能不是这里的方法:制作文本编辑器类型控件的真正方法是改为处理WM_KEYDOWN和WM_CHAR消息。当HWND具有焦点时,Windows会将这些发送到您的WndProc。这是Windows EDIT和RichEdit控件使用的技术。

使用WM_KEYDOWN处理非字符键 - 如箭头(VK_LEFT,VK_RIGHT),页面向上等;并使用WM_CHAR作为文本字符。 WM_KEYDOWN告诉您使用VK_值按下的键,并且不考虑移位状态;而WM_CHAR确实采取了移位状态,所以给你'A'对'a'或'1'vs'!'作为适当的。 (请注意,您必须在messsage循环中使用TranslateMessage才能实现此目的。)

说了这么多,更简单/更好的事情就是使用现有的Windows EDIT或RichEdit控件让他们为你工作 - 很少有理由重新发明轮子 - 除非你正在四处寻找乐趣并学习Win32。编写合适的文本编辑器非常复杂;有很多非显而易见的东西要考虑,特别是当你进入非英文文本时:你需要确保它能够正确地使用从右到左的文本(阿拉伯语,希伯来语),与以前用于的IME一起工作输入日文和中文字符。并且您必须确保屏幕阅读器可以访问您的控件,以便具有视觉障碍的用户仍然可以使用该控件。 EDIT和RichEdit为您完成所有这些。

例如,实际的记事本应用程序只是EDIT控件的包装器;而写字板只包含一个RichEdit控件;让控件完成所有艰苦的工作,只需在顶部添加额外的UI和文件保存/加载功能。

答案 2 :(得分:0)

尝试致电

GetKeyState(VK_CAPITAL); 

GetKeyboardState(keys);