12.3 实现模拟鼠标录制回放

这篇具有很好参考价值的文章主要介绍了12.3 实现模拟鼠标录制回放。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本节将向读者介绍如何使用键盘鼠标操控模拟技术,键盘鼠标操控模拟技术是一种非常实用的技术,可以自动化执行一些重复性的任务,提高工作效率,在Windows系统下,通过使用各种键盘鼠标控制函数实现动态捕捉和模拟特定功能的操作。

有时我们经常需要进行重复性的鼠标操作,例如繁琐的点击、拖拽。这些任务可能消耗大量时间和精力,为了解决这个问题,可自行设计并实现一个简单而强大的鼠标录制回放工具,旨在帮助用户轻松录制鼠标动作,通过借助鼠标录制回放工具,用户可以轻松实现自动化操作,从而解放双手。

首先我们需要创建一个Write_File函数,当用户每次调用该函数时都会向特定的文件内追加写入一条记录,此外还需要增加一个split函数,该函数用于将特定的一条记录根据特定的分隔符切割,保留分隔符后面的坐标信息。

// 切割字符串
int split(char dst[][32], char* str, const char* spl)
{
    int n = 0;
    char* result = NULL;
    result = strtok(str, spl);
    while (result != NULL)
    {
        strcpy(dst[n++], result);
        result = strtok(NULL, spl);
    }
    return n;
}

// 每次写入一行
int Write_File(char* path, char* msg)
{
    FILE* fp = fopen(path, "a+");
    if (fp == NULL) return -1;

    char ch, buffer[1024];

    int index = 0;
    while (msg[index] != '\0')
    {
        fputc(msg[index], fp);
        index++;
    }
    fclose(fp);
    return 1;
}

接着我们需要实现Recording()函数部分,该函数的左右是用于捕捉当前鼠标坐标与点击事件,函数中通过调用GetCursorPos()获取当前鼠标的屏幕坐标位置,这个函数参数传递非常简单,只需要传入一个POINT类型的结构体变量,其函数原型如下所示;

BOOL GetCursorPos(LPPOINT lpPoint);

参数:

  • lpPoint:指向 POINT 结构的指针,用于接收鼠标的屏幕坐标位置。

返回值:

  • 如果函数成功,返回值为非零,表示获取鼠标位置成功;
  • 如果函数失败,返回值为零,表示获取鼠标位置失败。

POINT 结构包含了两个成员变量 xy,分别表示鼠标在屏幕上的横坐标和纵坐标。

当有了当前鼠标坐标位置以后,接着就是需要获取到鼠标点击事件,鼠标点击可使用GetAsyncKeyState 获取指定虚拟键码对应的键盘键的状态,该函数原型如下所示;

SHORT GetAsyncKeyState(int vKey);

参数:

  • vKey:指定虚拟键码,它是一个整数,表示要获取的键的键码。

返回值:

  • 如果指定的虚拟键处于按下状态,返回值的最高位(符号位)为 1,其余位表示次数(持续时间)。如果指定的虚拟键处于释放状态或者参数无效,返回值为 0。

GetAsyncKeyState 函数允许检测键盘中某个虚拟键的状态,无论这个虚拟键是否处于焦点的窗口中。它适用于各种应用,通过VK_LBUTTON可用于检测鼠标左键是否被按下,通过VK_RBUTTON则可用于检测鼠标右键状态。

代码的主要功能如下:

  1. Recording 函数中,使用一个死循环不断检测鼠标的位置和按键状态。
  2. 使用 GetCursorPos 函数获取当前鼠标的位置,并将其保存在 xy 变量中。
  3. 使用 GetAsyncKeyState 函数检测鼠标左键和右键的状态,并将其保存在 lbuttonrbutton 变量中。
  4. 如果当前的鼠标位置或按键状态与之前保存的值不同,表示鼠标动作发生了变化,将当前的位置和按键状态记录下来。
  5. 将记录的鼠标动作信息以字符串的形式写入脚本文件,格式为 "X:位置,Y:位置,L:左键状态,R:右键状态"。
  6. 保存当前的鼠标位置和按键状态,用于下一次循环时比较是否发生了变化。
// 录制脚本
void Recording(char *script)
{
    int static_x = 0, static_y = 0;
    bool static_lbutton = 0, static_rbutton = 0;

    while (1)
    {
        POINT Position;
        GetCursorPos(&Position);

        int x = Position.x;
        int y = Position.y;
        bool lbutton = GetAsyncKeyState(VK_LBUTTON);
        bool rbutton = GetAsyncKeyState(VK_RBUTTON);

        if (x != static_x || y != static_y || lbutton != static_lbutton || rbutton != static_rbutton)
        {
            char szBuf[1024] = { 0 };
            std::cout << "X轴 = " << x << " Y轴 = " << y << " 鼠标左键 = " << lbutton << " 鼠标右键 = " << rbutton << std::endl;

            sprintf(szBuf, "X:%d,Y:%d,L:%d,R:%d\n", x, y, lbutton, rbutton);
            Write_File((char*)script, szBuf);

            static_x = x;
            static_y = y;
            static_lbutton = lbutton;
            static_rbutton = rbutton;
        }
    }
}

接着我们继续封装Play()回放功能,该功能的实现原理与录制保持一致,通过逐条读取传入文件中的参数,并调用SetCursorPos实现鼠标位置的移动操作,该函数与获取参数传递保持一致,这里我们需要注意mouse_event函数,该函数用于模拟鼠标的各种事件,如鼠标移动、鼠标按键的点击和释放等,其函数原型如下所示;

void mouse_event(DWORD dwFlags, DWORD dx, DWORD dy, DWORD dwData, ULONG_PTR dwExtraInfo);

其中dwFlags指定要模拟的鼠标事件类型和选项。可以是以下常量的组合;

  • MOUSEEVENTF_ABSOLUTE:指定鼠标位置是绝对坐标。如果不设置此标志,则坐标是相对于当前鼠标位置的增量。
  • MOUSEEVENTF_MOVE:模拟鼠标移动事件。
  • MOUSEEVENTF_LEFTDOWN:模拟鼠标左键按下事件。
  • MOUSEEVENTF_LEFTUP:模拟鼠标左键释放事件。
  • MOUSEEVENTF_RIGHTDOWN:模拟鼠标右键按下事件。
  • MOUSEEVENTF_RIGHTUP:模拟鼠标右键释放事件。

其他常量可根据需要自行查阅相关文档。

  • dx:鼠标事件发生时的横坐标(绝对坐标或增量坐标,根据 dwFlags 决定)。
  • dy:鼠标事件发生时的纵坐标(绝对坐标或增量坐标,根据 dwFlags 决定)。
  • dwData:鼠标事件的一些数据。对于滚轮事件,它表示滚动的数量。对于其他事件,通常设为 0。
  • dwExtraInfo:额外的信息。通常设为 0。

mouse_event 函数允许模拟鼠标事件,通过设置 dwFlags 参数来指定需要模拟的事件类型,设置 dxdy 参数来指定事件发生时的鼠标位置。通过调用这个函数,可以实现自动化鼠标操作,如模拟鼠标点击、拖动等。

如下代码段实现了鼠标动作脚本的回放功能,它从之前录制保存的脚本文件中读取鼠标动作信息,并按照脚本中记录的顺序模拟鼠标动作,实现鼠标动作的回放。

代码的主要功能如下:

  1. Play 函数中,打开之前保存的脚本文件,并使用 fgets 函数每次读取一行数据,保存在 buf 字符数组中。
  2. 使用 split 函数切割每行数据,将每行数据切割成以逗号分隔的四个字符串,并将这四个字符串转换为整数类型保存在 key_item 数组中。
  3. 根据 key_item 数组中的数据,判断是否需要进行鼠标点击动作,并调用 mouse_event 函数模拟鼠标点击。
  4. 调用 SetCursorPos 函数设置鼠标的位置,并使用 Sleep 函数模拟鼠标移动的延时,实现鼠标动作的回放。
  5. 循环执行以上步骤,直到脚本文件中的所有动作都被回放完毕。
// 回放脚本
void Play(char *script)
{
    FILE* fp = fopen(script, "r");
    char buf[1024];

    while (feof(fp) == 0)
    {
        // 每次读入一行
        memset(buf, 0, 1024);
        fgets(buf, 1024, fp);

        // 以逗号切割
        char split_comma[4][32] = { 0 };
        int comma_count = split(split_comma, buf, ",");

        int key_item[4] = { 0 };

        // std::cout << "长度: " << comma_count << std::endl;
        for (int x = 0; x < comma_count; x++)
        {
            // 继续切割冒号
            char split_colon[2][32] = { 0 };
            split(split_colon, split_comma[x], ":");

            // std::cout << "字典键 = " << split_colon[0] << " 字典值 = " << split_colon[1] << std::endl;
            key_item[x] = atoi(split_colon[1]);
        }

        if (key_item[3] != 0)
        {
            mouse_event(MOUSEEVENTF_LEFTUP | MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
        }
        if (key_item[4] != 0)
        {
            mouse_event(MOUSEEVENTF_RIGHTUP | MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
        }

        // 得到数据后开始回放
        SetCursorPos(key_item[0], key_item[1]);
        Sleep(70);
    }
}

最后是主函数部分,我们通过RegisterHotKey函数注册两个全局热键,通过F1实现鼠标录制部分,通过F2则实现鼠标回放,最后通过GetMessage函数接收全局消息事件,当出现WM_HOTKEY消息则依次判断是否启用录制回放等功能,代码如下所示;

int main(int argc, char* argv[])
{
    // 注册热键 F1 , F2
    if (0 == RegisterHotKey(NULL, 1,0, VK_F1))
    {
        cout << GetLastError() << endl;
    }
    if (0 == RegisterHotKey(NULL, 2,0, VK_F2))
    {
        cout << GetLastError() << endl;
    }
    if (0 == RegisterHotKey(NULL, 3, 0, VK_F3))
    {
        cout << GetLastError() << endl;
    }

    // 消息循环
    MSG msg = { 0 };

    while (GetMessage(&msg, NULL, 0, 0))
    {
        switch (msg.message)
        {
        case WM_HOTKEY:
        {
            if (1 == msg.wParam)
            {
                std::cout << "录制脚本" << std::endl;
                Recording((char *)"d://script.txt");
            }

            else if (2 == msg.wParam)
            {
                std::cout << "回放脚本" << std::endl;
                Play((char *)"d://script.txt");
            }

            else if (3 == msg.wParam)
            {
                exit(0);
                return 0;
            }

            break;
        }
        default:
            break;
        }
    }
    return 0;
}

读者可自行编译并运行这段代码,通过录制一段鼠标功能并回放,输出效果图如下所示;

12.3 实现模拟鼠标录制回放文章来源地址https://www.toymoban.com/news/detail-710527.html

到了这里,关于12.3 实现模拟鼠标录制回放的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android12 部分应用(客户大型游戏)使用鼠标点击无效,鼠标模拟触摸点击

            如标题,在某些较大的游戏应用中,会限制鼠标点击不生效,导致我们的鼠标在系统其他应用上都能使用,就是某个游戏应用无法点击。调试发现,触摸事件不受影响,那么我们可以在当前游戏应用中,点击的时候模拟一下触摸点击,查看是否生效。安卓有一个触摸

    2024年02月02日
    浏览(49)
  • C# 实现按键精灵 记录录制键盘鼠标

     是一个非常实用的键盘鼠标脚本录制工具,通过它你可以轻松地进行脚本录制,简单易用,不需要任何编程知识就能做出功能强大的脚本,只要你在电脑前用双手可以完成的动作,都可以替你完成。                下载软件 1.运行录制脚步时模拟过程 比按键精灵 更加流畅

    2024年02月11日
    浏览(40)
  • 微信小程序自动化测试实战,支持录制回放、智能遍历

      ​为了满足小程序性能、功能等方面的测试需求,微信团队上线 小程序云测服务 ,提供丰富的自动化测试能力。其中 智能化 Monkey 服务 凭借着零代码、低成本的优势吸引不少开发者使用。 在服务使用过程中,我们发现开发者有更多的进阶需求: 先完成指定操作,例如登

    2024年02月03日
    浏览(49)
  • 12.3用信号量进行线程同步——生产者与消费者问题

    1.shell程序设计 2.内存管理 3.链接库 4.文件操作

    2024年02月04日
    浏览(41)
  • GaussDB技术解读系列:5分钟带您了解DRS录制回放

    DRS录制回放是将源数据库发生的真实业务流量,在目标数据库模拟执行,从而观察和检验目标数据库的功能和性能表现。录制回放主要分为录制、回放两个阶段,录制过程是从源数据库上将所需时间段内的全部SQL原语句(包括增、删、改、查)通过审计日志下载、录制代理等

    2024年01月18日
    浏览(37)
  • Selenium 自动化 —— Selenium IDE录制、回放、导出Java源码

    之前我们在专栏的第一篇文章中演示了使用使用Selenium进行百度搜索的Hello world示例。 代码不复杂非常简单: 但是对不懂HTML、CSS和Selenium API的同学,可能要编写一个完整的可运行的Selenium程序还是有一点点难度。 熟悉CSS和花了一点的时间看了我后续Selenium 系列教程的除外哈。

    2024年03月22日
    浏览(43)
  • IMX477-160 12.3MP Camera在jetson nano上配置调用

      要在Jetson Nano上使用IMX477-160 12.3MP相机,您需要执行以下步骤: 将相机连接到Jetson Nano的CSI接口。确保连接正确,电源也已连接。  确保您的Jetson Nano系统已更新到最新版本。您可以使用以下命令检查并更新系统:      3. 安装适当的驱动程序和软件包。要使用IMX477-160相机

    2024年02月15日
    浏览(64)
  • 【涨薪技术】0到1学会性能测试 —— LR录制回放&事务&检查点

    上一次推文我们分享了性能测试分类和应用领域,今天带大家学习性能测试工作原理、事务、检查点!后续文章都会系统分享干货,带大家从0到1学会性能测试,另外还有教程等同步资料,文末免费获取~ ​通常我们认为LoadRunner是由三部分组成:VuGen、Controller、Analysis VuGen:录

    2024年02月05日
    浏览(52)
  • Ubuntu22.04 LTS + CUDA12.3 + CUDNN8.9.7 + PyTorch2.1.1

    本文记录Ubuntu22.04长期支持版系统下的CUDA驱动和cuDNN神经网络加速库的安装,并安装PyTorch2.1.1来测试是否安装成功。 如果是旧的不支持UEFI启动的主板,请参考本人博客U盘系统盘制作与系统安装(详细图解) 如果是新的支持UEFI启动的主板,请参考本人博客UEFI下Windows10和Ubun

    2024年02月03日
    浏览(44)
  • C#实现键盘鼠标模拟器

    下面程序可指定一连串重复动作,按顺序执行   using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Text.RegularExpressions; using System.Windows.Forms; namespace Simulator {     public partial class Form1 : Form     {         [System.Runtime.InteropServices.DllImp

    2024年02月16日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包