WinFrom、C# 学习记录五 开发一个鼠标自动点击小软件

这篇具有很好参考价值的文章主要介绍了WinFrom、C# 学习记录五 开发一个鼠标自动点击小软件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、说明

        经常会被问到需要点击软件的,主要都是玩游戏的盆友,但是也有其它用途的。所以简单弄了一个,打算每当有时间,有需求,就加一些小功能。

        这里主要是要记录一下相关开发工作,也记录一些使用/更新的信息。

二、更新记录

1、版本说明

        【2022/08/22】版本v1.0(初始版本,主要包含间隔点击模式、识别图片点击模式)

2、下载地址

基于winform/c#/opencv实现的windows下使用的自动鼠标点击小软件-桌面系统文档类资源-CSDN下载【2022/08/22】版本v1.0【功能描述】目前实现两种点击模式。间隔模式:一句话描述,更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/bashendixie5/86406516

三、功能描述

1、点击模式

        目前实现两种点击模式(仅支持鼠标左键单击)。

(1)间隔模式

        一句话描述,按设置好的间隔时间鼠标左键单击用户设定的位置。

c#开发小软件,开发语言,winform,c#,windows,桌面软件,鼠标自动点击

(2)图片模式

        一句话描述,用户截图想要识别的图片,上传到软件,然后软件按设置好的间隔时间识别屏幕是否出现了用户上传的图片,如果识别到了,则鼠标左键单击用户设定的位置。

c#开发小软件,开发语言,winform,c#,windows,桌面软件,鼠标自动点击

         后面会增加一些点击模式,比如文字识别,颜色识别等。

2、基础设置

        主要设置

c#开发小软件,开发语言,winform,c#,windows,桌面软件,鼠标自动点击

四、基础源码简述

1、枚举/实体

    internal enum ClickModes
    {
        /// <summary>
        /// 间隔模式
        /// </summary>
        ClickByStep,
        /// <summary>
        /// 根据图片点击
        /// </summary>
        ClickByPictures,
        /// <summary>
        /// 根据文字点击
        /// </summary>
        ClickByText,
        /// <summary>
        /// 根据颜色点击
        /// </summary>
        ClickByColor,
        /// <summary>
        /// 自定义的点击
        /// </summary>
        ClickByCustomize
    }
public enum SettingModes
    {
        NotSettingState,

        /// <summary>
        /// 间隔点击模式的点击位置设置
        /// </summary>
        ClickByStep_PositionOne,

        /// <summary>
        /// 根据图片的点击位置设置
        /// </summary>
        ClickByPictures_PositionOne,

        /// <summary>
        /// 根据文字的点击位置设置
        /// </summary>
        ClickByText_PositionOne,

        /// <summary>
        /// 根据颜色的点击位置设置
        /// </summary>
        ClickByColor_PositionOne,

        /// <summary>
        /// 根据自定义的点击设置
        /// </summary>
        ClickByCustomize_PositionOne,
        ClickByCustomize_PositionTwo,
        ClickByCustomize_PositionThree,
        ClickByCustomize_PositionFour,
        ClickByCustomize_PositionFive,
        ClickByCustomize_PositionSix,
    }

2、windows api

internal class Win32Api
    {
        [StructLayout(LayoutKind.Sequential)]
        public class POINT
        {
            public int x;
            public int y;
        }
        [StructLayout(LayoutKind.Sequential)]
        public class MouseHookStruct
        {
            public POINT pt;
            public int hwnd;
            public int wHitTestCode;
            public int dwExtraInfo;
        }
        public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
        //安装钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
        //卸载钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);
        //调用下一个钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("User32")]
        public extern static void SetCursorPos(int x, int y);

        //定义快捷键
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifiers fsModifiers, int vk);

        [Flags()]
        public enum KeyModifiers
        {
            None = 0,
            Alt = 1,
            Ctrl = 2,
            Shift = 4,
            WindowsKey = 8
        }

        /// <summary>
        /// 取消注册热键
        /// </summary>
        /// <param name="hWnd">要取消热键的窗口的句柄</param>
        /// <param name="id">要取消热键的ID</param>
        /// <returns></returns>
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        /// <summary>
        /// 向全局原子表添加一个字符串,并返回这个字符串的唯一标识符,成功则返回值为新创建的原子ID,失败返回0
        /// </summary>
        /// <param name="lpString"></param>
        /// <returns></returns>
        [DllImport("kernel32", SetLastError = true)]
        public static extern short GlobalAddAtom(string lpString);
        /// <summary>
        /// 热键的对应的消息ID
        /// </summary>
        public const int WM_HOTKEY = 0x312;


        [DllImport("kernel32", SetLastError = true)]
        public static extern short GlobalDeleteAtom(short nAtom);

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int mouse_event(int dwflags, int dx, int dy, int cbuttons, int dwextrainfo);

        public const int mouseeventf_move = 0x0001;      //移动鼠标
        public const int mouseeventf_leftdown = 0x0002; //模拟鼠标左键按下
        public const int mouseeventf_leftup = 0x0004; //模拟鼠标左键抬起
        public const int mouseeventf_rightdown = 0x0008; //模拟鼠标右键按下
        public const int mouseeventf_rightup = 0x0010; //模拟鼠标右键抬起
        public const int mouseeventf_middledown = 0x0020; //模拟鼠标中键按下
        public const int mouseeventf_middleup = 0x0040; //模拟鼠标中键抬起
        public const int mouseeventf_absolute = 0x8000; //标示是否采用绝对坐标

    }

3、定时器

timer = new System.Timers.Timer();
timer.Enabled = true;
timer.Interval = settingModel.intervals;    //执行间隔时间,单位为毫秒
timer.Elapsed += new System.Timers.ElapsedEventHandler(myTimedTask);

4、快捷键

 int f1 = Win32Api.GlobalAddAtom("F1");
 int f5 = Win32Api.GlobalAddAtom("F5");
 int f6 = Win32Api.GlobalAddAtom("F6");
Win32Api.RegisterHotKey(this.Handle, f1, Win32Api.KeyModifiers.None, (int)Keys.F1);
Win32Api.RegisterHotKey(this.Handle, f5, Win32Api.KeyModifiers.None, (int)Keys.F5);
Win32Api.RegisterHotKey(this.Handle, f6, Win32Api.KeyModifiers.None, (int)Keys.F6);
/// <summary>
        /// 监视Windows消息
        /// </summary>
        /// <param name="m"></param>
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case Win32Api.WM_HOTKEY:
                    ProcessHotkey(m);//按下热键时调用ProcessHotkey()函数
                    break;
            }
            base.WndProc(ref m); //将系统消息传递自父类的WndProc
        }

        /// <summary>
        /// 按下设定的键时调用该函数
        /// </summary>
        /// <param name="m"></param>
        private void ProcessHotkey(Message m)
        {
            IntPtr id = m.WParam;//IntPtr用于表示指针或句柄的平台特定类型
            int sid = id.ToInt32();
            if (sid == f1)
            {
                //do something
            }
            else if (sid == f5)
            {
                //do something
            }
            else if (sid == f6)
            {
                //do something
            }
        }

5、鼠标单击

        /// <summary>
        /// 单击
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public static void SingleClick(int x, int y)
        {
            //鼠标移动
            Win32Api.SetCursorPos(x, y);

            //鼠标点击
            Win32Api.mouse_event(Win32Api.mouseeventf_leftdown, x, y, 0, 0);
            Win32Api.mouse_event(Win32Api.mouseeventf_leftup, x, y, 0, 0);
        }

五、不同模式代码简述

1、开始监控

        监控开始的时候,首先检查是否正确设置了点击位置,然后开始定时器。

        switch (clickModes)
        {
                //间隔模式
                case ClickModes.ClickByStep:
                    int x1, y1;
                    if (!this.control0.ClickPositionFlag(out x1, out y1))
                    {
                        MessageBox.Show("请检查鼠标点击位置设置是否正确。");
                        return;
                    }
                    break;
                //图片模式
                case ClickModes.ClickByPictures:
                    if(this.control1.mat == null)
                    {
                        MessageBox.Show("请选择待匹配图片。");
                        return;
                    }
                    break;
            }

            this.BackColor = Color.AliceBlue;
            this.startFlag = true;
            this.timer.Start();

2、定时任务的代码 

    public void myTimedTask(object sender, System.Timers.ElapsedEventArgs e)
    {
            if (startFlag)
            {
                switch (this.clickModes)
                {
                    //间隔模式
                    case ClickModes.ClickByStep:
                        int x0, y0;
                        if (this.control0.ClickPositionFlag(out x0, out y0))
                        {
                            HelpTools.SingleClick(x0, y0);
                        }
                        break;
                    //图片模式
                    case ClickModes.ClickByPictures:
                        int x2, y2;
                        //检查是否再屏幕内匹配到用户上传的图片
                        if(this.GetShouldClickFlagByPictures(out x2, out y2))
                        {
                            int x1, y1;
                            //如果用户设置了点击位置,则点击设置的位置
                            if(this.control1.ClickPositionFlag(out x1, out y1))
                            {
                                HelpTools.SingleClick(x1, y1);
                            }
                            //如果用户没有设置点击位置,则点击图片中心
                            else
                            {
                                HelpTools.SingleClick(x2, y2);
                            }
                        }
                        break;
                    case ClickModes.ClickByText:

                        break;
                    case ClickModes.ClickByColor:

                        break;
                    case ClickModes.ClickByCustomize:

                        break;

                    default:
                        break;
                }
                
                // 用于统计点击的次数
                runtimes++;
                // 如果是点击固定次数,则点击次数达到了的时候,停止运行
                if(settingModel!=null && settingModel.fixedFlag && runtimes>= settingModel.clickNums)
                {
                    this.Invoke(new Action(() =>this.button5_Click(null, null)));
                }    
            }
        }

3、图片识别

        首先全屏截图,然后从全屏截图中使用用户上传的图片进行模板匹配,找到匹配的区域之后再将该区域抠出来和用户上传的图片进行一次结构相似性的比较(故此说这里未必次次都能正确找到,但是一般辨识度高的图片问题不太大)。文章来源地址https://www.toymoban.com/news/detail-604954.html

        /// <summary>
        /// 判断图片模式是否需要点击
        /// </summary>
        /// <returns></returns>
        public bool GetShouldClickFlagByPictures(out int x1, out int y1)
        {
            //全屏截图
            int width = Screen.PrimaryScreen.Bounds.Width;
            int height = Screen.PrimaryScreen.Bounds.Height;
            Rectangle smallRect = new Rectangle(0, 0, width, height);
            Rectangle tScreenRect = new Rectangle(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
            Bitmap tSrcBmp = new Bitmap(width, height); // 用于屏幕原始图片保存
            Graphics gp = Graphics.FromImage(tSrcBmp);
            gp.CopyFromScreen(0, 0, 0, 0, smallRect.Size);
            gp.DrawImage(tSrcBmp, 0, 0, smallRect, GraphicsUnit.Pixel);

            //全屏截图转mat
            Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(tSrcBmp);
            Cv2.CvtColor(mat, mat, ColorConversionCodes.BGRA2BGR);
            
            //从全屏截图查找待匹配图像
            Mat out1 = new Mat();
            Cv2.MatchTemplate(mat, this.control1.mat, out1, TemplateMatchModes.CCoeffNormed);
            
            //寻找匹配到的最大最小值
            double minVal, maxVal;
            OpenCvSharp.Point minLoc, maxLoc;
            Cv2.MinMaxLoc(out1, out minVal, out maxVal, out minLoc, out maxLoc, null);
            //Cv2.Rectangle(mat, maxLoc, new OpenCvSharp.Point(maxLoc.X + this.control1.mat.Width, maxLoc.Y + this.control1.mat.Height), 255, 2);

            //获取匹配到的部分图像
            Mat child = new Mat(mat, new OpenCvSharp.Rect(maxLoc.X, maxLoc.Y, this.control1.mat.Width, this.control1.mat.Height));

            x1 = maxLoc.X + this.control1.mat.Width / 2;
            y1 = maxLoc.Y + this.control1.mat.Height / 2;

            //比较匹配到的和原图的相似度
            double ssim = ImagesTools.Compare_SSIM(child.Clone(), this.control1.mat.Clone());
            Console.WriteLine("相似性:" + ssim);
            if (ssim > 0.9)
            {
                return true;
            }

            System.GC.Collect();
            return false;
        }

到了这里,关于WinFrom、C# 学习记录五 开发一个鼠标自动点击小软件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • QT`实现鼠标超时未点击,窗口自动关闭

    QT 实现鼠标超时未点击,窗口自动关闭 前言 有的时候我们需要某些窗口实现超时自动关闭,但是Qt窗口一般是多部件堆叠而成,如果常规处理,对每一个部件进行鼠标点击事件处理显然不太合理,我个人参考了网上前辈的处理方法,通过直接重新实现 QApplication::notify 函数来

    2024年02月10日
    浏览(12)
  • 【Python】实现一个鼠标连击器,每秒点击1000次

    【Python】实现一个鼠标连击器,每秒点击1000次

    鼠标连击是指在很短的时间内多次点击鼠标按钮,通常是鼠标左键。当触发鼠标连击时,鼠标按钮会迅速按下和释放多次,产生连续的点击效果。 在这里鼠标连击的主要用途是: 帮助我们进行鼠标点击,疯狂连击; 例如在射击游戏中连续开火,如果点击就可以攻击怪物,那

    2024年02月12日
    浏览(11)
  • Unity学习笔记--使用 C# 开发一个 LRU

    什么是 LRU 在计算机系统中,LRU(Least Recently Used,最近最少使用)是一种缓存置换算法。缓存是计算机系统中的一种能够高速获取数据的介质,而缓存置换算法则是在缓存空间不足时,需要淘汰掉部分缓存数据以腾出空间,使得后来需要访问数据能够有更多的缓存空间可用。

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

    C# 实现按键精灵 记录录制键盘鼠标

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

    2024年02月11日
    浏览(15)
  • C# 给winfrom窗体添加皮肤控件

    C# 给winfrom窗体添加皮肤控件

    如何快速给C# winform添加好看的皮肤C# Winform中窗体的美化 SkinEngine的应用 皮肤控件换肤素材包,IrisSkin2.dll皮肤素材资源下载  压缩包内一共有22种皮肤素材,使用说明:把控件拖到你的form上,只需一行代码,即可实现整个form包括其所有控件的皮肤的更换,  总共有几十套皮肤

    2024年02月05日
    浏览(12)
  • C# Winfrom将DataGridView数据导入Excel

    C# Winfrom将DataGridView数据导入Excel

      1.项目添加Word和Excel的COM类型库引用 2.创建Excel工作表 3.设置Excel表格的标题 4.加载数据进入Excel表格 5.显示和释放工作簿对象 6.补充         一:                 在前面老是用到Microsoft.Office.Interop.Excel这个命名空间,可以给它起个别名方便书写                 例

    2024年02月16日
    浏览(12)
  • C#之Winfrom自定义输入框对话框。

    在你的程序中,在需要触发输入框的地方添加一个按钮或其他事件处理器。例如,你可以在按钮点击事件中执行相应的代码和逻辑。 通过以上步骤,你可以在 WinForms 程序中创建一个带有输入框的自定义窗体,并在点击确定按钮后获取用户输入的值。确保根据实际需求修改输

    2024年02月14日
    浏览(12)
  • 基于C#制作一个鼠标连点器

    基于C#制作一个鼠标连点器

    秒杀抢券、压枪换弹都是网上冲浪的基本操作,制作一个鼠标连点器,从此在互联网所向披靡。 打开Visual Studio,右侧选择创建新项目。

    2024年02月08日
    浏览(5)
  • C# Winfrom实例:武汉智能安检闸机数据接收和解析

    C# Winfrom实例:武汉智能安检闸机数据接收和解析

    项目介绍: 本实例主要是接收安检闸机的数据解析并显示到界面上,只做功能实现,不做界面美化 硬件:闸机一个、网线一根、电脑主机 开发环境:vs2017 系统:win10 涵盖知识点:tcp通讯、文件写入、多线程,委托、类型转换等 软件操作流程: 点击开始监听按钮,8999要是未

    2024年02月19日
    浏览(11)
  • OpenCV学习(三)——响应鼠标事件(获取点击点坐标和颜色,利用鼠标进行绘图)

    OpenCV学习(三)——响应鼠标事件(获取点击点坐标和颜色,利用鼠标进行绘图)

    使用OpenCV读取图像,可以在读取图像的窗口通过鼠标点击可以实现:获取鼠标点击像素点的坐标、获取鼠标点击像素点的颜色和在鼠标点击的像素点生成圆等等。 winname:窗口的名字 callback:回调函数 userdata:给回调函数的参数 enent:鼠标事件 x:横坐标 y:纵坐标 flags:事件

    2024年02月08日
    浏览(112)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包