【问题标题】:Check if left mouse button is held down?检查鼠标左键是否被按住?
【发布时间】:2019-09-20 13:50:46
【问题描述】:

所以我只是开始使用 C++ 进行编码,在学习了一点之后,我开始编写一个自动点击器。我已经做到了,所以你可以使用键盘上的按钮或类似的东西来切换自动点击器,但这不是我想要的。

我遇到的问题是我似乎无法找到一种方法来检查鼠标左键是否被按住。如果它被按住,则继续单击,直到不再按住鼠标左键。

另外,我环顾四周,想知道如何做到这一点,我已经得到了一些我应该做的不同的事情,但它们都不起作用。我被告知要使用:

if((GetKeyState(VK_LBUTTON) & 0x100) != 0)

从这个答案here,但我也发现人们被告知使用:

if(GetKeyState(VK_LBUTTON) & 0x8000

遗憾的是,我在我的历史中找不到我在哪里找到它。

  1. 我已尝试获取 WM_LBUTTONDOWN 的键状态,但它似乎没有拾起正在按下的鼠标按钮。

  2. 我可以通过检查 VK_LBUTTON 的键状态来使其工作,但这仅检查鼠标左键是否被按下,而不是按住。所以它只是不断地点击,直到你打破 while 循环或关闭程序。

  3. 真的不值得把它放下,但我凌晨 12 点的自我认为检查左键是否被按下(就像之前的那个),它会将布尔值设置为 true,然后继续单击。但在那之后,我无法像以前那样停下来。现在回头看看代码,我明白为什么它不起作用了。

while (1) {
   if(GetKeyState(WM_LBUTTONDOWN)) {

      Sleep(delay);
      mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
      mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, 0);
      std::cout << "Clicked" << endl;
   }

   if (GetKeyState(VK_ESCAPE)) {

      break;
   }

}

就像我之前说的,我尝试了所有不同的组合来尝试让它发挥作用。但是我看不到鼠标左键是否被按住。我希望有人有答案,可以帮助我和其他人。无论如何,谢谢,祝您有愉快的一天。

【问题讨论】:

  • 嗨,exro,问题解决了吗?如果是,您可以accept the answer 帮助您或发布您自己的解决方案。

标签: c++ winapi


【解决方案1】:

GetKeyState() 接受virtual key code 作为输入,但WM_LBUTTONDOWN 不是虚拟键码,而是窗口消息。请改用VK_LBUTTON。

另外,GetKeyState() 依赖于调用线程本地的状态机。仅当线程处理来自其消息队列的键盘/鼠标窗口消息时,才会更新该状态机。您的代码没有这样的消息处理。对于您正在尝试的内容,请改用GetAsyncKeyState()。

此外,mouse_event() 已被弃用并且已经存在很长时间了。请改用SendInput()。

试试这个:

while (GetAsyncKeyState(VK_ESCAPE) >= 0)
{
   if (GetAsyncKeyState(VK_LBUTTON) < 0)
   {
      Sleep(delay);

      INPUT input[2] = {};

      input[0].type = INPUT_MOUSE;
      input[0].mi.dx = x;
      input[0].mi.dy = y;
      input[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;

      input[1] = input[0];
      input[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;

      SendInput(2, input, sizeof(INPUT));

      std::cout << "Clicked" << endl;
   }
}

【讨论】:

    【解决方案2】:

    我不确定我是否正确理解了 q .. 但要检查按下状态,您必须始终检查返回的 GetKeyState(VK_LBUTTON) 的高字节中的最低位(参见 GetKeyState() in MSDN-- 表示:

    bool leftButtonPressed = 0 != (GetKeyState(VK_LBUTTON) &amp; 0x800);

    WM_LBUTTONDOWN 是发送到报告客户区左键按下事件的窗口的消息——因此在 GetKeyState() 函数中使用它是错误的。试试

    const int delay = 50;
    while (1) 
    {
      if (GetKeyState(VK_LBUTTON) & 0x800)
      {
        Sleep(delay);
        mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
        mouse_event(MOUSEEVENTF_LEFTUP, 0,0, 0, 0);
        std::cout << "Clicked" << std::endl;
      }
    
      if (GetKeyState(VK_ESCAPE) & 0x800)
      {
        break;
      }
    }
    

    【讨论】:

    • 我刚试过,即使我按住左键,它仍然只打印一次“点击”。
    • 但是 mouse_event(MOUSEEVENTF_LEFTUP, 0,0, 0, 0); 将键设置回“未按下”——意味着 if (GetKeyState(VK_LBUTTON) &amp; 0x800) 说“假”并等待 while 循环中的下一次单击。所以你必须再次点击。
    • 哦,好吧。我想我可能知道如何解决它。感谢您的帮助。
    • 只要按下按钮,下面的代码就会打印出“点击”:while ((GetKeyState(VK_ESCAPE) &amp; 0x800) == 0) { if (GetKeyState(VK_LBUTTON) &amp; 0x800) { Sleep(delay); std::cout &lt;&lt; "Clicked" &lt;&lt; std::endl; } }
    • GetKeyState() 返回一个 SHORT(一个 16 位有符号整数),如果密钥关闭,则其中高位为 1。但是0x800 不代表高位,0x8000 可以。您可以使用GetKeyState(...) &lt; 0 代替GetKeyState(...) &amp; 0x8000 来测试是否下降,而不是使用GetKeyState(...) &gt;= 0 来测试是否上升。
    猜你喜欢
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多