欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# SendInput 模拟鼠标操作的实现方法

程序员文章站 2023-12-15 09:39:46
刚刚开始学习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 = //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;

上一篇:

下一篇: