您的位置:首页 > 编程语言 > C语言/C++

使用WH_MOUSE_LL钩子来判断按键是否是mouse_event模拟的

2016-08-23 13:12 1556 查看
在玩游戏时,我们可能需要一些快捷工具,比如左键连点,效果就是在按下鼠标左键后将会以一个很快的速度一直模拟点击鼠标左键,松开后就会自动停止。网上也有很多这样的工具,从前我也自己尝试开发过,但是总会有一个严重的问题——如何判定真正的鼠标左键是否被按下。

一直以来,我都是用如下代码模拟鼠标左键的点击。

mouse_event(MOUSEEVENTF_LEFTDOWN, NULL, NULL, NULL, NULL);
mouse_event(MOUSEEVENTF_LEFTUP, NULL, NULL, NULL, NULL);


同时通过WH_MOUSE_LL钩子来判断鼠标的按键。

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
switch (wParam)
{
case WM_LBUTTONDOWN:
{
//这里写代码
break;
}
case WM_LBUTTONUP:
{
//这里写代码
break;
}
default:
break;
}
return CallNextHookEx(hMouse, nCode, wParam, lParam);
}


本以为会使用很复杂的API才能实现对真实按键和模拟按键的识别,没想到在不经意的测试之中发现原来钩子本身就带有许多有用的信息。

在WH_MOUSE_LL钩子的消息中,lParam指向一个MOUSEHOOKSTRUCT结构,MOUSEHOOKSTRUCT定义如下:

typedef struct tagMOUSEHOOKSTRUCT {
POINT   pt;
HWND    hwnd;
UINT    wHitTestCode;
ULONG_PTR dwExtraInfo;
} MOUSEHOOKSTRUCT, FAR *LPMOUSEHOOKSTRUCT, *PMOUSEHOOKSTRUCT;


其中的wHitTestCode参数,在真实按键时为0,而在使用mouse_event模拟时,它将为1。因此我们可以定义一个变量来保存鼠标左键是否真正被按下。

BOOL MouseDown = FALSE;

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
MOUSEHOOKSTRUCT mhs = *((PMOUSEHOOKSTRUCT)lParam); //将lParam指向的内容拷贝到mhs中

switch (wParam)
{
case WM_LBUTTONDOWN:
{
if (!mhs.wHitTestCode) //如果wHitTestCode为0
{
MouseDown = TRUE;
}
break;
}
case WM_LBUTTONUP:
{
if (!mhs.wHitTestCode) //如果wHitTestCode为0
{
MouseDown = FALSE;
}
break;
}
default:
break;
}
return CallNextHookEx(hMouse, nCode, wParam, lParam);
}

//其他代码已省略


这样就能准确地判断是否真正按下了鼠标左键了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  鼠标 C-C++