mfc中钩子的使用

MFC钩子简单应用 #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)#define KEY_UP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)      // 判断按键发生 #define DllExport _declspec(dllexpor 阅读详情

钩子的安装与卸载

  系统是通过调用位于钩子链表最开始处的钩子函数而进行消息拦截处理的,因此在设置钩子时要把回调函数放置于钩子链表的链首,操作系统会使其首先被调用。由函数SetWindowsHookEx()负责将回调函数放置于钩子链表的开始位置。SetWindowsHookEx()函数原型声明为:

HHOOK SetWindowsHookEx(int idHook;HOOKPROC lpfn;HINSTANCE hMod;DWORD dwThreadId);


  其中,参数idHook 指定了钩子的类型,可以使用的类型有以下13种:

WH_CALLWNDPROC 系统将消息发送到指定窗口之前的“钩子” 
WH_CALLWNDPROCRET 消息已经在窗口中处理的“钩子” 
WH_CBT 基于计算机培训的“钩子” 
WH_DEBUG 差错“钩子” 
WH_FOREGROUNDIDLE 前台空闲窗口“钩子” 
WH_GETMESSAGE 接收消息投递的“钩子” 
WH_JOURNALPLAYBACK 回放以前通过WH_JOURNALRECORD“钩子”记录的输入消息 
WH_JOURNALRECORD 输入消息记录“钩子” 
WH_KEYBOARD 键盘消息“钩子” 
WH_MOUSE 鼠标消息“钩子” 
WH_MSGFILTER 对话框、消息框、菜单或滚动条输入消息“钩子” 
WH_SHELL 外壳“钩子” 
WH_SYSMSGFILTER 系统消息“钩子”


  参数lpfn为指向钩子函数的指针,也即回调函数的首地址;参数hMod标识了钩子处理函数所处模块的句柄;参数dwThreadId 指定被监视的线程,如果明确指定了某个线程的ID就只监视该线程,此时的钩子即为线程钩子;如果该参数被设置为0,则表示此钩子为监视系统所有线程的全局钩子。此函数在执行完后将返回一个钩子句柄。

  在SetWindowsHookEx()函数完成对钩子的安装后,如果被监视的事件发生,系统会立即调用位于相应钩子链表开始处的钩子函数进行处理,每一个钩子函数在进行处理时都要考虑是否需要把事件传递给下一个钩子处理函数。如果需要传递,就要调用函数CallNestHookEx()。尽管在理论上不调用CallNestHookEx()也并不算错,但在实际使用时还是强烈建议无论是否需要进行事件传递都要在过程的最后调用一次CallNextHookEx( ),否则将会引起一些无法预知的系统行为或是系统锁定。该函数将返回位于钩子链表中的下一个钩子处理过程的地址,至于具体的返回值类型则要视所设置的钩子类型而定。CallNextHookEx( )的函数原型为:

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


  其中,参数hhk为由SetWindowsHookEx()函数返回的当前钩子句柄;参数nCode为传给钩子过程的事件代码;参数wParam和lParam 则为传给钩子处理函数的参数值,其具体含义同设置的钩子类型有关。

  由于安装钩子对系统的性能有一定的影响,所以在钩子使用完毕后应及时将其卸载以释放其所占资源。释放钩子的函数为UnhookWindowsHookEx(),该函数比较简单只有一个参数用于指定此前由SetWindowsHookEx()函数所返回的钩子句柄,原型声明如下:

BOOL UnhookWindowsHookEx(HHOOK hhk);


  使用鼠标钩子

  由于系统全局钩子在功能上完全覆盖了线程局部钩子,因此其实际使用范围要远比线程局部钩子广泛的多。本节也由此着重对系统全局钩子的使用进行介绍。

  鼠标钩子是钩子中比较常用也是使用比较简单的一类钩子。下面给出的应用示例将通过安装鼠标全局钩子来捕获鼠标当前所处窗口的窗口标题。由于本例程使用了全局钩子,因此首先构造全局钩子的载体——动态链接库。考虑到 Win32 DLL与Win16 DLL存在的差别,在Win32环境下要在多个进程间共享数据,就必须采取一些措施将待共享的数据提取到一个独立的数据段,并通过def文件将其属性设置为读写共享:

#pragma data_seg("mydata")
HWND glhPrevTarWnd = NULL; // 上次鼠标所指的窗口句柄
HWND glhDisplayWnd = NULL; // 显示目标窗口标题编辑框的句柄
HWND glhHook = NULL; // 安装的鼠标钩子句柄
HINSTANCE glhInstance = NULL; // DLL实例句柄
#pragma data_seg()
……
SECTIONS // def文件中将数据段TestData设置为读写共享
TestData READ WRITE SHARED


  在完成上述准备工作后,在动态库输出函数StartHook()中调用SetWindowsHookEx()函数完成对全局鼠标钩子的安装,设定鼠标钩子函数为MouseProc(),安装函数返回的钩子句柄保存于变量glhHook中:

BOOL CMouseHook::StartHook(HWND hWnd)
{
 BOOL result = FALSE;
 // 安装钩子
 glhHook = (HWND)SetWindowsHookEx(WH_MOUSE, MouseProc, glhInstance, 0);
 if (glhHook != NULL)
  result = TRUE;
 glhDisplayWnd = hWnd; // 设置显示目标窗口标题编辑框的句柄 
 return result;
}


  在鼠标钩子安装完毕后,系统内的任何鼠标动作所发出的鼠标消息均要经过钩子函数MouseProc()的拦截过滤处理。在此进行的处理是通过获取当前鼠标所在位置下的窗口句柄,并以此进一步得到窗口标题。在处理完成后,调用CallNextHookEx()函数将本事件传递到钩子链表中的下一个钩子函数:

LRESULT WINAPI MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
 LPMOUSEHOOKSTRUCT pMouseHook = (MOUSEHOOKSTRUCT FAR *) lParam;
 if (nCode >= 0) {
  HWND glhTargetWnd = pMouseHook->hwnd; // 取目标窗口句柄 
  HWND ParentWnd = glhTargetWnd; 
  while (ParentWnd != NULL){
   glhTargetWnd = ParentWnd; 
   ParentWnd = GetParent(glhTargetWnd); // 取应用程序主窗口句柄 
  } 
  if (glhTargetWnd != glhPrevTarWnd) { 
   char szCaption[100]; 
   GetWindowText(glhTargetWnd, szCaption, 100); // 取目标窗口标题 
   if (IsWindow(glhDisplayWnd)) 
    SendMessage(glhDisplayWnd, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)szCaption); 
   glhPrevTarWnd = glhTargetWnd; // 保存目标窗口 
  } 
 }
 // 继续传递消息 
 return CallNextHookEx((HHOOK)glhHook, nCode, wParam, lParam); 
}


  此动态链接库还提供有输出函数StopHook(),调用程序通过对此函数的调用完成对先前加载钩子的卸载。在此输出函数内则是通过UnhookWindowsHookEx()函数来卸载指定钩子的:

BOOL CMouseHook::StopHook()
{
 BOOL result = FALSE;
 if (glhHook){
  result = UnhookWindowsHookEx((HHOOK)glhHook); // 卸载钩子
  if (result) 
   glhDisplayWnd = glhPrevTarWnd = glhHook = NULL;
 }
 return result;
}


  通过编译、链接可以得到有关鼠标全局钩子的动态链接库,在经过调用程序对其的调用后,可以实现对在当前系统所有线程中的鼠标消息的拦截处理。在钩子动态链接库加载到进程后,只需调用输出函数StartHook()安装好全局钩子即可对鼠标消息进行拦截过滤,在调用程序退出前调用输出函数StopHook()卸载钩子。

消息钩子函数入门篇 Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的。而钩子是Windows系统中非常重要的系统接口,用它可以截获并处理送给其他应用程序的消息,来完成普通应用程序难以实现的功能。钩子可以监视系统或进程中的各种事件消息,截获发往目标窗口的消息并进行处理。这样,我们就可以在系统中安装自定义的钩子,监视系统中特定事件的发生,完成特定的功能,比如截获键盘、鼠标的输入, 阅读详情

相关推荐

C++/MFC——一个能截获和屏蔽系统热键的钩子

 BOOL installhook()...{    HINSTANCE hins=AfxGetInstanceHandle();    HHOOK Hook = SetWindowsHookEx(WH_KEYBOARD_LL,(HOOKPROC)KeyboardProc,hins,0);     return (BOOL)Hook;}第一句是获得当前应用实例的句柄。第二句是创建钩

非语 7650

《MFC编程》:钩子函数

《MFC编程》:钩子函数

ProgramNovice的博客 995

C++ MFC 使用低级键盘钩子 获取键值 (WH_KEYBOARD_LL)

LRESULT CALLBACK LowLevelKeyboardProc(INT nCode, WPARAM wParam, LPARAM lParam) { // By returning a non-zero value from the hook procedure, the // message does not get passed to the target window //

nibiru_holmes的博客 5486

MFC4.2实现键盘钩子捕获,基于DLL实现

一我们可以在应用程序中毫不费力的捕获在本程序窗口上所进行的键盘操作,但如果我们想要将此程序作成一个监控程序,捕获在Windows平台下任意窗口上的键盘操作,就需要借助于全局钩子来实现了。 二、系统钩子和DLL 钩子的本质是一段用以处理系统消息的程序,通过系统调用,将其挂入系统。钩子的种类有很多,每种钩子可以截获并处理相应的消息,每当特定的消息发出,在到达目的窗口之前,钩子程序先行截获该消息、得到对

夜澜偶作庄周梦 酒后聊为楚客狂 4575

MFC实现键盘钩子(附完整源码)

MFC实现键盘钩子(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 392

实现MFC钩子技术的VS2015实践指南

MFC(Microsoft Foundation Classes)是一个C++库,用于快速开发基于Windows操作系统的应用程序。它提供了大量的Windows API的封装,方便开发者不必直接与底层API打交道,同时MFC也支持消息映射机制,使得事件驱动编程变得简单直观。系统级Hook(也称为全局Hook)是一个挂钩,它可以监视系统中的事件或者消息,这些事件或消息不特定于某个进程或线程。系统级Hook允许开发者拦截或修改系统范围内的信息流,比如键盘输入、鼠标移动、窗口消息等。

weixin_35516273的博客 835

MFC 全局钩子dll注入监听键盘消息

MFC通过DLL注入使用全局钩子来监听键盘消息,能实现在MFC界面外监听系统键盘消息。

hzl2323406的博客 1549

C++与MFC结合的Windows钩子技术源码分析与实战

在Windows操作系统中,钩子技术是编程中用于监视系统或应用程序中的事件消息传递的机制。它允许开发者在消息被传递到目标窗口过程之前截获并处理消息。这种技术在开发全局热键、键盘监听、系统监控以及自定义输入法等方面有着广泛的应用。钩子(Hook)技术是Windows编程中一种广泛应用于事件处理的机制。它允许开发者截获系统或应用程序中的特定事件,并允许在事件到达目标窗口过程之前对其进行修改、处理或截断。

weixin_35751412的博客 853

VC/MFC 键盘钩子,代码片断

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34192732的博客 120

全局鼠标钩子

该程序是通过全局鼠标钩子进行鼠标消息捕捉,并对其操作进行记录,方便回放操作过程,改程序可以用作简单的自动化测试。

VBA鼠标键盘钩子类.xlsm

VBA鼠标键盘钩子类.xlsm

MFC消息的路由-钩子函数

 用最基本的一句话概述,钩子函数起了很大作用。故事是这样的,有些漫长,也需要些耐心。MFC中消息分为3类: 1. WM_COMMAND:所有的UI组件和加速键都会产生这种消息,所有派生于CCmdTarget的类都有能力处理该消息 2. 标准消息:除WM_COMMAND之外的WM_xx消息都是标准消息,派生于CWnd的类都有能力处理该消息 3. 控件通知消息:用于子窗

northhero的专栏 1286

光模块的封装工艺有哪些?

COB封装传统的单路10Gb/s或25Gb/s速率的光模块采用SFP封装将电芯片和TO封装的光收发组件焊接到PCB板上组成光模块。但对于40G及以上速率的高速光模块,受激光器速率限制(多为25G),主要通过多通道并行实现,如40G由4×10G实现,而100G则由4×25G实现。蝶形封装:壳体通常为长方体,结构及实现功能通常比较复杂,可以内置制冷器、热沉、陶瓷基块、芯片、热敏电阻、背光监控,并且可以支持所有以上部件的键合引线。BOX封装属于蝶形封装的一种,用于多通道并行封装。

WaytoICT- Explore ICT Technology, Build Your Tech Path 3813

MFC为什么要安装_AfxCbtFilterHook钩子函数?

在学习Windows程序设计时,模拟MFC的代码写出消息映射。 AFX框架中,CWnd类在创建窗口时,在AfxHookWindowCreate里面安装了一个WH_CBT类型的钩子函数_AfxCbtFilterHook。 BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWO

booksyhay的专栏 1832

OpenBmc开发11:添加传感器(I2C)

1 查看传感器信息 通过qemu以本地端口映射方式运行编译后的镜像,访问bmcweb页面的网址是:https://localhost:2443/,如果想用IP地址启动请参考:openbmc开发4:启动运行编译镜像。(这里以网桥方式启动,以ip地址方式访问BMC) 输入用户名和密码,密码是:0penBmc(第一个是数字)。 选择Health,然后点击Sensor,可以看到传感器信息。 2 查看传感器配置文件 进入meta-live/meta-test/recipes-phosphor/...

master 1万+

海康威视 2DC 系列球机手机直连实用教程

海康威视2DC系列球机手机直连教程:首先确认设备支持直连功能并下载官方"海康互联"App;通过网线连接球机与路由器,使用SADP软件调整IP至同一网段;在App中添加设备并激活,完成调试即可远程查看监控画面。常见问题包括部分型号需远程解锁、网络连接异常等,可通过检查网络环境、联系客服等方式解决。本教程提供从准备到连接的完整指引,助您轻松实现手机监控管理。

海康威视技术支持 5417

VC++/MFC消息映射机制(4):附:钩子函数原理

VC++/MFC消息映射机制(4):附:钩子函数原理 若对C++语法不熟悉,建议参阅《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解。 一、钩子SetWindowsHookEx 注意:本文的钩子和钩子函数是两个概念,请不要搞混淆了。 1、作用(重点):钩子主要作用是用于拦截消息。在消息发出还未到达目的窗口之前,钩子...

黄邦勇帅的博客 1593

C/C++ 计算程序运行的时间

C/C++计算程序执行时间的方法,精度依次增加,推荐度也依次增加 1.#include <time.h> clock_t start, finish; double process_interval ; start=clock(); process(); //要计时的程序 finish=clock(); process_interval =(double)(finish-star...

stu_shanghui的博客 1020
上一篇: PreTranslateMessage作用和使用方法
下一篇: HOOK钩子机制学习笔记
AstrayLinux
博客等级 码龄15年 55粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值