使用 GetAsyncKeyState() 的键监听器/记录器

Posted

技术标签:

【中文标题】使用 GetAsyncKeyState() 的键监听器/记录器【英文标题】:Key listener / logger using GetAsyncKeyState() 【发布时间】:2011-11-02 22:35:45 【问题描述】:

我看到很多人能够使用 for 循环来确定按下的键的值,例如它将是 GetAsyncKeyState(41),因此他们可以轻松使用循环,但由于某种原因它只能工作对我来说,如果我输入 GetAsyncKeyState(0x41) 等,我能做些什么,这样我就可以循环遍历它,而不必单独输入每个值?

int main()

while(!GetAsyncKeyState(VK_F8))

    for(int i=65; i<90; i++)
    

        if(GetAsyncKeyState(i))
        
        log << "HELLO DER";
        
        Sleep(200);
     


【问题讨论】:

41 != 0x410x41 == 65 就像你在你的循环中一样。 【参考方案1】:

410x41 是两个完全不同的值。第二个,0x41 是十六进制的十进制值 65,它是 'A' 的 ASCII 码。但我猜你已经知道这一点,因为你将i 初始化为 65(大写 ASCII 字母和 VK 代码匹配)。

无论如何,假设您正在尝试记录按键操作,您的代码在某种程度上几乎可以正常工作。长话短说,你的循环延迟方式太长了,它会遍历每个字符200ms * 26 = 5.2 seconds。因此,如果您在 5.2 秒内键入“AAAB”,则只会注册“AB”。但如果延迟太短,您可能会多次注册新闻。

阅读documentation for GetAsyncKeyState了解更多信息。

无论如何,我可能会选择上面文档注释中提到的不同功能,例如GetKeyboardState,因为您通常使用GetAsyncKeyState 之类的东西来注册热键的按键或类似的东西。 IE。 GetAsyncKeyState 非常适合想知道是否按下了一个键,而不是按下了多少次、按下的顺序等。像你这样的循环似乎真的很容易出现问题。

另外,不要做任何愚蠢的记录键...

编辑:实际上GetKeyboardState 仍然不是一个好的解决方案。使用SetWindowsHookEx 设置键盘挂钩将是一个更好的选择。您可以使用WH_KEYBOARD_LL 钩子类型来设置带有LowLevelKeyboardProc 回调的低级键盘钩子。

我做了一些谷歌搜索,有一个开源宏程序 AutoHotkey 使用这种方法,我想如果你愿意,可以看看。

【讨论】:

【参考方案2】:

看看this。

用法很简单:

unsigned char kbstate[256];
if(!GetKeyboardState(kbstate))

   // can not get keyboard state
else
   for(int i=0; i<256: i++)
   
      if(kbstate[i] & 0x1)
      
         // the key is pressed, do something
      
   

【讨论】:

以上是关于使用 GetAsyncKeyState() 的键监听器/记录器的主要内容,如果未能解决你的问题,请参考以下文章

杂文虚拟键码表(供函数GetAsyncKeyState()使用)

为啥在 Win32 中使用 `GetAsyncKeyState()` 时我的热键会出错?

使用 GetAsyncKeyState() 识别按下的热键仅在 [重复]

将 GetAsyncKeyState() 重置为默认值

C#GetAsyncKeyState 不起作用

GetAsyncKeyState(int vKey)中的点逗号减号