1

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

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]);
            }
      }
 }
4

3 回答 3

1

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

  1. GetAsyncKeyState可能会错过键。当用户在通话之间按下一个键时会发生什么?
  2. 当你按住一个键时会发生什么?键盘重复怎么办?
  3. 最关键的是,您的代码假定键和字符之间存在 1:1 的关系。您没有任何机制来处理诸如 shift / caps lock 状态或死键之类的组合。

如果您尝试解释您正在尝试做的事情会更好,并且您可以获得有关正确方法的建议。尝试重新发明这种基本输入设备的行为可能不是最好的方法。

于 2012-06-22T12:10:44.720 回答
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' vs 'a' 或 '1' vs '!' 作为适当的。(请注意,您必须在消息循环中包含 TranslateMessage 才能发生这种情况。)

说了这么多,更容易/更好的事情就是使用现有的 Windows EDIT 或RichEdit控件并让它们为您完成工作 - 很少有充分的理由重新发明轮子 - 除非您是为了好玩而玩耍和学习Win32也许。编写一个合适的文本编辑器是相当复杂的。有很多不明显的东西需要考虑,尤其是当你进入非英语文本时:你需要确保它与从右到左的文本(阿拉伯语、希伯来语)一起正常工作,与习惯于的 IME 一起工作输入日文和中文字符。而且您必须确保屏幕阅读器可以访问您的控件,以便有视觉障碍的用户仍然可以使用该控件。EDIT 和 RichEdit 为您完成所有这些工作。

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

于 2012-06-22T19:53:03.223 回答
0

试着打电话

GetKeyState(VK_CAPITAL); 

GetKeyboardState(keys);
于 2012-06-22T12:12:32.477 回答