You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让自动点击器区分自身点击与用户手动左键点击并停止?

区分自动模拟点击与用户手动点击的自动点击器解决方案

嘿,这个问题我太熟悉了!你遇到的核心问题是:mouse_event触发的模拟点击会被GetAsyncKeyState当成用户的手动点击,所以程序刚完成第一次自动点击就直接退出了。咱们可以通过几个简单的方法来解决这个区分问题:

方法一:添加状态标志位(最简单直接)

思路很简单:在模拟点击前后设置一个标志,告诉程序“现在是我自己在触发点击,别触发退出逻辑”。修改后的代码如下:

#include <windows.h>

int main() {
    bool isSimulatingClick = false;
    while (true) {
        Sleep(10);
        
        // 标记当前正在模拟点击
        isSimulatingClick = true;
        mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
        mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
        // 模拟完成,取消标记
        isSimulatingClick = false;
        
        Sleep(200);
        
        // 只有当不是模拟点击时,才检测用户的手动左键点击
        // 注意:GetAsyncKeyState需要和0x8000按位与,确保检测的是按键按下的状态
        if (!isSimulatingClick && (GetAsyncKeyState(VK_LBUTTON) & 0x8000)) {
            exit(0);
        }
    }
    return 0;
}

这里要注意GetAsyncKeyState的返回值:它的高位(第15位)表示按键是否处于按下状态,所以必须和0x8000做按位与运算,避免因为返回值的其他位导致误判。

方法二:改用SendInputAPI(推荐更可靠的方案)

mouse_event是Windows旧版API,微软现在更推荐使用SendInput来模拟输入。这个API不仅更稳定,还能通过dwExtraInfo字段给模拟事件添加自定义标记(如果需要更高级的区分的话)。结合标志位的简化版代码如下:

#include <windows.h>

int main() {
    bool isSimulating = false;
    while (true) {
        Sleep(10);
        
        isSimulating = true;
        // 准备两个输入事件:左键按下和抬起
        INPUT inputEvents[2] = {0};
        
        // 模拟左键按下
        inputEvents[0].type = INPUT_MOUSE;
        inputEvents[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
        
        // 模拟左键抬起
        inputEvents[1].type = INPUT_MOUSE;
        inputEvents[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;
        
        // 发送输入事件
        SendInput(2, inputEvents, sizeof(INPUT));
        isSimulating = false;
        
        Sleep(200);
        
        // 同样,只在非模拟状态下检测用户手动点击
        if (!isSimulating && (GetAsyncKeyState(VK_LBUTTON) & 0x8000)) {
            break;
        }
    }
    return 0;
}

方法三:全局鼠标钩子(进阶精确区分)

如果需要绝对精确地区分模拟输入和用户手动输入,可以设置一个低级鼠标钩子。在钩子回调函数中,你可以检查输入事件的dwExtraInfo(如果用SendInput的话,你可以给这个字段设置一个自定义值),或者判断事件是否来自注入。不过这个方法相对复杂,适合对区分精度要求极高的场景,一般前两种方法就足够解决你的问题了。

为什么你的原代码会失效?

因为mouse_event生成的鼠标事件会被系统当作普通的用户输入事件,GetAsyncKeyState会检测到这个“左键按下”的状态,所以第一次自动点击后就触发了exit(0)的逻辑。通过添加标志位,我们就跳过了模拟点击时的按键检测,只响应用户的手动点击。

内容的提问来源于stack exchange,提问作者Eric Ko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 07:04:41