【问题标题】:Virtual key code of ALT KEYALT KEY的虚拟键码
【发布时间】:2018-03-01 23:20:29
【问题描述】:

我正在制作挂钩并捕获键盘虚拟键码,根据 MSDN, these are 存在的键码。

每个关键代码都可以正常工作,因为我将在我的代码下方给出一个示例。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

HHOOK altKey;
KBDLLHOOKSTRUCT kbdHK;
MSG message;

LRESULT CALLBACK kbdProc(int nCode, WPARAM wPar, LPARAM lPar);

int main(int argc, char *argv[]) {
  altKey = SetWindowsHookEx(WH_KEYBOARD_LL, kbdProc, NULL, 0);

  while(GetMessage(&message, NULL, 0, 0) > 0){
    TranslateMessage(&message);
    DispatchMessage(&message);
  }
  return 0;
}

LRESULT CALLBACK kbdProc(int nCode, WPARAM wPar, LPARAM lPar){

  if(nCode >= 0){
    if(wPar == 256){
      kbdHK = *(KBDLLHOOKSTRUCT *)lPar;
      if(kbdHK.vkCode == 0x20){
        printf("spacebar pressed!!\n");
      }
    }
  }
  return CallNextHookEx(NULL, nCode, wPar, lPar);
}

但是当我用0x12 替换虚拟键代码时,根据MSDN 是ALT KEY,我无法得到结果。可能是什么问题?

编辑

当我使用这行代码时,我可以为每个键获取scanCode,但不能再次获取 alt 键,这很有趣。

printf("%d", kbd.scanCode); 

【问题讨论】:

  • 控制台模式应用程序是错误类型的应用程序来测试这一点。控制台主机(conhost.exe)首先在击键时得到破解,它对待 Alt 是特殊的,因为它操作控制台本身而不是程序。例如,尝试 Alt+Space。改为构建本机 Windows 程序。
  • 顺便说一句 - 仅仅因为代码使用了 winapi,并不能取消它也是 C 的资格。您的代码,就像它在我的 ANSI C 编译器中构建和运行一样。因此它是 C。 否决的投票者更有可能响应了帮助调试代码的请求。也就是说,它没有任何可检测到的错误,它的行为符合预期,但你无法让它按照 的期望去做。接近投票将 off-topic 列为原因。我不同意,但是反对的选民不需要我这样做。我个人认为这是一个很好的问题,并且将来可能对其他人有所帮助。 (+1)
  • Nothing - 重新阅读我的上一条评论:仅仅因为代码使用了 winapi,并不能取消它也是 C 的资格。您的代码,就像它在我的 ANSI C 编译器中构建和运行一样.因此它是 C。
  • @IInspectable - 来自 MSDN:GetAsyncKeyState 确定在调用函数时某个键是向上还是向下,以及在上一次调用 GetAsyncKeyState 之后是否按下了该键。 通过观察这些状态变化,可以检测到按键。通常在循环中实现此功能,因此可以检测到状态的变化,甚至可以检测同时按下的按键组合。
  • @ryyker: GetAsyncKeyState 是基于样本的。监控击键的可靠方法需要基于事件的实现。 GetAsyncKeyState 在采样点之间发生时很可能会错过键盘输入。我的评论仍然成立:你不能使用GetAsyncKeyState 来监控击键。

标签: windows winapi hook


【解决方案1】:

我建议挂钩the WM_SYSKEYDOWN messages,并注意这些值对应于通常具有标识符的常量(在本例中为VK_MENU)。毕竟,作为程序员,我们很早就被教导不要使用幻数

WM_SYSKEYDOWN 消息

当用户按下 F10 键(激活菜单栏)或按住 ALT 键然后按下另一个键时,以键盘焦点发布到窗口。

正如 cmets 中所指出的,另一个选项是使用GetAsyncKeyState。你担心你将无法使用 vkCode 似乎很奇怪,毕竟GetAsyncKeyStates 参数 虚拟键代码,所以你的代码'会使用将沿着:

short result = GetAsyncKeyState(VK_MENU);
if (!result) {
    // no alt keystrokes since last call
}

这是您能够区分左 alt (VK_LMENU) 和右 alt (VK_RMENU) 键的唯一方法,但它不是窗口循环方式。现在你两者都有了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 2020-10-24
    • 2013-04-06
    • 1970-01-01
    相关资源
    最近更新 更多