欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

真就释放双手?C#模拟鼠标操作

程序员文章站 2022-06-17 17:06:39
...

前言

最近玩贪玩蓝月,老是让我呆呆站着领在线礼包?我可能每过几分钟就领一下礼包吗?害,要是有人能帮我一会点一下鼠标就好了… …于是,奇怪的知识又增加了… …

页面设计

真就释放双手?C#模拟鼠标操作

注:因为控件可能有点多,代码中也没有办法标明是哪里,所以又回头把所有控件的名字都标在上面,肝完保存才发现有几个第一个字母只显示了一半,这里补充一下,显示一半的文本框第一个字母是t,单选按钮第一个字母是r,按钮第一个字母是b,因为每个都标上去要耗费很久时间,所以就不再重新制作一遍了,希望理解。(其中button1、button2这些命名格式是反面教材!!!)
界面很简单,一般来说,模拟鼠标操作一般都是给定像素位置,所以起始要先设置一下自己屏幕的分辨率,分辨率不符点击的效果就会出现误差。当然,凭肉眼看要点击的目标点的位置貌似有点扯,但总不能就这点儿需求还需要第三方软件辅助吧?所以右上角就是简单的获取当前鼠标位置,大概如下图:

真就释放双手?C#模拟鼠标操作
然后就是鼠标事件的执行,包括朝指定位置移动阿,朝指定方向移动啊,之类的,还有鼠标的单击,双击,右键,以及滚轮的滑动。然后就是整个程序的“开始”和“停止”了,接下来就看一看代码吧。

代码实现部分

引入模拟鼠事件

具体每个操作对应的行为都在注释里标明了。

        [System.Runtime.InteropServices.DllImport("user32")]
        private static extern int mouse_event(int mouseevent, int dx, int dy, int cButtons, int dwExtraInfo);
        [DllImport("User32")]
        public extern static void SetCursorPos(int x, int y);
        const int MOUSEEVENTF_MOVE = 0x0001;            //移动鼠标 
        const int MOUSEEVENTF_LEFTDOWN = 0x0002;        //模拟鼠标左键按下 
        const int MOUSEEVENTF_LEFTUP = 0x0004;          //模拟鼠标左键抬起 
        const int MOUSEEVENTF_RIGHTDOWN = 0x0008;       //模拟鼠标右键按下 
        const int MOUSEEVENTF_RIGHTUP = 0x0010;         //模拟鼠标右键抬起 
        const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;      //模拟鼠标中键按下 
        const int MOUSEEVENTF_MIDDLEUP = 0x0040;        //模拟鼠标中键抬起 
        const int MOUSEEVENTF_ABSOLUTE = 0x8000;        //标示是否采用绝对坐标 
        const int MOUSEEVENTF_WHEEL = 0x800;            //模拟鼠标滑轮移动

更改分辨率事件

这里默认的是1366786,因为博主的是1366768(分辨率很低了,害),然后就是输入格式正确的话,就对power_X,power_Y分别重新赋值,因为下面移动以及点击都需要用到屏幕的分辨率。

        public int power_X = 1366;                      //分辨率X的值
        public int power_Y = 768;                       //分辨率Y的值
        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                power_X = int.Parse(power_Xtxt.Text);
                power_Y = int.Parse(power_Ytxt.Text);
                MessageBox.Show("分辨率更改成功,若不为默认分辨率,则每次启动均需手动修改,谢谢", "操作成功", MessageBoxButtons.OK);
            }
            catch (Exception eee)
            {
                MessageBox.Show("分辨率未成功修改,请检查输入格式是否正确\n详细错误信息为:"+eee.Message, "错误提示", MessageBoxButtons.OK);
            }
        }

获取鼠标当前位置

有时需要查看目标点的位置,就可以需要使用此功能,下列代码依次为“开始显示”,“停止显示”以及“timer显示事件”。

        private void button5_Click(object sender, EventArgs e)
        {
            timerMousemovement.Enabled = true;                    //开始记录鼠标位置
        }

        private void button6_Click(object sender, EventArgs e)
        {
            timerMousemovement.Enabled = false;                   //停止记录鼠标位置
            nowX.Text = "已结束";
            nowY.Text = "已结束";
        }

        private void timerMousemovement_Tick(object sender, EventArgs e)
        {
            nowX.Text = Cursor.Position.X.ToString();             //记录鼠标指针的详细坐标
            nowY.Text = Cursor.Position.Y.ToString();
        }

设定按钮事件

此功能仅为重新赋予定时器间隔。

        private void button3_Click(object sender, EventArgs e)
        {
            string time = ((double.Parse(Secondtxt.Text) + double.Parse(Minutetxt.Text) * 60) * 1000).ToString();     //设定timer间隔时间
            timer1.Interval = int.Parse(time);
        }

执行定时器事件

此处的定时器分别调用点击方法和移动方法,根据“先执行移动”和“先执行点击”按钮的选中状态来建立点击和移动的先后顺序,注释中也有说明。

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (radiokickfirst.Checked == true)
            {
                buttendown();                          //鼠标点击操作
            }
            mouse_move();                              //鼠标移动操作
            if (radiomovefirst.Checked == true)
            {
                buttendown();
            }
            //如果选择了鼠标点击优先,就执行前两个,点击事件在前,如果选择移动优先,就执行后两个,移动事件在前,达到相应的逻辑关系
        }

鼠标点击方法

根据单选按钮的选中状态执行相关语句,由上到下依次为:左键单击、左键双击、右键单击和滚轮操作,其中前三个都是调用语句即可,滚轮模拟的具体用法注释中也有解释。

        private void buttendown()
        {
            if (radiolifedown.Checked == true)
            {
                mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
            }
            if (radiolifedoubledown.Checked == true)
            {
                mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
                mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
            }
            if (radiorightdown.Checked == true)
            {
                mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
            }
            if (radioRoller.Checked == true)
            {
                try
                {
                    int count = int.Parse(textRoller.Text);
                    mouse_event(MOUSEEVENTF_WHEEL, 0, 0, count, 0);   //控制鼠标滑轮滚动,count代表滚动的值,负数代表向下,正数代表向上,如-100代表向下滚动100的y坐标
                }
                catch (Exception eee)
                {
                    timer1.Enabled = false;
                    MessageBox.Show("引发此异常的原因是您输入的滚轮数值为非法格式\n您可以单击“确定”并检查输入信息后重试\n详细错误信息为:" + eee.Message, "错误提示", MessageBoxButtons.OK);
                }
            }
        }

鼠标移动方法

此处即需要使用开头定义的屏幕分辨率了,从上到下依次为向指定坐标移动和向指定方向移动,其中方向移动从上到下依次为向上、下、左、右移动。

        private void mouse_move()
        {
            try
            {
                if (radioButton1.Checked == true)
                {
                    mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, (int.Parse(textBoxmoveX.Text)) * 65536 / power_X, (int.Parse(textBoxmoveY.Text)) * 65536 / power_Y, 0, 0);
                }
                if (radioButton2.Checked == true)
                {
                    if (checkBoxUP.Checked == true)
                    {
                        int nowX = Cursor.Position.X;                //获取当前坐标的X,Y值
                        int nowY = Cursor.Position.Y;
                        mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, (nowX) * 65536 / power_X, (nowY - int.Parse(textBoxUP.Text)) * 65536 / power_Y, 0, 0);       //根据输入的power_X,power_Y的分辨率值详细移动     
                    }
                    if (checkBoxdown.Checked == true)
                    {
                        int nowX = Cursor.Position.X;
                        int nowY = Cursor.Position.Y;
                        mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, (nowX) * 65536 / power_X, (nowY + int.Parse(textBoxdown.Text)) * 65536 / power_Y, 0, 0);
                    }
                    if (checkBoxlife.Checked == true)
                    {
                        int nowX = Cursor.Position.X;
                        int nowY = Cursor.Position.Y;
                        mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, (nowX - int.Parse(textBoxlife.Text)) * 65536 / power_X, (nowY) * 65536 / power_Y, 0, 0);
                    }
                    if (checkBoxright.Checked == true)
                    {
                        int nowX = Cursor.Position.X;
                        int nowY = Cursor.Position.Y;
                        mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, (nowX + int.Parse(textBoxrigth.Text)) * 65536 / power_X, (nowY) * 65536 / power_Y, 0, 0);
                    }
                }

            }
            catch (Exception eee)
            {
                timer1.Enabled = false;
                MessageBox.Show("引发此异常的原因可能是您输入非法格式,或逻辑选择错误\n您可以单击“确定”并检查输入信息后重试\n详细错误信息为:" + eee.Message, "错误提示", MessageBoxButtons.OK);
            }
        }

开始&结束

开始和结束按钮就是简单的启动定时器和关闭定时器。

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;                //定时器启动
        }

        private void button2_Click(object sender, EventArgs e)
        {
            timer1.Enabled = false;               //定时器关闭
        }

其他逻辑关系

即如果没有勾选移动鼠标时,移动鼠标选项不启用,没有勾选方向移动时,运动方向不启用,诸如此类,是为了避免程序出错。

        private void checkBoxmove_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBoxmove.Checked == true)
            {
                groupmove.Enabled = true;
            }
            else
            {
                groupmove.Enabled = false;
            }
        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton1.Checked == true)
            {
                textBoxmoveX.Enabled = true;
                textBoxmoveY.Enabled = true;
            }
            else
            {
                textBoxmoveX.Enabled = false;
                textBoxmoveY.Enabled = false;
            }
        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButton2.Checked == true)
            {
                groupBoxmovewhere.Enabled = true;
            }
            else
            {
                groupBoxmovewhere.Enabled = false;
            }
        }

        private void radioRoller_CheckedChanged(object sender, EventArgs e)
        {
            if (radioRoller.Checked == true)
            {
                groupBox5.Enabled = true;
            }
            else
            {
                groupBox5.Enabled = false;
            }
        }

结语

模拟鼠标操作的方法有很多种,组合也有很多,这个小例子只是课堂作业基本的小玩意,希望你能喜欢。如果你觉得对你有所帮助就请给我点个赞,关注更好,嘿嘿,谢谢。如有描述错误或不足之处,还望指正。