1. 简介

玩游戏的时候难免会遇到一些游戏的 "折磨"。例如:我们要使用道具的时候,可这个道具居然没有批量使用!!!

那行吧,我们就来动手做一个按键精灵解放我们的双手。

PS:目前只做了鼠标按键版的,如果有需要键盘的,可以私信或下方留言,后续看需补充吧~

2. 那我们就开始吧~

①. 首先是Win32的框架(这里我就直接套用过来了,不懂可以看下我之前的文章哈~)

//++++++++++++++++++++++++++++++++++
// 宏定义
//----------------------------------
#ifndef UNICODE
#define UNICODE  // 使用UNICODE编码,如果在编译器设置了使用UNICODE字符集此处可免
#endif
#ifndef _UNICODE
#define _UNICODE // 使用UNICODE编码,如果在编译器设置了使用UNICODE字符集此处可免
#endif//++++++++++++++++++++++++++++++++++
// 头文件
//----------------------------------
#include <windows.h>                                    // Win32程序最重要的头文件
#include <tchar.h>                                      // 兼容字符集头文件#include "VibraClick.h"                                 // 鼠标模拟器头文件//++++++++++++++++++++++++++++++++++
// 全局变量
//----------------------------------
TCHAR g_lpszClassName[] = _T("VibraClick");             // 窗口类的名称
TCHAR g_lpszWindowName[] = _T("VibraClick");            // 窗口的名称,(也就是窗口的标题)VibraClick g_vibraClick;                                // 鼠标模拟器//++++++++++++++++++++++++++++++++++
// 函数声明
//----------------------------------
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);   // 窗口消息处理过程
VOID VibraClick_Init(HWND);                         // 初始化软件//++++++++++++++++++++++++++++++++++
// 游戏主函数
//----------------------------------
INT APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, INT nCmdShow)
{/* 1.设计一个窗口类 */.../* 2.注册窗口类 */.../* 3.创建窗口, 并居中显示 */.../* 4.更新显示窗口 */.../* 初始化 */VibraClick_Init(hWnd);/* 5.消息循环 */...return msg.wParam;
}//++++++++++++++++++++++++++++++++++
// 窗口消息处理过程
//----------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{switch (message){case WM_HOTKEY:g_vibraClick.OnHotKey(wParam);break;case WM_DESTROY:// 窗口销毁,释放资源::PostQuitMessage(0);break;default:return ::DefWindowProc(hWnd, message, wParam, lParam);}return ((LRESULT)0);
}VOID VibraClick_Init(HWND hWnd)
{g_vibraClick.Init(hWnd);
}

简单讲解上面内容:

1. 定义了一个按键模拟器类(VibraClick) 的变量 g_vibraClick

2. 初始化这个按键模拟器

3. 由于注册了热键 CTRL + S 和 CTRL + R 进行录制和运行,所以消息处理了WM_HOTKEY

②. VibraClick(按键模拟器类)

VibraClick.h

#pragma once#ifndef __VIBRA_CLICK_H__
#define __VIBRA_CLICK_H__#include <Windows.h>
#include <vector>// 参照 INPUT 类
struct MouseRecInput {DWORD type;MOUSEINPUT mi;
};// 定时器回调
VOID CALLBACK TimerProc(HWND hwnd, UINT message, UINT nIDEvent, DWORD dwTime);
// 鼠标Hook消息处理
LRESULT CALLBACK MouseMessageProc(INT nCode, WPARAM wParam, LPARAM lParam);
class VibraClick
{using MouseRecInputVector = std::vector<MouseRecInput *>;
public:VibraClick();~VibraClick();public:void Init(HWND hWnd);              // 初始化void StartMouseRec();             // 开始录制鼠标操作void StopMouseRec();             // 停止录制鼠标操作void StartRunMouseRec();         // 开始运行鼠标录制的内容void StopRunMouseRec();               // 停止运行鼠标录制的内容void CleanMouseRecInput();            // 清除鼠标记录内容void OnHotKey(WPARAM nHotKeyId);         // 热键处理public:static VibraClick *GetInstance() { return _inst; }bool IsStartMouseRec() { return m_IsStartMouseRec; }bool IsStartRunMouseRec() { return m_IsStartRunMouseRec; }HHOOK GetHHMouseHook() { return m_hhMouseHook; }MouseRecInputVector &GetMouseRecInputVector() { return m_vecMouseRecInput; }int GetMouseRecIndex() { return m_MouseRecIndex; }void SetMouseRecIndex(int value) { m_MouseRecIndex = value; }protected:static VibraClick *_inst;           // 实例自己HWND m_hWnd;                            // 窗口句柄MouseRecInputVector m_vecMouseRecInput;    // 鼠标操作数据bool m_IsStartMouseRec;                    // 是否开始记录鼠标操作bool m_IsStartRunMouseRec;                 // 是否开始鼠标操作int m_MouseRecIndex;                       // 鼠标操作索引UINT_PTR m_RunTimerId;                     // 运行的定时器IdATOM m_VibraClick_StartRec;                // 开始记录热键idATOM m_VibraClick_RunRec;                  // 开始运行记录热键id// 鼠标的HookHHOOK m_hhMouseHook;};#endif // !__VIBRA_CLICK_H__

INPUT 结构体(WinUser.h头文件中)

typedef struct tagINPUT {DWORD   type;union{MOUSEINPUT      mi;KEYBDINPUT      ki;HARDWAREINPUT   hi;} DUMMYUNIONNAME;
} INPUT, *PINPUT, FAR* LPINPUT;

简单讲解上面的内容:

1. MouseRecInput结构体,具体参照 INPUT 结构体。因为MOUSEINPUT是在共用体内,所以对其进行一个扩展

2. TimerProc是一个定时器的处理,用在运行按键模拟的时候

3. MouseMessageProc这个一个鼠标的录制Hook处理

4. 类的方法和成员变量都有对应的注释就不详细说明了哈~(不懂的话在下方留言吧,到时候再进行补充)

VibraClick.cpp


#include "VibraClick.h"
#include <tchar.h>VibraClick *VibraClick::_inst = nullptr;
VibraClick::VibraClick()
{// 初始化一些变量m_IsStartMouseRec = false;m_IsStartRunMouseRec = false;m_MouseRecIndex = 0;m_RunTimerId = -1;m_hhMouseHook = NULL;m_hWnd = NULL;_inst = this;
}VibraClick::~VibraClick()
{// 清除鼠标记录内容CleanMouseRecInput();StopMouseRec();StopRunMouseRec();// 反注册热键UnregisterHotKey(this->m_hWnd, m_VibraClick_StartRec); // Ctrl + SUnregisterHotKey(this->m_hWnd, m_VibraClick_RunRec); // Ctrl + R
}void VibraClick::Init(HWND hWnd)
{m_hWnd = hWnd;m_VibraClick_StartRec = GlobalAddAtom(_T("VibraClick_StartRec")) - 0xC000;m_VibraClick_RunRec = GlobalAddAtom(_T("VibraClick_RunRec")) - 0xC000;RegisterHotKey(this->m_hWnd, m_VibraClick_StartRec, MOD_CONTROL, 'S');   // Ctrl + SRegisterHotKey(this->m_hWnd, m_VibraClick_RunRec, MOD_CONTROL, 'R');   // Ctrl + R
}void VibraClick::StartMouseRec()
{// 清除鼠标记录内容CleanMouseRecInput();// 设置当前为录制鼠标操作状态m_IsStartMouseRec = true;// 开始鼠标Hook(全局鼠标钩子)m_hhMouseHook = SetWindowsHookEx(WH_MOUSE_LL, &MouseMessageProc, GetModuleHandle(NULL), NULL);
}void VibraClick::StopMouseRec()
{// 取消设置当前为录制鼠标操作状态m_IsStartMouseRec = false;// 释放鼠标Hookif (m_hhMouseHook != NULL)UnhookWindowsHookEx(m_hhMouseHook);
}void VibraClick::StartRunMouseRec()
{// 开始模拟鼠标操作m_IsStartRunMouseRec = true;// 设置运行索引m_MouseRecIndex = 0;// 开启定时器m_RunTimerId = SetTimer(m_hWnd, 999, 10, &TimerProc);
}void VibraClick::StopRunMouseRec()
{// 停止运行鼠标记录的内容m_IsStartRunMouseRec = false;// 关闭定时器if (m_RunTimerId != -1){KillTimer(m_hWnd, m_RunTimerId);m_RunTimerId = -1;}
}void VibraClick::CleanMouseRecInput()
{// 清除记录的内容for (auto input : m_vecMouseRecInput){delete input;input = nullptr;}// 释放vector占用内存MouseRecInputVector tmp;m_vecMouseRecInput.swap(tmp);// 设置运行索引m_MouseRecIndex = 0;
}void VibraClick::OnHotKey(WPARAM nHotKeyId)
{if (nHotKeyId == m_VibraClick_StartRec){if (m_IsStartMouseRec)StopMouseRec();elseStartMouseRec();}else if (nHotKeyId == m_VibraClick_RunRec){if (m_IsStartRunMouseRec)StopRunMouseRec();elseStartRunMouseRec();}
}VOID CALLBACK TimerProc(HWND hwnd, UINT message, UINT nIDEvent, DWORD dwTime)
{switch (nIDEvent){case 999:{// 取余方式进行循环运行int MouseRecIndex = VibraClick::GetInstance()->GetMouseRecIndex();MouseRecIndex %= VibraClick::GetInstance()->GetMouseRecInputVector().size();// 读取当前索引的鼠标模拟消息auto pMHD = VibraClick::GetInstance()->GetMouseRecInputVector()[MouseRecIndex++];// 通过INPUT进行模拟操作INPUT Input;Input.type = pMHD->type;memcpy((void *)&Input.mi, (void *)&pMHD->mi, sizeof(MOUSEINPUT));// 发送模拟消息SendInput(1, &Input, sizeof(INPUT));VibraClick::GetInstance()->SetMouseRecIndex(MouseRecIndex);}break;}
}LRESULT CALLBACK MouseMessageProc(INT nCode, WPARAM wParam, LPARAM lParam)
{PMSLLHOOKSTRUCT pStruct = (PMSLLHOOKSTRUCT)lParam;// LLMHF_INJECTED标志着: 事件是否被注入,通过SendInput后会触发这个标志,也就是模拟的处理消息则不记录了// nCode 表示有关Hook的消息/** Hook Codes** #define HC_ACTION           0* #define HC_GETNEXT          1* #define HC_SKIP             2* #define HC_NOREMOVE         3* #define HC_NOREM            HC_NOREMOVE* #define HC_SYSMODALON       4* #define HC_SYSMODALOFF      5*/if (nCode < 0 || pStruct->flags & LLMHF_INJECTED){return CallNextHookEx(VibraClick::GetInstance()->GetHHMouseHook(), nCode, wParam, lParam);}// 是否开启录制鼠标操作if (!VibraClick::GetInstance()->IsStartMouseRec())return CallNextHookEx(VibraClick::GetInstance()->GetHHMouseHook(), nCode, wParam, lParam);// 判断是否为鼠标数据, 当前只是列举一部分的鼠标消息,有需要可以自己加哈~if (wParam == WM_LBUTTONDOWN ||wParam == WM_LBUTTONUP ||wParam == WM_RBUTTONDOWN ||wParam == WM_RBUTTONUP ||wParam == WM_MBUTTONDOWN ||wParam == WM_MBUTTONUP ||wParam == WM_MOUSEMOVE){MouseRecInput *Input = new MouseRecInput;// 现在固定为鼠标的模拟输入Input->type = INPUT_MOUSE;             // 设置输入的数据Input->mi.dx = pStruct->pt.x;Input->mi.dy = pStruct->pt.y;Input->mi.mouseData = pStruct->mouseData;Input->mi.time = pStruct->time;Input->mi.dwExtraInfo = pStruct->dwExtraInfo;switch (wParam){case WM_LBUTTONDOWN:Input->mi.dwFlags = MOUSEEVENTF_LEFTDOWN;break;case WM_LBUTTONUP:Input->mi.dwFlags = MOUSEEVENTF_LEFTUP;break;case WM_RBUTTONDOWN:Input->mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;break;case WM_RBUTTONUP:Input->mi.dwFlags = MOUSEEVENTF_RIGHTUP;break;case WM_MBUTTONDOWN:Input->mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;break;case WM_MBUTTONUP:Input->mi.dwFlags = MOUSEEVENTF_MIDDLEUP;break;case WM_MOUSEMOVE:{int cx_screen = ::GetSystemMetrics(SM_CXSCREEN);int cy_screen = ::GetSystemMetrics(SM_CYSCREEN);Input->mi.dx = pStruct->pt.x * 65536 / cx_screen;Input->mi.dy = pStruct->pt.y * 65536 / cy_screen;Input->mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;}break;}VibraClick::GetInstance()->GetMouseRecInputVector().push_back(Input);}return CallNextHookEx(VibraClick::GetInstance()->GetHHMouseHook(), nCode, wParam, lParam);
}

简单讲解上面的内容:

1. 对静态的_inst进行一个初始化,做这个主要是在Hook和定时器中进行使用到这个按键模拟器

2. 初始化的时候进行保存窗口的句柄,然后进行注册热键和定时器的使用

3. 讲一下这个HOOK的MOUSEMOVE,鼠标点击的x和y坐标需要转换到绝对位置,屏幕的全屏范围是 0~65535,所以需要用当前的电脑分辨率进行转换到绝对的位置

最后PS:这个按键模拟器没有按钮,所以目前只能靠热键进行模拟

分别是:

CTRL + S 开启和关闭录制

CTRL + R 运行模拟

后续有需求可以下方留言,到时候在补充吧~~~

源码:已上传到Github了哦,有兴趣的读者可以去下载了~

Win32软件开发: 按键精灵 鼠标模拟器(VibraClick)相关推荐

  1. java开发按键精灵_Java 按键精灵

    软件介绍 快速开发工具类,用最简洁的命令实现想要的功能.辅助模拟开发. 纯Java,跨平台,模拟按键.鼠标点击.找图.找色,实现简单按键精灵的功能 DEMO演示 辅助开发配套工具:ScreenCapt ...

  2. 脚本录制软件python 按键精灵 tc_键鼠录制工具(KeymouseGo)

    KeymouseGo是一款类似于按键精灵的简洁版鼠标键盘录制程序,由Python编写且全开源.该软件主要用在进行某些操作简单.单调重复的工作时,使用本软件就可以很省力了.自己只要做一遍,然后接下来就让 ...

  3. 定时自动按键软件_[按键精灵手机版教程]QUI界面也可以如此炫酷

    金猪脚本(原飞猪脚本)以按键精灵教学为主,涉及UiBot,Python,Lua等脚本编程语言,教学包括全自动办公脚本,游戏辅助脚本,引流脚本,网页脚本,安卓脚本,IOS脚本,注册脚本,点赞脚本,阅读脚 ...

  4. 脚本录制软件python 按键精灵 tc_用动作脚本的方式介绍如何使用按键精灵的录制功能...

    使用说明:按下热键2,即可启动脚本. 运行环境:分辨率:1024x768 色深:32位 操作系统:Win @vrBrothers.Leo 2006.9//初始化的工作 Dim hWnd Dim ax, ...

  5. 脚本录制软件python 按键精灵 tc_如何使用按键精灵录制脚本

    按键精灵可以代替我们手动完成很多重复的电脑工作,其实用按键精灵写脚本不难,对于新手来说,录制是最简单的,本经验介绍一下如何使用按键精灵录制脚本 工具/原料 按键精灵 方法/步骤 1 首先要安装按键精灵 ...

  6. 脚本录制软件python 按键精灵 tc_使用Python来做一个屏幕录制工具的操作代码

    一.写在前面 作为一名测试,有时候经常会遇到需要录屏记录自己操作,方便后续开发同学定位.以前都是用ScreenToGif来录屏制作成动态图,偶尔的机会看到python也能实现.那就赶紧学习下. 二.效 ...

  7. 脚本录制软件python 按键精灵 tc_《脚》字意思读音、组词解释及笔画数 - 新华字典 - 911查询...

    基本词义 ◎ 脚 脚 jiǎo 〈名〉 (1) (形声.从肉,却声.本义:胫,小腿) (2) 同本义 [shank] 脚,胫也.--<说文> 捶笞膑脚.--<荀子·正论> (3 ...

  8. 脚本录制软件python 按键精灵 tc_从10种脚相看你的财运

    千里之行,始于足下,双脚对我们的重要性不言而喻.在相学中,不仅手相可以算命,我们从脚相也能看出人的富贵吉凶.每个人都希望自己的财运旺盛,能够一生富贵,然而并不是每个人都能有富贵命的.今天我们就通过脚相 ...

  9. php鼠标移动脚本,按键精灵鼠标移动脚本–eq

    如果没有建立好通讯MODEM会返回"BUSY"}一个事件可能有自己的参数,例如,一个Command按钮有一个Click(单击)事件,它没有参数 转义的 html 文本 VB程序也能 ...

  10. 按键精灵入门指引——应用导向学习

    目录 基本方法: 基本的脚本制作方法 应用导向学习 一个应用实例 基本方法: 作为一个小白最初使用的肯定是按键精灵的录制功能.假如你对按键精灵和编程基础知识有了一定的了解,打开脚本查看源代码以后,不难 ...

最新文章

  1. ant table表格整行点击事件并获取当前行的数据
  2. 2022王道操作系统名词解释概念题
  3. 批处理 操作mysql_用批处理对MySQL进行数据操作
  4. php 输出中文的引号,如何将php英文引号转换为中文引号
  5. OJ1077: 字符串加密(C语言)
  6. c语言程序申请管理员权限,vc 软件 要管理员运行 vc 管理员权限运行
  7. libsvm-3.1-[FarutoUltimate3.1Mcode]——辅助函数简介(修改)
  8. Zabbix 4.0升级5.0 ES 6.1升级7.0
  9. 信号的捕捉与sigaction函数
  10. 机器学习---人脸对齐的基于形状模型的训练
  11. 卡拉OK歌词同步播放
  12. vbs中使用select case条件语句,case中匹配项多于一个时,提示:type mismathc/ 800A000D...
  13. 【纯干货】中国的支付清算体系是怎么玩的?
  14. Android源码参考
  15. 滑动窗口协议如何实现流量控制
  16. 2021年山东省职业院校技能大赛中职组”网络安全“正式赛题
  17. POJ 1625 Censored! (AC自动机 + 高精度 + DP)
  18. 360浏览器强制使用极速模式
  19. 【编程题】【Scratch二级】2021.03 寻找宝石
  20. Windows-to-Linux roadmap: Part 2. Console crash course

热门文章

  1. 【转载】财务主管的ERP实施之路
  2. BackgroundWorker DoWork事件调用多次的问题
  3. 使用GAT解析Minidump(图形界面)
  4. Linux系统如何安装oki打印机,涨知识!OKI针式打印机的驱动安装方法
  5. 28万个开源项目之番外篇
  6. 科普写作与专业写作的区别
  7. 怎样将自己学到的东西发布到博客
  8. 将百度万年历存入自己的数据库
  9. Protel 99se汉化步骤
  10. java毕业设计基于javaweb+mysql数据库实现的在线学习网站|在线课堂含论文+开题报告