C# SendInput 模擬鼠標(biāo)操作的實(shí)現(xiàn)方法
剛剛開始學(xué)習(xí)C#,想自己做一個(gè)網(wǎng)頁(yè)游戲的掛。游戲里面有收錢的動(dòng)作,一個(gè)建筑物一個(gè)建筑物的點(diǎn),很累啊。于是想用C#模擬鼠標(biāo)操作替我收錢,想著學(xué)習(xí)這個(gè)對(duì)以后的測(cè)試工作也有幫助,于是有了動(dòng)力。學(xué)習(xí)過(guò)程也是曲折的,因?yàn)榫W(wǎng)上搜了半天資料很少。該游戲是Flash的,用sendmessage不行,因?yàn)槿〔坏嚼锩娴膶?duì)象。查到有些介紹Mouse_Event的文章,但是msdn上說(shuō)已經(jīng)過(guò)時(shí)。于是查到了SendInput函數(shù)。
廢話少說(shuō),上代碼:
首先看下 Win API 中SendInput函數(shù)描述:
UINT WINAPI SendInput(
__in UINT nInputs,
__in LPINPUT pInputs,
__in int cbSize
);
對(duì)應(yīng)的C#代碼:
[DllImport("user32.dll")]
public static extern UInt32 SendInput(UInt32 nInputs,Input[] pInputs, int cbSize);
其中參數(shù)pInputs是的數(shù)組類型,數(shù)組元素INPUT結(jié)構(gòu),所以我們下面還要在C#中定義對(duì)應(yīng)的INPUT結(jié)構(gòu)或者對(duì)象。INPUT結(jié)構(gòu)中主要是定義你需要的鼠標(biāo)或者鍵盤等操作。nInputs指明pInputs數(shù)組長(zhǎng)度。cbSize指明INPUT結(jié)構(gòu)的大小。
定義INPUT結(jié)構(gòu),下面是Win API 中INPUT結(jié)構(gòu)描述:
typedef struct tagINPUT {
DWORD type;
union {
MOUSEINPUT mi;
KEYBDINPUT ki;
HARDWAREINPUT hi;
} ;
} INPUT, *PINPUT;
對(duì)應(yīng)的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結(jié)構(gòu)需要定義。下面直接貼出代碼啦。
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#中對(duì)應(yīng)代碼:
[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;
}
我主要是模擬鼠標(biāo),所以只需定義鼠標(biāo)的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#中模擬鼠標(biāo)操作的代碼:
for (i = X; i <= X+width; i += 450)
//X為Flash窗口的左上角的x軸絕對(duì)坐標(biāo)值。屏幕左上角坐標(biāo)是(0,0)。width是Flash窗口寬度。
{
for (j = Y; j <= Y +height; j+=150) //Y為Flash窗口的左上角的y軸絕對(duì)坐標(biāo)值。height是Flash窗口高度。
{
MouseInput myMinput = new MouseInput();
myMinput.dx = i;
myMinput.dy = j;
myMinput.Mousedata = http://www.dhdzp.com/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");
}
}
}
知識(shí)點(diǎn):將像素坐標(biāo)轉(zhuǎn)化為絕對(duì)坐標(biāo):
API中MouseInput結(jié)構(gòu)中的dx,dy含義是絕對(duì)坐標(biāo),是相對(duì)屏幕的而言的,屏幕左上角的坐標(biāo)為(0,0),右下角的坐標(biāo)為(65535,65535)。而我們?cè)贑#中獲得的對(duì)象(Frame,button,flash等)的坐標(biāo)都是像素坐標(biāo),是跟你當(dāng)前屏幕的分辨率相關(guān)的。假如你的顯示器分辨率是1024*768,那么屏幕左上角的像素坐標(biāo)是(0,0),右下角坐標(biāo)為(1024,768)。轉(zhuǎn)換函數(shù)如下:
dx = x * (65335/ScreenWidth) //x,y為像素坐標(biāo)。
dy = y * (65335/ScreenHeight)//ScreenWidth和ScreenHeight,其實(shí)是當(dāng)前顯示器的分辨率,獲得方法是ScreenWidth=Screen.PrimaryScreen.WorkingArea.Width;
ScreenHeight=Screen.PrimaryScreen.WorkingArea.Height;
- c# 在WebBrowser中用SendMessage模擬鼠標(biāo)點(diǎn)擊
- C#模擬Http與Https請(qǐng)求框架類實(shí)例
- C#模擬http 發(fā)送post或get請(qǐng)求的簡(jiǎn)單實(shí)例
- C#采用mouse_event函數(shù)實(shí)現(xiàn)模擬鼠標(biāo)功能
- C#實(shí)現(xiàn)的三種模擬自動(dòng)登錄和提交POST信息的方法
- 使用C#發(fā)送Http請(qǐng)求實(shí)現(xiàn)模擬登陸實(shí)例
- C#基于socket模擬http請(qǐng)求的方法
- c#模擬銀行atm機(jī)示例分享
- C#模擬window操作鼠標(biāo)的方法
- C#如何使用Bogus創(chuàng)建模擬數(shù)據(jù)示例代碼
相關(guān)文章
C#面向?qū)ο笤O(shè)計(jì)原則之接口隔離原則
這篇文章介紹了C#面向?qū)ο笤O(shè)計(jì)原則之接口隔離原則,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
C#單例模式Singleton的實(shí)現(xiàn)詳解
單例模式(Singleton?Pattern)是日常開發(fā)中最簡(jiǎn)單的設(shè)計(jì)模式之一,它提供了一種創(chuàng)建對(duì)象的最佳方式,本文主要為大家介紹的是C#單例模式的實(shí)現(xiàn)方法,需要的可以參考一下2023-05-05
Unity輸出帶點(diǎn)擊跳轉(zhuǎn)功能的Log實(shí)現(xiàn)技巧詳解
這篇文章主要為大家介紹了Unity輸出帶點(diǎn)擊跳轉(zhuǎn)功能的Log實(shí)現(xiàn)技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
WinForm實(shí)現(xiàn)攔截窗體上各個(gè)部位的點(diǎn)擊特效實(shí)例
這篇文章主要介紹了WinForm實(shí)現(xiàn)攔截窗體上各個(gè)部位的點(diǎn)擊特效實(shí)例,對(duì)窗體上各個(gè)部位進(jìn)行定義,從而實(shí)現(xiàn)了點(diǎn)擊特效,需要的朋友可以參考下2014-09-09
UnityWebRequest前后端交互實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了UnityWebRequest前后端交互實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
C#使用foreach語(yǔ)句遍歷堆棧(Stack)的方法
這篇文章主要介紹了C#使用foreach語(yǔ)句遍歷堆棧(Stack)的方法,涉及C#操作foreach實(shí)現(xiàn)遍歷堆棧的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
WPF實(shí)現(xiàn)好看的Loading動(dòng)畫的示例代碼
這篇文章主要介紹了如何利用WPF實(shí)現(xiàn)好看的Loading動(dòng)畫效果,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定幫助,需要的可以參考一下2022-08-08
Unity游戲開發(fā)之2048游戲的實(shí)現(xiàn)
2048是一款數(shù)字益智游戲,初始數(shù)字則是由2+2組成的基數(shù)4。在操作方面的不同則表現(xiàn)為一步一格的移動(dòng),變成更為爽快的一次到底。相同數(shù)字的方?jīng)r在靠攏、相撞時(shí)會(huì)相加。本文將通過(guò)Unity3D實(shí)現(xiàn)這一游戲,需要的可以參考一下2022-03-03
C#實(shí)現(xiàn)撲克游戲(21點(diǎn))的示例代碼
21點(diǎn)又名黑杰克,該游戲由2到6個(gè)人玩,使用除大小王之外的52張牌,游戲者的目標(biāo)是使手中的牌的點(diǎn)數(shù)之和不超過(guò)21點(diǎn)且盡量大。本文將用C#實(shí)現(xiàn)這一經(jīng)典游戲,需要的可以參考一下2022-08-08

