游戏程序的操作不外乎两种——键盘输入控制和鼠标输入控制,几乎所有游戏中都使用鼠标来改变角色的位置和方向,本文主要是讲述如何使用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

C#之鼠标模拟技术的更多相关文章

  1. [转]C# 系统应用之鼠标模拟技术及自动操作鼠标

    原文网址: C# 系统应用之鼠标模拟技术及自动操作鼠标        游戏程序的操作不外乎两种——键盘输入控制和鼠标输入控制,几乎所有游戏中都使用鼠标来改变角色的位置和方向,本文主要是讲述如何使用C# ...

  2. C# 系统应用之鼠标模拟技术及自动操作鼠标

    游戏程序的操作不外乎两种——键盘输入控制和鼠标输入控制,几乎所有游戏中都使用鼠标来改变角色的位置和方向,本文主要是讲述如何使用C#调用Windows API函数实现鼠标模拟操作的功能.首先通过结合Fi ...

  3. C# 调用windows api 操作鼠标、键盘、窗体合集...更新中

    鼠标操作window窗体合集...更新中 1.根据句柄查找窗体 引自http://www.2cto.com/kf/201410/343342.html 使用SPY++工具获取窗体   首先打开spy+ ...

  4. [转]鼠标和键盘模拟API

    几乎所有的游戏中都使用了鼠标来改变角色的位置和方向,玩家仅用一个小小的鼠标,就可以使角色畅游天下. 那么,我们如何实现在没有玩家的参与下角色也可以自动行走呢.其实实现这个并不难,仅仅几个Windows ...

  5. Winserver下的Hyper-v “未在远程桌面会话中捕获到鼠标”

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 服务器相关的知识点:http://www.cnblogs.com/dunitia ...

  6. JS判断鼠标进入容器方向的方法和分析window.open新窗口被拦截的问题

    1.鼠标进入容器方向的判定 判断鼠标从哪个方向进入元素容器是一个经常碰到的问题,如何来判断呢?首先想到的是:获取鼠标的位置,然后经过一大堆的if..else逻辑来确定.这样的做法比较繁琐,下面介绍两种 ...

  7. 自定义鼠标光标cursor

    通过css属性 Cursor:url()自定义鼠标光标. {cursor:url('图标路径'),default;} url是自定义鼠标图标路径 default指的是定义默认的光标(通常是一个箭头), ...

  8. JS鼠标事件大全 推荐收藏

    一般事件 事件 浏览器支持 描述 onClick HTML: 2 | 3 | 3.2 | 4 Browser: IE3 | N2 | O3 鼠标点击事件,多用在某个对象控制的范围内的鼠标点击 onDb ...

  9. CSharpGL(39)GLSL光照示例:鼠标拖动太阳(光源)观察平行光的漫反射和镜面反射效果

    CSharpGL(39)GLSL光照示例:鼠标拖动太阳(光源)观察平行光的漫反射和镜面反射效果 开始 一图抵千言.首先来看鼠标拖动太阳(光源)的情形. 然后是鼠标拖拽旋转模型的情形. 然后我们移动摄像 ...

随机推荐

  1. Red Hat EX413 通过笔记

    最近通过了EX413考试,在这里记录一下- EX413是Red Hat RH413对应的考试,RH413主要涉及Linux主机加固内容.考试大概18题的样子,给两台虚拟机,然后按照各个题目要求进行安全 ...

  2. java 聊天程序

    package cn.apr.chart; import java.net.*; import java.io.*; import java.util.*; public class ChatServ ...

  3. C++高精度

    整理了一下高精度,虽然可用java,但很多时候还是C++写的方便. 附上kuangbin神的高精度模板(HDU1134 求卡特兰数) #include <iostream> #includ ...

  4. git常用命令收集

    [git远程操作命令] 1.$ git remote –v #查看本地配置的所有远程仓库,内容为远程仓库的地址和本地别名 harvey@harvey:~/node$ git remote -v nod ...

  5. 使用DRF视图集时自定义action方法

    在我们用DRF视图集完成了查找全部部门,创建一个新的部门,查找一个部门,修改一个部门,删除一个部门的功能后,views.py的代码是这样子的: class DepartmentViewSet(Mode ...

  6. CSS选择器及其权重

    #转载请留言联系 1.标签选择器 标签选择器,此种选择器影响范围大,一般用来做一些通用设置,或用在层级选择器中.举例: div{color:red} ...... <div>这是第一个di ...

  7. (2)C# 创建ef oracle

    1.NUGet下载 2.下载  Oracle Developer Tools for Visual Studio https://www.oracle.com/technetwork/develope ...

  8. CF 1006B Polycarp's Practice【贪心】

    Polycarp is practicing his problem solving skill. He has a list of n problems with difficulties a1,a ...

  9. AMQ学习笔记 - 08. Spring-JmsTemplate之发送

    概述 JmsTemplate提供了3组*3,共计9个发送用的方法.   发送的方法有3组: 基本的发送 转换并发送 转换.后处理再发送 必需的资源 必需的资源有: javax.jms.Connecti ...

  10. 树状数组优化DP 【模拟赛】删区间

    哇,难受得一匹. 看到题的一瞬间竟然只想到了\(n^3\)的区间\(DP\) 一.\(40pts\) 设\(f[i][j]\)代表删去\(i\)到\(j\)这一段区间的最小代价和. 然后直接写普通的区 ...