zoukankan      html  css  js  c++  java
  • C#之鼠标模拟技术

    游戏程序的操作不外乎两种——键盘输入控制和鼠标输入控制,几乎所有游戏中都使用鼠标来改变角色的位置和方向,本文主要是讲述如何使用C#调用Windows API函数实现鼠标模拟操作的功能.首先通过结合FindWindow和FindWindowEx寻找到窗体的按钮,在通过SetCursorPos或mouse_event函数操作鼠标,同时涉及到通过spy++工具获取窗体消息的信息.

    鼠标自动点击按钮和查看鼠标运行轨迹:

    首先创建一个C#工程,设计的窗体如下图所示,同时添加Timer时间器控件:

    然后添加的如下代码,即可实现鼠标模拟技术及自动操作鼠标:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    //引用新命名空间
    using System.Runtime.InteropServices;  //StructLayout
     
    namespace MouseAction
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
     
            //结构体布局 本机位置
            [StructLayout(LayoutKind.Sequential)]
            struct NativeRECT
            {
                public int left;
                public int top;
                public int right;
                public int bottom;
            }
     
            //将枚举作为位域处理
            [Flags]
            enum MouseEventFlag : uint //设置鼠标动作的键值
            {
                Move = 0x0001,               //发生移动
                LeftDown = 0x0002,           //鼠标按下左键
                LeftUp = 0x0004,             //鼠标松开左键
                RightDown = 0x0008,          //鼠标按下右键
                RightUp = 0x0010,            //鼠标松开右键
                MiddleDown = 0x0020,         //鼠标按下中键
                MiddleUp = 0x0040,           //鼠标松开中键
                XDown = 0x0080,
                XUp = 0x0100,
                Wheel = 0x0800,              //鼠标轮被移动
                VirtualDesk = 0x4000,        //虚拟桌面
                Absolute = 0x8000
            }
     
            //设置鼠标位置
            [DllImport("user32.dll")]
            static extern bool SetCursorPos(int X, int Y);
     
            //设置鼠标按键和动作
            [DllImport("user32.dll")]
            static extern void mouse_event(MouseEventFlag flags, int dx, int dy,
                uint data, UIntPtr extraInfo); //UIntPtr指针多句柄类型
     
            [DllImport("user32.dll")]
            static extern IntPtr FindWindow(string strClass, string strWindow);
     
            //该函数获取一个窗口句柄,该窗口雷鸣和窗口名与给定字符串匹配 hwnParent=Null从桌面窗口查找
            [DllImport("user32.dll")]
            static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,
                string strClass, string strWindow);
            
            [DllImport("user32.dll")]
            static extern bool GetWindowRect(HandleRef hwnd, out NativeRECT rect);
     
            //定义变量
            const int AnimationCount = 80;        
            private Point endPosition;           
            private int count;
     
            private void button1_Click(object sender, EventArgs e)
            {
                NativeRECT rect;
                //获取主窗体句柄
                IntPtr ptrTaskbar = FindWindow("WindowsForms10.Window.8.app.0.2bf8098_r11_ad1", null);
                if (ptrTaskbar == IntPtr.Zero)
                {
                    MessageBox.Show("No windows found!");
                    return;
                }
                //获取窗体中"button1"按钮
                IntPtr ptrStartBtn = FindWindowEx(ptrTaskbar, IntPtr.Zero, null, "button1");
                if (ptrStartBtn == IntPtr.Zero)
                {
                    MessageBox.Show("No button found!");
                    return;
                }
                //获取窗体大小
                GetWindowRect(new HandleRef(this, ptrStartBtn), out rect);
                endPosition.X = (rect.left + rect.right) / 2;
                endPosition.Y = (rect.top + rect.bottom) / 2;
                //判断点击按钮
                if (checkBox1.Checked)
                {
                    //选择"查看鼠标运行的轨迹"
                    this.count = AnimationCount;
                    movementTimer.Start();
                }
                else
                {
                    SetCursorPos(endPosition.X, endPosition.Y);
                    mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
                    mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);
                    textBox1.Text = String.Format("{0},{1}", MousePosition.X, MousePosition.Y);
                }
     
            }
     
            //Tick:定时器,每当经过多少时间发生函数
            private void movementTimer_Tick(object sender, EventArgs e)
            {
                int stepx = (endPosition.X - MousePosition.X) / count;
                int stepy = (endPosition.Y - MousePosition.Y) / count;
                count--;
                if (count == 0)
                {
                    movementTimer.Stop();
                    mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
                    mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);
                }
                textBox1.Text = String.Format("{0},{1}", MousePosition.X, MousePosition.Y);
                mouse_event(MouseEventFlag.Move, stepx, stepy, 0, UIntPtr.Zero);
            }
        }
    }
     
    同时自定义一个对话框,增加一个button按钮,其运行结果如下图所示:
    原文地址:http://www.2cto.com/kf/201410/343342.html
  • 相关阅读:
    VMware Tools的安装
    XmlSerializer
    string[][]和string[,] 以及 int[][]和int[,]
    Get Length 使用dynamic关键字
    Cocos2d-x 3.0final 终结者系列教程01-无论是从cocos2d-x2.x升级到版本cocos2d-x3.x
    Hosting WCF Service
    A*算法进入
    OpenCV面、人眼检测
    JAVA学习篇--JAVA两种编程模式控制
    采用Java语言如何实现高速文件复制?
  • 原文地址:https://www.cnblogs.com/milantgh/p/4125080.html
Copyright © 2011-2022 走看看