【问题标题】:C++ loop simulate keypress while key is pressedC ++循环在按下键时模拟按键
【发布时间】:2016-11-28 19:03:18
【问题描述】:

我正在尝试获得一个小型应用程序,该应用程序将在按下另一个键时连续模拟 UP(↑ 箭头键),在我的情况下为 Right CTRL

然而,我编写的代码每次按下只会发送一个 UP - 当我按住 Right CTRL 时,它只会发送一个 UP 并停止。

我想提一下,这段代码完全是根据我在网上找到的文档构建的,我以前从未用 C++ 或任何其他语言编写过任何东西,因此任何建议都会对我有很大帮助。我最初尝试在 CAPS LOCK 处于活动状态时执行此操作,但我发现无论我尝试什么,获取键状态(开/关)都对我不起作用。

int main()
{
  // This structure will be used to create the keyboard
  // input event.
  INPUT ip;

  // Pause for 1 seconds.
  Sleep(1000);

  // Set up a generic keyboard event.
  ip.type = INPUT_KEYBOARD;
  ip.ki.wScan = 0; // hardware scan code for key
  ip.ki.time = 0;
  ip.ki.dwExtraInfo = 0;

  while(1){
      if(GetAsyncKeyState(VK_RCONTROL))
      {
            // Press the "UP arrow" key
            ip.ki.wVk = 0x26; // virtual-key code for the "UP arrow" key
            ip.ki.dwFlags = 0; // 0 for key press
            SendInput(1, &ip, sizeof(INPUT));

            Sleep(50);

            // Release the "UP arrow" key
            ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
            SendInput(1, &ip, sizeof(INPUT));

            Sleep(50);
      }
  }

  // Exit normally
  return 0;
}  

【问题讨论】:

    标签: c++ windows keyboard


    【解决方案1】:

    GetAsyncKeyState 不返回关于键是向上还是向下的布尔值,而是返回一个 SHORT(一个 16 位整数,通常字面意思是 short

    如果函数成功,则返回值指定自上次调用GetAsyncKeyState 以来是否按下了键,以及该键当前是向上还是向下。如果设置了最高有效位,则按键按下,如果设置了最低有效位,则在上一次调用 GetAsyncKeyState 之后按下了按键。

    那么这是什么意思?硬件中的“最高有效位”是实现定义的(Which end of a bit field is the most significant bit?),但我们可以将所有内容视为“最左边”位是有效的(1000 与 0001)。

    所以我们可以用bitmask 测试keydown。

    我写了a small demo program 来帮助你想象这一切:

    std::cout << "number of bytes in a short: " << sizeof(short) << std::endl;
    short i = 0;
    i = 1 << (sizeof(short)*8-1); // use bit shifting to set most significant bit
    std::cout << "Initial value of i: " << i << std::endl;
    std::cout << "Initial value of i as hex: " << std::hex << i << std::endl;
    std::cout << "Is most significant bit set?\n";
    short bitmask = 0x8000;
    std::cout << std::boolalpha << ((bitmask & i) != 0) << std::endl;
    std::cout << "Unsetting MSB\n";
    i = 0x0000;
    std::cout << "Is most significant bit set?\n";
    std::cout << std::boolalpha << ((bitmask & i) != 0) << std::endl;
    

    此演示展示了如何将位掩码应用于短路以询问是否设置了最高有效位。

    GetAsyncKeyState 使您能够检查自上次检查后是否按下了键。如需更简单的通话,请查看GetKeyState

    【讨论】:

    • GetAsyncKeyState 使用最高有效位来表示键的当前状态:“如果函数成功,则返回值指定自上次调用 GetAsyncKeyState 以来是否按下了键,以及当前键是向上还是向下。"
    • @MilesBudnek:这里的“和”是合乎逻辑的,我相信。因此,如果自上次调用后没有按下他们的键,则无论键的状态如何,该函数都将始终返回 false。
    • 不,只是做了一个快速测试。在我按下键后它立即返回 0x8001,然后在我释放它之前返回 0x8000。
    • @AndyG 非常感谢您为我指明了正确的方向。实际上,我从一开始就完全按照自己的意愿去做,那就是使用切换状态。我用这个位替换它 if(GetKeyState(VK_CAPITAL) == 1 )
    • @MilesBudnek:非常感谢您的周到!我已经更新了帖子。我希望你发现它更准确。
    猜你喜欢
    • 2020-04-29
    • 2011-03-04
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多