最近在做有关kinect控制鼠标事件时遇到了一个小问题,这里写点记录。
首先我简单介绍一下关于SendInput和mouse_event函数模拟鼠标事件的方法。
这两个函数是C++里使用的,先给个SendInput函数的原型,参照MSDN
UINT SendInput( UINT nInputs, // count of input events LPINPUT pInputs, // array of input events int cbSize // size of structure );函数说明:该函数合成键盘事件和鼠标事件,用来模拟鼠标或者键盘操作。事件将被插入在鼠标或键盘处理队列里面。
这儿使用这个函数时我们需要配置一下INPUT结构体,结构体组织参照MSND。
typedef struct tagINPUT { DWORD type; union { MOUSEINPUT mi; KEYBDINPUT ki; HARDWAREINPUT hi; }; } INPUT, *PINPUT;我给个具体代码,大家自己看了就知道如何使用它了。
INPUT Input={0};
// left down
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1,&Input,sizeof(INPUT));
// left up
ZeroMemory(&Input,sizeof(INPUT));
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1,&Input,sizeof(INPUT));
cout << "You press down left key!" << endl;
首先初始化结构体INPUT,然后配置Input.type,标签INPUT_MOUSE表示鼠标事件,INPUT_KEYBOARD代表键盘事件,INPUT_HARDWARE表示除鼠标和键盘的其它硬件事件;Input.mi.dwFlags代表具体事件,请参照MSDN,这儿的点击和释放鼠标左键操作还可以这样写,将//left up后面的代码全部删掉,将Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;改为Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN |MOUSEEVENTF_LEFTUP;将SendInput(1,&Input,sizeof(INPUT));改为SendInput(2,&Input,sizeof(INPUT));
SendInput的第一个参数代表发送的事件个数,这里是一次发送两个,所以为2.
模拟鼠标点击的另一个方式就是使用mouse_event函数向操作系统发送事件,用mouse_event函数还学要GetCursorPos函数配合,具体看代码
POINT currentPoint;
GetCursorPos(¤tPoint);
mouse_event(MOUSEEVENTF_LEFTDOWN,currentPoint.x,currentPoint.x,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,currentPoint.x,currentPoint.y,0,0);
同样发送事件的时候也可以用或的形式,具体参数意义大家参看MSDN。
那么当我们使用这些函数实现鼠标点击事件时就会出现这样一个情况,那就是点击具体程序图标、窗口和标题栏等都没有问题,但是点击桌面时就无法释放鼠标,这到底是怎么一回事呢?
我花了大概一天事件检查,都没有发现问题所在,知道第二天看到一个网友说可能跟防火墙有关系,于是我就将360防火墙的驱动防护关闭了才回复正常了。 具体原因是自己写的程序多数没有数字标签,所以发送的事件被防火前拦截了。具体做法:
打开360->木马防火墙->系统防护->驱动防护(防止木马加载驱动获得系统权限)点关闭。
祝大家开发愉快!