尧图精选

Visual Basic 6.0 连点器制作原理 + 源码:鼠标点击与鼠标录制完整实现(TaoToken 统一 Key 通道)

🕒 发布时间:2026/10/1 19:54:50 📁 来源:尧图网络
1. VB6 连点器到底在做什么从鼠标点击到鼠标录制的底层原理Visual Basic 6.0 连点器说白了就是一个用 Windows API 模拟鼠标动作、再把鼠标轨迹录下来回放的小工具。它适合两类人一类是想复刻经典小工具的老派开发者另一类是想搞懂 Windows 消息机制、钩子Hook和鼠标事件到底怎么串起来的人。核心检索词就三个鼠标点击、鼠标录制、VB6 源码实现。很多人第一次写连点器会直接用窗体事件 MouseDown、MouseUp、MouseMove 来记录我早期也这么干过。问题很明显窗体必须透明、必须置顶而且录不到桌面其他窗口的操作回放时坐标一偏就全乱。真正靠谱的做法是走 Windows API 这条路——用mouse_event发点击用SetWindowsHookEx装低级鼠标钩子WH_MOUSE_LL抓全局鼠标消息再用GetCursorPos、SetCursorPos做坐标读写。这里先把几个关键 API 的职责理清楚后面写代码才不会乱API 名称作用关键参数mouse_event模拟鼠标点击/移动dwFlags 控制按下、抬起、移动GetCursorPos获取鼠标屏幕坐标lpPoint 接收 POINTAPISetCursorPos设置鼠标屏幕坐标X、YClipCursor限制鼠标活动区域lpRect 为 RECT传 0 解除GetDoubleClickTime取双击间隔返回毫秒最大 5000GetDesktopWindow取桌面句柄返回 HWNDGetWindowRect取窗口矩形配合桌面句柄拿分辨率SetWindowsHookEx安装钩子idHook 选 WH_MOUSE_LLUnhookWindowsHookEx卸载钩子hhk 为钩子句柄CallNextHookEx传给下一个钩子强烈建议调用mouse_event的 dwFlags 是重点左键按下是H2左键抬起是H4所以一次左键单击就是H2 H4。右键是H8 H10中键是H20 H40。这个值组合错了就会出现“只按下不抬起”或者“点了没反应”的情况。录制这块钩子回调里拿到的是鼠标消息但消息本身不带坐标得在回调里再调GetCursorPos把当前坐标补上。所以录制结构体一般长这样Private Type MouseButtonData MouseX As Long MouseY As Long Button As Integer State As Integer End TypeButton 用 1/2/4 表示左/右/中State 用 -1/0/1 表示按下/无/抬起。回放时按索引逐条读遇到“按下抬起”相邻且按键一致就合并成一次单击这样回放出来的点击才干净不会出现半按状态卡住。至于为什么不用鼠标消息直接记录而要在钩子里转一道是因为低级钩子拿到的是原始输入事件跨进程、跨窗口都能抓到比窗体事件覆盖面大得多。代价是回调函数必须放在标准模块里且要用AddressOf取函数地址VB6 对这块限制比较多写的时候要小心。2. TaoToken 统一 Key 通道给连点器配套服务留一个入口连点器本身是本地工具但很多老派开发者会顺手给它加一些配套能力比如点击日志上报、配置云端同步、或者调用一个模型接口做“智能点击间隔推荐”。这些服务如果每个都单独配 Key、单独改 Base URL维护起来很烦。TaoToken 在这里的作用就是把这些调用统一到一个 Key 通道上Base URL 固定为https://taotoken.net/api模型 ID 自己选Key 在控制台生成一次就能复用。先说清楚它是什么TaoToken 是一个统一的大模型 API 接入通道能做什么——把不同模型的调用收敛到同一个 Base URL 和同一套 Key 管理适合谁——需要在自己小工具里接模型能力、又不想每个服务单独维护凭证的开发者。对 VB6 连点器来说最典型的用法是点击间隔不是写死的而是让模型根据你录制的轨迹密度给一个建议值或者把点击次数、耗时写进日志后调模型做简单分析。前置准备只有三步。第一打开官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content注册并登录。第二进控制台创建 API Key地址是https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite。第三如果你要验证模型通不通直接去模型对话页https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite发一条消息试试。Key 拿到后不要硬编码进 VB6 源码里VB6 编译出来的 exe 反编译成本很低。建议放在同目录的 ini 或 json 里运行时读。下面这个 JSON 就是配套服务调用的配置片段路径按你项目实际放{ taotoken: { base_url: https://taotoken.net/api, api_key: sk-你的Key, model_id: 你选的模型ID, timeout_ms: 15000 }, clicker: { default_interval_ms: 120, max_click_count: 5000, record_file: .\\record\\mouse_trace.dat } }注意 Base URL 是https://taotoken.net/api不要多加斜杠也不要写成别的路径。Model ID 必须填因为统一通道下不同模型靠这个字段区分。VB6 里读 JSON 可以用ScriptControl或者自己写个简易解析读 ini 更省事用GetPrivateProfileString就行。如果你后面要做长期编码或者 Agent 类的东西比如让连点器根据任务自动生成点击脚本可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite。API Key 管理页在https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite。这几个入口按需用别一股脑全塞进连点器主流程里本地点击和网络调用要解耦不然网络一抖点击就卡。3. 可复制配置API 声明、点击循环与录制回放核心代码这一节直接给能粘贴进 VB6 的代码。先建一个标准模块modMouse.bas放 API 声明和基础封装。 modMouse.bas Option Explicit Public Type POINTAPI X As Long Y As Long End Type Public Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type Public Enum MouseKey MouseNullKey H0 MouseLeftKey H2 H4 MouseLeftKey_Down H2 MouseLeftKey_Up H4 MouseRightKey H8 H10 MouseRightKey_Down H8 MouseRightKey_Up H10 MouseMiddleKey H20 H40 MouseMiddleKey_Down H20 MouseMiddleKey_Up H40 End Enum Public Declare Sub mouse_event Lib user32 (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long) Public Declare Function GetCursorPos Lib user32 (lpPoint As POINTAPI) As Long Public Declare Function SetCursorPos Lib user32 (ByVal X As Long, ByVal Y As Long) As Long Public Declare Function ClipCursor Lib user32 (lpRect As Any) As Long Public Declare Function GetDoubleClickTime Lib user32 () As Long Public Declare Function SetDoubleClickTime Lib user32 (ByVal wCount As Long) As Long Public Declare Function GetDesktopWindow Lib user32 () As Long Public Declare Function GetWindowRect Lib user32 (ByVal hwnd As Long, lpRect As RECT) As Long Public Sub SendMouseKey(ByVal mk As MouseKey) mouse_event mk, 0, 0, 0, 0 End Sub Public Sub GetMousePosition(ByRef X As Long, ByRef Y As Long) Dim p As POINTAPI GetCursorPos p X p.X Y p.Y End Sub Public Sub SetMousePosition(ByVal X As Long, ByVal Y As Long) SetCursorPos X, Y End Sub Public Sub GetDeskTopArea(ByRef W As Long, ByRef H As Long) Dim r As RECT GetWindowRect GetDesktopWindow, r W r.Right H r.Bottom End Sub点击循环不要用DoEvents死等VB6 里用Sleep更稳声明在kernel32Public Declare Sub Sleep Lib kernel32 (ByVal dwMilliseconds As Long) Public Sub ClickLoop(ByVal x As Long, ByVal y As Long, ByVal intervalMs As Long, ByVal count As Long) Dim i As Long For i 1 To count SetMousePosition x, y SendMouseKey MouseLeftKey Sleep intervalMs Next i End Sub录制部分钩子回调必须放标准模块AddressOf只能取标准模块里的函数地址 modHook.bas Option Explicit Public Declare Function SetWindowsHookEx Lib user32 Alias SetWindowsHookExA (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long Public Declare Function UnhookWindowsHookEx Lib user32 (ByVal hHook As Long) As Long Public Declare Function CallNextHookEx Lib user32 (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As Long Public Declare Function GetModuleHandle Lib kernel32 Alias GetModuleHandleA (ByVal lpModuleName As String) As Long Public Const WH_MOUSE_LL As Long 14 Public Const WM_LBUTTONDOWN As Long H201 Public Const WM_LBUTTONUP As Long H202 Public Const WM_RBUTTONDOWN As Long H204 Public Const WM_RBUTTONUP As Long H205 Public Const WM_MBUTTONDOWN As Long H207 Public Const WM_MBUTTONUP As Long H208 Public HookHandle As Long Public Recording As Boolean Public RecordData() As MouseButtonData Public RecordCount As Long Public Function MouseHookProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long If nCode 0 Then MouseHookProc CallNextHookEx(HookHandle, nCode, wParam, lParam) Exit Function End If If Recording Then Dim btn As Integer, st As Integer btn 0: st 0 Select Case wParam Case WM_LBUTTONDOWN: btn 1: st -1 Case WM_LBUTTONUP: btn 1: st 1 Case WM_RBUTTONDOWN: btn 2: st -1 Case WM_RBUTTONUP: btn 2: st 1 Case WM_MBUTTONDOWN: btn 4: st -1 Case WM_MBUTTONUP: btn 4: st 1 End Select If btn 0 Then Dim px As Long, py As Long GetMousePosition px, py RecordCount RecordCount 1 ReDim Preserve RecordData(1 To RecordCount) RecordData(RecordCount).MouseX px RecordData(RecordCount).MouseY py RecordData(RecordCount).Button btn RecordData(RecordCount).State st End If End If MouseHookProc CallNextHookEx(HookHandle, nCode, wParam, lParam) End Function Public Sub StartHook() HookHandle SetWindowsHookEx(WH_MOUSE_LL, AddressOf MouseHookProc, GetModuleHandle(vbNullString), 0) End Sub Public Sub StopHook() If HookHandle 0 Then UnhookWindowsHookEx HookHandle HookHandle 0 End If End Sub回放时把录制数据按索引读出来按下和抬起相邻且按键一致就合并成单击Public Sub Playback() Dim i As Long i 1 Do While i RecordCount SetMousePosition RecordData(i).MouseX, RecordData(i).MouseY If i RecordCount Then If RecordData(i).Button RecordData(i 1).Button And _ RecordData(i).State -1 And RecordData(i 1).State 1 Then Select Case RecordData(i).Button Case 1: SendMouseKey MouseLeftKey Case 2: SendMouseKey MouseRightKey Case 4: SendMouseKey MouseMiddleKey End Select i i 2 GoTo NextItem End If End If Select Case RecordData(i).State Case -1 Select Case RecordData(i).Button Case 1: SendMouseKey MouseLeftKey_Down Case 2: SendMouseKey MouseRightKey_Down Case 4: SendMouseKey MouseMiddleKey_Down End Select Case 1 Select Case RecordData(i).Button Case 1: SendMouseKey MouseLeftKey_Up Case 2: SendMouseKey MouseRightKey_Up Case 4: SendMouseKey MouseMiddleKey_Up End Select End Select i i 1 NextItem: Sleep 30 Loop End Sub这套代码里MouseButtonData结构体要放在标准模块顶部RecordData用动态数组。回放间隔 30ms 是保守值实际按录制节奏调。如果你要接 TaoToken 做间隔推荐就在Playback前调一次接口把RecordCount和总时长传过去拿回建议的Sleep值。4. 验证请求与成功结果编译运行、点击精度与接口连通性代码写完先别急着接网络本地点击先跑通。VB6 里新建一个标准 EXE把modMouse.bas、modHook.bas加进去窗体上放三个按钮开始录制、停止录制、回放。录制按钮里Recording True: RecordCount 0: StartHook停止按钮里Recording False: StopHook回放按钮里调Playback。编译运行后先测点击精度。在画图工具里画一个点用ClickLoop 500, 400, 100, 10点十次看落点是否都在同一像素。如果偏移检查SetMousePosition是否在SendMouseKey之前调用顺序反了会点到上一个位置。再测录制回放录一段“移动左键单击右键单击”回放时观察是否有多余的半按状态。如果出现“按下不抬起”多半是合并逻辑没命中检查State值是不是 -1 和 1 配对。接口连通性验证用 curl 最直接先确认 Key 和 Base URL 没问题curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-你的Key \ -d { model: 你选的模型ID, messages: [{role: user, content: 返回一个100到200之间的整数}] }成功的话会返回 JSONchoices数组里有内容。如果返回 401说明 Key 不对或没带Bearer如果返回model not found说明 Model ID 填错了。VB6 里调这个接口用MSXML2.XMLHTTP或WinHttp.WinHttpRequest.5.1注意设置setRequestHeader Authorization, Bearer sk-你的Key超时设 15000ms。验证模型对话也可以直接在网页端做打开https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite发一条“你好”能正常回复就说明通道通了。这一步和 VB6 里调是同一套 Key网页通、代码不通基本就是请求头或 JSON 格式问题。点击精度验证还有个土办法把回放速度调慢到 500ms 一次肉眼盯着鼠标走看坐标有没有跳变。跳变通常是GetCursorPos在钩子回调里取到的坐标和实际点击坐标有时差解决办法是在回放时先SetMousePosition再Sleep 10再发点击给系统一点时间同步。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth排错这块按真实报错来别猜。401 Unauthorized。最常见的原因是 Key 没带Bearer前缀或者 Key 复制时带了空格。VB6 里字符串拼接容易多空格用Trim包一下。还有一种情况是 Key 创建后没启用去https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite确认状态。如果 Base URL 写成了https://taotoken.net/api/带尾斜杠某些 HTTP 库会拼出双斜杠导致鉴权失败统一用https://taotoken.net/api。local proxy failed。这个报错通常出现在本机 HTTP 客户端配置了系统代理但代理没起来。VB6 的XMLHTTP默认走系统代理设置如果你本机装过抓包工具代理残留就会报这个。解决办法是在代码里显式设置setProxy 2, 绕过或者去系统设置里关掉代理。注意这里说的是本机代理配置问题不是让你去搞什么网络工具纯粹是开发环境清理。reading choices 相关报错。一般是返回 JSON 解析失败choices字段读不到。原因可能是模型返回了错误结构比如error字段而不是choices。VB6 里解析 JSON 前先判断InStr(responseText, choices) 0没有就打印原始返回。还有一种情况是流式返回没处理stream设成了true但代码按非流式解析把stream去掉或改成false即可。OAuth 相关报错。如果你用的是 Claude Code 这类工具接 TaoToken报 OAuth 错误通常是认证方式选错了。Claude Code 接入要用 API Key 方式Base URL 填https://taotoken.net/apiModel ID 填你选的模型。Claude Code 的接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite里面有完整的环境变量配置。如果你用 CC Switch 或 Cline MCP三件套必须写全Base URL、Key、Model ID缺一个就会报认证失败。还有一个 VB6 特有的坑AddressOf取钩子回调地址时如果回调函数写在窗体模块里编译能过但运行会崩。必须放标准模块。另外SetWindowsHookEx的 hmod 参数用GetModuleHandle(vbNullString)拿当前模块句柄传 0 在部分系统上装不上钩子。6. 把连点器接进统一通道长期维护与扩展建议连点器跑通之后如果你打算长期用建议把配置和代码分开。点击间隔、录制文件路径、TaoToken 的 Base URL 和 Key 都放外部配置文件换机器不用重编译。VB6 读 ini 用GetPrivateProfileString读 json 用ScriptControl的Eval也行但要注意ScriptControl在 64 位系统上要注册 32 位版本。配套服务调用建议做成异步别在点击循环里同步等接口返回。VB6 可以用Timer控件做轮询或者开一个ActiveX EXE做后台。点击主流程只读本地缓存的结果网络断了也不影响点击。如果你后面要扩展成 Agent 式工具比如根据屏幕内容自动决定点哪里那就不是简单连点器了需要接模型做视觉理解。这时候 Coding Plan 更合适https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite。但记住本地鼠标操作和模型调用要分层模型挂了不能把鼠标卡死。最后说个实测经验VB6 的Sleep会阻塞消息循环长时间点击时界面会假死。解决办法是把点击循环放Timer里分批执行每次点一批就DoEvents一下。但DoEvents别滥用录制回放时用多了会丢帧。折中方案是每 50 次点击DoEvents一次既保持响应又不影响精度。代码都在上面了编译环境用 VB6 SP6Windows 10/11 都能跑。钩子部分如果被杀软拦截把编译出的 exe 加白名单这是低级钩子的正常行为不是代码问题。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →