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);
}
}
}
C#之鼠标模拟技术的更多相关文章
- [转]C# 系统应用之鼠标模拟技术及自动操作鼠标
原文网址: C# 系统应用之鼠标模拟技术及自动操作鼠标 游戏程序的操作不外乎两种——键盘输入控制和鼠标输入控制,几乎所有游戏中都使用鼠标来改变角色的位置和方向,本文主要是讲述如何使用C# ...
- C# 系统应用之鼠标模拟技术及自动操作鼠标
游戏程序的操作不外乎两种——键盘输入控制和鼠标输入控制,几乎所有游戏中都使用鼠标来改变角色的位置和方向,本文主要是讲述如何使用C#调用Windows API函数实现鼠标模拟操作的功能.首先通过结合Fi ...
- C# 调用windows api 操作鼠标、键盘、窗体合集...更新中
鼠标操作window窗体合集...更新中 1.根据句柄查找窗体 引自http://www.2cto.com/kf/201410/343342.html 使用SPY++工具获取窗体 首先打开spy+ ...
- [转]鼠标和键盘模拟API
几乎所有的游戏中都使用了鼠标来改变角色的位置和方向,玩家仅用一个小小的鼠标,就可以使角色畅游天下. 那么,我们如何实现在没有玩家的参与下角色也可以自动行走呢.其实实现这个并不难,仅仅几个Windows ...
- Winserver下的Hyper-v “未在远程桌面会话中捕获到鼠标”
异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 服务器相关的知识点:http://www.cnblogs.com/dunitia ...
- JS判断鼠标进入容器方向的方法和分析window.open新窗口被拦截的问题
1.鼠标进入容器方向的判定 判断鼠标从哪个方向进入元素容器是一个经常碰到的问题,如何来判断呢?首先想到的是:获取鼠标的位置,然后经过一大堆的if..else逻辑来确定.这样的做法比较繁琐,下面介绍两种 ...
- 自定义鼠标光标cursor
通过css属性 Cursor:url()自定义鼠标光标. {cursor:url('图标路径'),default;} url是自定义鼠标图标路径 default指的是定义默认的光标(通常是一个箭头), ...
- JS鼠标事件大全 推荐收藏
一般事件 事件 浏览器支持 描述 onClick HTML: 2 | 3 | 3.2 | 4 Browser: IE3 | N2 | O3 鼠标点击事件,多用在某个对象控制的范围内的鼠标点击 onDb ...
- CSharpGL(39)GLSL光照示例:鼠标拖动太阳(光源)观察平行光的漫反射和镜面反射效果
CSharpGL(39)GLSL光照示例:鼠标拖动太阳(光源)观察平行光的漫反射和镜面反射效果 开始 一图抵千言.首先来看鼠标拖动太阳(光源)的情形. 然后是鼠标拖拽旋转模型的情形. 然后我们移动摄像 ...
随机推荐
- Ubuntu 下nginx 的卸载 与重新装
由于本人把自己服务器的nginx 给玩坏了,不得已选择卸载重新安装,(先让我哭一会) 然后我把/usr/sbin/nginx 和/etc/nginx 和/usr/share/nginx 和 /usr ...
- HDU1083(二分图最大匹配vector实现)
Courses Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total S ...
- 两个kernel.org国内镜像
两个kernel.org国内镜像 https://mirror.tuna.tsinghua.edu.cn/kernel/v4.x/testing/ http://mirror.bjtu.edu.cn/ ...
- 关于easyui checkbox 的一些操作处理
1.easyui在每一行加checkbox { field: 'id', title: '编号', checkbox: true } 2.easyui分页时记住前面已选的checkbox 设置easy ...
- [ Openstack ] Openstack-Mitaka 高可用之 Mariadb-Galera集群部署
目录 Openstack-Mitaka 高可用之 概述 Openstack-Mitaka 高可用之 环境初始化 Openstack-Mitaka 高可用之 Mariadb-Galera集群 ...
- 【Android开发日记】之入门篇(十三)——Android的控件解析
Android的控件都派生自android.view.View类,在android.widget包中定义了大量的系统控件供开发者使用,开发者也可以从View类及其子类中,派生出自定义的控件. 一.An ...
- Selenium2+python自动化37-爬页面源码(page_source)【转载】
前言 有时候通过元素的属性的查找页面上的某个元素,可能不太好找,这时候可以从源码中爬出想要的信息.selenium的page_source方法可以获取到页面源码. selenium的page_sour ...
- java连接Fastdfs图片服务器上传失败的解决方法
照着视频上做,但是却连接不了虚拟机linux上的图片服务器,估计是linux防火墙的问题(这个实在是神烦,前面有好几次连接不了都是因为linux防火墙),果不其然,关闭即可. Linux关闭防火墙的命 ...
- C# 通过串口发送短信
手机短信群发作为企业日常通知,公告,天气预报等信息的一个发布平台,在于成本低,操作方便等诸多特点,成为企业通讯之首选.本文介绍短信的编码方式,AT指令以及用C#实现串口通讯的方法. 前言目前,发送短信 ...
- css :not 选择器
:not 选择器是css3里面的 :not([class]){color:red;} // 没有class属性的元素都设置为红色 p:not([class]){color:red;} // 没有cl ...