C# SendInput 模拟鼠标操作的实现方法
C# SendInput 模拟鼠标操作的实现方法
发布时间:2016-12-28 来源:查字典编辑
摘要:刚刚开始学习C#,想自己做一个网页游戏的挂。游戏里面有收钱的动作,一个建筑物一个建筑物的点,很累啊。于是想用C#模拟鼠标操作替我收钱,想着学...

刚刚开始学习C#,想自己做一个网页游戏的挂。游戏里面有收钱的动作,一个建筑物一个建筑物的点,很累啊。于是想用C#模拟鼠标操作替我收钱,想着学习这个对以后的测试工作也有帮助,于是有了动力。学习过程也是曲折的,因为网上搜了半天资料很少。该游戏是Flash的,用sendmessage不行,因为取不到里面的对象。查到有些介绍Mouse_Event的文章,但是msdn上说已经过时。于是查到了SendInput函数。

废话少说,上代码:

首先看下 Win API 中SendInput函数描述:

复制代码 代码如下:

UINT WINAPI SendInput(

__in UINT nInputs,

__in LPINPUT pInputs,

__in int cbSize

);

对应的C#代码:

复制代码 代码如下:

[DllImport("user32.dll")]

public static extern UInt32 SendInput(UInt32 nInputs,Input[] pInputs, int cbSize);

其中参数pInputs是的数组类型,数组元素INPUT结构,所以我们下面还要在C#中定义对应的INPUT结构或者对象。INPUT结构中主要是定义你需要的鼠标或者键盘等操作。nInputs指明pInputs数组长度。cbSize指明INPUT结构的大小。

定义INPUT结构,下面是Win API 中INPUT结构描述:

复制代码 代码如下:

typedef struct tagINPUT {

DWORD type;

union {

MOUSEINPUT mi;

KEYBDINPUT ki;

HARDWAREINPUT hi;

} ;

} INPUT, *PINPUT;

对应的C#代码

复制代码 代码如下:

[StructLayout(LayoutKind.Explicit)]

public struct Input

{

[FieldOffset(0)]public Int32 type;

[FieldOffset(4)]public MouseInput mi;

[FieldOffset(4)]public tagKEYBDINPUT ki;

[FieldOffset(4)]public tagHARDWAREINPUT hi;

}

上面看到,还有MOUSEINPUT,KEYBDINPUT,HARDWAREINPUT结构需要定义。下面直接贴出代码啦。

Win API中描述:

复制代码 代码如下:

typedef struct tagMOUSEINPUT { LONG dx; LONG dy; DWORD mouseData; DWORD dwFlags; DWORD time; ULONG_PTR dwExtraInfo; } MOUSEINPUT, *PMOUSEINPUT;

typedef struct tagKEYBDINPUT { WORD wVk; WORD wScan; DWORD dwFlags; DWORD time; ULONG_PTR dwExtraInfo; } KEYBDINPUT, *PKEYBDINPUT;

typedef struct tagHARDWAREINPUT { DWORD uMsg; WORD wParamL; WORD wParamH; } HARDWAREINPUT, *PHARDWAREINPUT;

C#中对应代码:

复制代码 代码如下:

[StructLayout(LayoutKind.Sequential)]

public struct MouseInput

{

public Int32 dx;

public Int32 dy;

public Int32 Mousedata;

public Int32 dwFlag;

public Int32 time;

public IntPtr dwExtraInfo;

}

[StructLayout(LayoutKind.Sequential)]

public struct tagKEYBDINPUT

{

Int16 wVk;

Int16 wScan;

Int32 dwFlags;

Int32 time;

IntPtr dwExtraInfo;

}

[StructLayout(LayoutKind.Sequential)]

public struct tagHARDWAREINPUT

{

Int32 uMsg;

Int16 wParamL;

Int16 wParamH;

}

我主要是模拟鼠标,所以只需定义鼠标的flag值:

复制代码 代码如下:

const int MouseEvent_Absolute = 0x8000;

const int MouserEvent_Hwheel = 0x01000;

const int MouseEvent_Move = 0x0001;

const int MouseEvent_Move_noCoalesce = 0x2000;

const int MouseEvent_LeftDown = 0x0002;

const int MouseEvent_LeftUp = 0x0004;

const int MouseEvent_MiddleDown = 0x0020;

const int MouseEvent_MiddleUp = 0x0040;

const int MouseEvent_RightDown = 0x0008;

const int MouseEvent_RightUp = 0x0010;

const int MouseEvent_Wheel = 0x0800;

const int MousseEvent_XUp = 0x0100;

const int MousseEvent_XDown = 0x0080;

c#中模拟鼠标操作的代码:

复制代码 代码如下:

for (i = X; i <= X+width; i += 450)

//X为Flash窗口的左上角的x轴绝对坐标值。屏幕左上角坐标是(0,0)。width是Flash窗口宽度。

{

for (j = Y; j <= Y +height; j+=150) //Y为Flash窗口的左上角的y轴绝对坐标值。height是Flash窗口高度。

{

MouseInput myMinput = new MouseInput();

myMinput.dx = i;

myMinput.dy = j;

myMinput.Mousedata = http://www.jb51.net/cx361/archive/2011/12/11/0;

myMinput.dwFlag = MouseEvent_Absolute | MouseEvent_Move | MouseEvent_LeftDown | MouseEvent_LeftUp;

myMinput.time = 0;

Input[] myInput = new Input[1];

myInput[0] = new Input();

myInput[0].type = 0;

myInput[0].mi = myMinput;

UInt32 result = SendInput((uint)myInput.Length, myInput, Marshal.SizeOf(myInput[0].GetType()));

if (result == 0)

{

MessageBox.Show("fail");

}

}

}

知识点:将像素坐标转化为绝对坐标:

API中MouseInput结构中的dx,dy含义是绝对坐标,是相对屏幕的而言的,屏幕左上角的坐标为(0,0),右下角的坐标为(65535,65535)。而我们在C#中获得的对象(Frame,button,flash等)的坐标都是像素坐标,是跟你当前屏幕的分辨率相关的。假如你的显示器分辨率是1024*768,那么屏幕左上角的像素坐标是(0,0),右下角坐标为(1024,768)。转换函数如下:

复制代码 代码如下:

dx = x * (65335/ScreenWidth) //x,y为像素坐标。

dy = y * (65335/ScreenHeight)//ScreenWidth和ScreenHeight,其实是当前显示器的分辨率,获得方法是ScreenWidth=Screen.PrimaryScreen.WorkingArea.Width;

ScreenHeight=Screen.PrimaryScreen.WorkingArea.Height;

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新C#教程学习
热门C#教程学习
编程开发子分类