b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

WindowsHook钩子技术全面总结按照钩子拦截消息范围的范围

电脑杂谈  发布时间:2021-05-24 18:04:04  来源:网络整理

基本知识

HOOK是Windows消息处理机制的平台。应用程序可以通过设置钩子来监视指定窗口的特定消息。消息到达后,将在目标窗口对其进行处理之前对其进行处理。监视的窗口可以由其他进程创建。

有关特定的深入知识,请参阅本文Windows Hook Hook技术的全面摘要

根据钩子拦截消息的范围,可以分为

相关接口功能简介:

HHOOK SetWindowsHookEx(
  int       idHook,  //钩子类型,如 WH_MOUSE_LL, WH_MOUSE
  HOOKPROC  lpfn,	 //拦截回调函数
  HINSTANCE hmod,	 // dll句柄
  DWORD     dwThreadId // 线程Id,当为0时表示全局钩子
);

此功能用于安装挂钩。若要拦截来自其他线程的消息,则必须由dll中的回调函数来触发全局挂钩。处理不当会导致系统崩溃。不建议新手使用。推荐使用螺纹钩。

在这种需求下,我们将重点放在鼠标钩上。鼠标钩有两种类型:

在当前情况下,我们可以使用WM_MOUSE挂钩。请注意,WM_MOUSE_LL挂钩只能应用于全局挂钩类型。如果要监视特定线程,则在注入阶段将提示1429错误。该挂钩程序只能对整个错误消息进行设置。

LRESULT CALLBACK MouseProc(
  _In_ int    nCode,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
);

此函数定义了鼠标挂钩回调函数的接口,

鼠标钩子控制鼠标位置_实现键盘钩子截获密码_系统钩子 截获鼠标

LRESULT CallNextHookEx(
  HHOOK  hhk,
  int    nCode,
  WPARAM wParam,
  LPARAM lParam
);

此函数用于将挂钩信息传递到当前挂钩链中的下一个挂钩。

BOOL UnhookWindowsHookEx(
  HHOOK hhk
);

此功能用于卸载该钩子。

总体设计

此功能的总体设计如下:

鼠标钩子使能非激活窗口

此功能的关键业务逻辑有两点:

注册鼠标钩

注册WM_MOUSE鼠标挂钩类型就足够了,这里需要注意的一点是,官方文档中WM_MOUSE类型消息的回调函数原型是:

LRESULT CALLBACK MouseProc(
  	_In_ int    nCode,
  	_In_ WPARAM wParam,
  	_In_ LPARAM lParam
);

实现键盘钩子截获密码_鼠标钩子控制鼠标位置_系统钩子 截获鼠标

wParam表示鼠标消息标识符,例如WM_MOUSEWHEEL,WM_MOUSEMOVE等。

lParam表示鼠标指针消息回调结构类型MOUSEHOOKSTRUCT,结构声明如下:

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

根据上述结构,我们关心的是pt(基于屏幕坐标系的当前鼠标的位置坐标),并且鼠标滚轮需要滚动一定距离。搜索后,我们发现此参数有两个位置:

typedef struct tagMSLLHOOKSTRUCT {
  POINT     pt;
  DWORD     mouseData;
  DWORD     flags;
  DWORD     time;
  ULONG_PTR dwExtraInfo;
} MSLLHOOKSTRUCT, *LPMSLLHOOKSTRUCT, *PMSLLHOOKSTRUCT;

截获鼠标滚轮消息时,mouseData的高字节表示鼠标滚轮距离。但是,低级挂钩需要全局挂钩,因此不适合使用。

This is an extension of the MOUSEHOOKSTRUCT structure that includes information 
about wheel movement or the use of the X button.
typedef struct tagMOUSEHOOKSTRUCTEX {
  DWORD mouseData;
} MOUSEHOOKSTRUCTEX, *LPMOUSEHOOKSTRUCTEX, *PMOUSEHOOKSTRUCTEX;

显然,此结构是在普通消息结构上扩展的,扩展的mouseData字段正是我们所需要的。

在拦截滚轮消息后传输消息

基于以上分析,我们现在要做的是将钩形滚轮消息转换为普通滚轮消息。

根据MSDN文档,钩轮消息的wParam是鼠标消息标识符,例如WM_MOUSE_WHEEL。钩轮消息的lParam转换如下:

鼠标钩子控制鼠标位置_实现键盘钩子截获密码_系统钩子 截获鼠标

    MOUSEHOOKSTRUCTEX const &eventInfo = *(MOUSEHOOKSTRUCTEX*)lParam;
    // eventInfo.mouseData  <-- 鼠标滚轮距离
    // eventInfo.pt         <-- 鼠标当前坐标

可以通过GET_WHEEL_DELTA_WPARAM宏从mouseData成员中提取滚轮的滚动距离。除了正常滚轮消息WM_MOUSEWHEEL的wParam中滚轮的滚动距离之外,低字节还包括虚拟键消息。挂钩消息不包括在内,因此虚拟密钥消息也已完成。此步骤需要GetAsyncKeyState函数。

最后一步是根据鼠标的当前坐标获取当前位置所在的窗口的句柄。 Windows提供了WindowFromPoint函数来实现此功能。

到目前为止,已经介绍了基于钩子的非活动窗口实现对鼠标滚动的响应的要点。

演示参考链接

重新加载预处理消息的实现方案

在Internet上找到另一种方法。有关详细信息,请参见对鼠标滚轮的无效窗口响应

核心思想是在PreTranslateMessage中拦截当前应用程序接收到的鼠标滚轮消息,并将其直接发送到当前鼠标悬停位置下的窗口以进行处理。此解决方案非常简单,但是当它可能引起问题时,鼠标消息将发送到由非当前线程创建的窗口。可能有问题,需要更多测试。

摘要

以上两种实现思路仅供参考。

经验:在这个世界上,如果只有一种方法可以做一件事情,那会不会很无聊。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/bofangqi/article-377809-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...