本文完整测试工程的源码免积分下载地址:http://download.csdn.net/detail/zy_dreamer/5336484

我们先来简单的了解一下基本概念:

Hook是WINDOWS提供的一种消息处理机制,它使得程序员可以使用子过程来监视系统消息,并在消息到达目标过程前得到处理。

HOOK链 
WINDOWS提供了几种不同类型的HOOKS;不同的HOOK可以处理不同的消息。例如,WH_MOUSE HOOK用来监视鼠标消息。 
WINDOWS为这几种HOOKS维护着各自的HOOK链。HOOK链是一个由应用程序定义的回调函数队列,当某种类型的消息发生时,WINDOWS向此种类型的HOOK链的第一个函数发送该消息,在第一函数处理完该消息后由该函数向链表中的下一个函数传递消息,依次向下。如果链中某个函数没有向下传送该消息,那么链表中后面的函数将得不到此消息。(对于某些类型的HOOK,不管HOOK链中的函数是否向下传递消息,与此类型HOOK联系的所有HOOK函数都会收到系统发送的消息)
HOOK过程 
为了拦截特定的消息,你可以使用SetWindowsHookEx函数在该类型的HOOK链中安装你自己的HOOK函数。

该函数MSDN中的描述

The SetWindowsHookEx function installs an application-defined hook procedure into a hook chain. You would install a hook procedure to monitor the system for certain types of events. These events are associated either with a specific thread or with all threads in the same desktop as the calling thread. SyntaxHHOOK SetWindowsHookEx(          int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId
);
ParametersidHook
[in] Specifies the type of hook procedure to be installed. This parameter can be one of the following values.
WH_CALLWNDPROC
Installs a hook procedure that monitors messages before the system sends them to the destination window procedure. For more information, see the CallWndProc hook procedure.
WH_CALLWNDPROCRET
Installs a hook procedure that monitors messages after they have been processed by the destination window procedure. For more information, see the CallWndRetProc hook procedure.
WH_CBT
Installs a hook procedure that receives notifications useful to a computer-based training (CBT) application. For more information, see the CBTProc hook procedure.
WH_DEBUG
Installs a hook procedure useful for debugging other hook procedures. For more information, see the DebugProc hook procedure.
WH_FOREGROUNDIDLE
Installs a hook procedure that will be called when the application's foreground thread is about to become idle. This hook is useful for performing low priority tasks during idle time. For more information, see the ForegroundIdleProc hook procedure.
WH_GETMESSAGE
Installs a hook procedure that monitors messages posted to a message queue. For more information, see the GetMsgProc hook procedure.
WH_JOURNALPLAYBACK
Installs a hook procedure that posts messages previously recorded by a WH_JOURNALRECORD hook procedure. For more information, see the JournalPlaybackProc hook procedure.
WH_JOURNALRECORD
Installs a hook procedure that records input messages posted to the system message queue. This hook is useful for recording macros. For more information, see the JournalRecordProc hook procedure.
WH_KEYBOARD
Installs a hook procedure that monitors keystroke messages. For more information, see the KeyboardProc hook procedure.
WH_KEYBOARD_LL
Windows NT/2000/XP: Installs a hook procedure that monitors low-level keyboard input events. For more information, see the LowLevelKeyboardProc hook procedure.
WH_MOUSE
Installs a hook procedure that monitors mouse messages. For more information, see the MouseProc hook procedure.
WH_MOUSE_LL
Windows NT/2000/XP: Installs a hook procedure that monitors low-level mouse input events. For more information, see the LowLevelMouseProc hook procedure.
WH_MSGFILTER
Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. For more information, see the MessageProc hook procedure.
WH_SHELL
Installs a hook procedure that receives notifications useful to shell applications. For more information, see the ShellProc hook procedure.
WH_SYSMSGFILTER
Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. The hook procedure monitors these messages for all applications in the same desktop as the calling thread. For more information, see the SysMsgProc hook procedure.
lpfn
[in] Pointer to the hook procedure. If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a DLL. Otherwise, lpfn can point to a hook procedure in the code associated with the current process.
hMod
[in] Handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
dwThreadId
[in] Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop as the calling thread.
Return ValueIf the function succeeds, the return value is the handle to the hook procedure. If the function fails, the return value is NULL. To get extended error information, call GetLastError.

这里我来简单的解释一下:

函数的功能描述是:SetWindowsHookEx函数安装一个程序自定义的钩子过程到钩子链。你可以安装一个钩子过程来监视系统的特定消息。可以监视某一个特定的线程的消息,或者是与这个消息相关的当前运行的所有线程。

函数一共有四个参数
参数1:idHook
定义了钩子过程的类型,也就是这个钩子将要监视哪种消息
参数2:lpfn
它是一个钩子过程的指针。如果dwThreadId也就是第四个参数的值是0或者是由其它进程创建的线程的ID,那么这个参数必须是指向一个位于DLL中的钩子过程的指针,否则这个指针可以是当前进程代码空间中定义的一个钩子过程的地址。
参数3:hMod
是一个包含了lpfn所指向的钩子过程的DLL的句柄。如果第四个参数线程ID的值是由当前进程创建的线程的ID值并且钩子过程是在当前进程中定义的,那么这个参数必须设置成NULL。
参数4:dwThreadId
指明钩子过程要监视的线程ID。如果是0那么钩子过程将监视所有桌面运行的线程。
返回值:
成功返回钩子过程的句柄。
失败返回NULL,获得额外信息,调用GetLastError

lpfn指向钩子回调函数的函数地址,这个函数用来对钩子检测到的消息进行处理。MSDN中函数的原型如下,这里以键盘检测函数的原型为例:

The KeyboardProc hook procedure is an application-defined or library-defined callback function used with theSetWindowsHookEx function. The system calls this function whenever an application calls the GetMessage orPeekMessage function and there is a keyboard message (WM_KEYUP or WM_KEYDOWN) to be processed.

The HOOKPROC type defines a pointer to this callback function. KeyboardProc is a placeholder for the application-defined or library-defined function name.

Syntax

LRESULT CALLBACK KeyboardProc(      int code,WPARAM wParam,LPARAM lParam
);

Parameters

code
[in] Specifies a code the hook procedure uses to determine how to process the message. If code is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx. This parameter can be one of the following values.

HC_ACTION
The wParam and lParam parameters contain information about a keystroke message.
HC_NOREMOVE
The wParam and lParam parameters contain information about a keystroke message, and the keystroke message has not been removed from the message queue. (An application called thePeekMessage function, specifying the PM_NOREMOVE flag.)
wParam
[in] Specifies the virtual-key code of the key that generated the keystroke message.
lParam
[in] Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag. For more information about the lParam parameter, see Keystroke Message Flags. This parameter can be one or more of the following values.

0-15
Specifies the repeat count. The value is the number of times the keystroke is repeated as a result of the user's holding down the key.
16-23
Specifies the scan code. The value depends on the OEM.
24
Specifies whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if the key is an extended key; otherwise, it is 0.
25-28
Reserved.
29
Specifies the context code. The value is 1 if the ALT key is down; otherwise, it is 0.
30
Specifies the previous key state. The value is 1 if the key is down before the message is sent; it is 0 if the key is up.
31
Specifies the transition state. The value is 0 if the key is being pressed and 1 if it is being released.

Return Value

If code is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If code is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_KEYBOARD hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.

Remarks

An application installs the hook procedure by specifying the WH_KEYBOARD hook type and a pointer to the hook procedure in a call to the SetWindowsHookEx function.

keyboardProc钩子过程是定义在应用程序中或是库文件中的回调函数,它有SetWindowsHookEx来使用。当应用程序中调用了GetMessage或是PeekMessage方法时并且处理的是键盘消息(WM_KEYUP或WM_KEYDOWN)HOOKPROC类型定义了一个指向回调函数的指针。从原型定义中我们可以看出:typedef LRESULT (CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);

它其实就是在WinUser.h中定义的一个函数指针

一个简单的回调函数的例子如下(键盘钩子为例)

// 钩子回调函数(钩子过程)
LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{if (nCode < 0 || nCode == HC_NOREMOVE)//向下传递消息使得hook链上的其他函数可以处理该消息return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);    if (lParam & 0x40000000)    // Check the previous key state{return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);}//将自定义消息发送到主窗口//wParam 定义了虚拟键代码//lParam 定义了按键数据::PostMessage(g_hWnd, WM_KEYSTROKE, wParam, lParam);return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

上面PostMessage函数中的g_hWnd是主窗口的句柄,就是我们用来处理检测到的消息的那个窗口。
WM_KEYSTROKE是我们自己定义的一个消息宏,当钩子检测到消息后,就将这个消息发送到主窗口来进行处理。
#define WM_KEYSTROKE (WM_USER + 101)

我们定义了下面一个函数来安装或卸载一个消息钩子。

//安装或者卸载钩子的函数
BOOL WINAPI SetKeyboardHook(BOOL bInstall, DWORD dwThreadId, HWND hWndCaller)
{BOOL bOk;g_hWnd = hWndCaller;if (bInstall){g_hHook = ::SetWindowsHookEx(WH_KEYBOARD, KeyboardHookProc, ModuleFromAddress(KeyboardHookProc), dwThreadId);//安装消息钩子bOk = (g_hHook != NULL);}else {bOk = ::UnhookWindowsHookEx(g_hHook);g_hHook = NULL;}return bOk;
}

ModuleFromAddress函数帮助我们获得模块地址:

HMODULE WINAPI ModuleFromAddress(PVOID pv)
{MEMORY_BASIC_INFORMATION mbi;if (::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0){return (HMODULE)mbi.AllocationBase;}else{return NULL;}
}

由于上面我们定义的消息钩子的回调函数是和安装钩子的程序代码定义在一起的,而不是定义在外部DLL中,所以这个钩子只能监视本线程的消息,而不是一个全局消息钩子。要想实现能对所有程序的键盘消息进行检测,必须将消息钩子的回调函数定义在DLL模块中。
DLL中的定义如下:

.h

#ifdef HOOKDLL_EXPORTS
#define HOOKDLL_API __declspec(dllexport)
#else
#define HOOKDLL_API __declspec(dllimport)
#endif//自定义消息,当键盘按键按下和释放时发送消息
#define WM_KEYSTROKE (WM_USER + 101)
#define WM_KEYINPUT  (WM_USER + 102)//导出函数
BOOL HOOKDLL_API WINAPI SetKeyboardHook(BOOL bInstall, DWORD dwThreadId = 0, HWND hWndCaller = NULL);

.cpp

#include <windows.h>#define HOOKDLL_EXPORTS
#include "HookDll.h"// Shared data among all instances.
#pragma data_seg(".HOOKDATA")
HWND g_hWnd = NULL;            // Window handle
HHOOK g_hHook = NULL;      // Hook handle// Get module from address
HMODULE WINAPI ModuleFromAddress(PVOID pv)
{MEMORY_BASIC_INFORMATION mbi;if (::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0){return (HMODULE)mbi.AllocationBase;}else{return NULL;}
}// 钩子回调函数(钩子过程)
LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{if (nCode < 0 || nCode == HC_NOREMOVE)//向下传递消息使得hook链上的其他函数可以处理该消息return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);    if (lParam & 0x40000000)    // Check the previous key state{return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);}//将自定义消息发送到主窗口//wParam 定义了虚拟键代码//lParam 定义了按键数据::PostMessage(g_hWnd, WM_KEYSTROKE, wParam, lParam);return ::CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
//安装或者卸载钩子的函数
BOOL WINAPI SetKeyboardHook(BOOL bInstall, DWORD dwThreadId, HWND hWndCaller)
{BOOL bOk;g_hWnd = hWndCaller;if (bInstall){g_hHook = ::SetWindowsHookEx(WH_KEYBOARD, KeyboardHookProc, ModuleFromAddress(KeyboardHookProc), dwThreadId);//安装消息钩子bOk = (g_hHook != NULL);}else {bOk = ::UnhookWindowsHookEx(g_hHook);g_hHook = NULL;}return bOk;
}

.def

LIBRARY  CppHooKDll
EXPORTSSetKeyboardHook
SECTIONS.HOOKDATA   Read Write Shared

在需要安装全局钩子的程序中调用:

::SetWindowsHookEx(WH_KEYBOARD, KeyboardHookProc, ModuleFromAddress(KeyboardHookProc), 0)

C++ Windows Hook 消息钩子 详解相关推荐

  1. 令人生疑的Windows窗口消息WM_PAINT详解

    目录 1.WM_APINT消息的产生 2.WM_ERASEBKGND消息说明 3.InvalidateRect和UpdateWindow 4.何时使用BeginPaint和EndPaint? 在做Wi ...

  2. Windows 窗口发送消息参数详解

    窗口发送消息参数详解 // 窗口.发送消息 函数功能: 将指定的消息发送到一个窗口,同win32 api 里面的SendMessage等同的效果中文函数原型: 发送消息(hwnd,msg,wparam ...

  3. C#环境下的钩子详解

    C#环境下的钩子详解 摘自网上供自己备查: http://www.csharpwin.com/csharpspace/2423.shtml 1. WINDOWS的消息机制 2. HOOK介绍 3. H ...

  4. mfc编程vc6.0实现进程的创建和通信_免费送书:windows黑客编程技术详解

    01 书怎么送 点赞并留言,关注在下面的公众号后台回复「抽奖」,弹出小程序后点击参与. 开奖时间是 7 月 7 号 20:00 ,一定要留意微信消息,如果你中奖了,请尽快在中奖页面提交收件人信息并备注 ...

  5. 窗口发送消息参数详解

    窗口发送消息参数详解 //    窗口.发送消息    函数功能: 将指定的消息发送到一个窗口,同win32 api 里面的SendMessage等同的效果 中文函数原型: 发送消息(hwnd,msg ...

  6. [vb]一些窗口消息的详解

    代码: Public Const WM_NULL = &H0 '空消息 Public Const WM_NCCREATE = &H81 '当窗口第一次被创建时,此消息在WM_CREAT ...

  7. 《Windows驱动开发技术详解》学习笔记

    Abstract   如果推荐 Windows 驱动开发的入门书,我强烈推荐<Windows驱动开发技术详解>.但是由于成书的时间较早,该书中提到的很多工具和环境都已不可用或找不到,而本文 ...

  8. 豆邮windows客户端(第三方)开发详解

    豆邮windows客户端(第三方)开发详解 "豆邮",是社区网站"豆瓣"的一个类似私信的功能模块.在豆瓣官网,"豆邮"曾一度被改为" ...

  9. C# Windows 窗体编程入门详解

    C# Windows 窗体编程入门详解 基于Web的B/S架构应用程序近年来确实非常流行,B/S易于部署.易于维护的特点使Web应用程序开发得到了前所未有的发展.但是,Web应用程序的缺点是,它们有时 ...

最新文章

  1. mysql 开启慢查询命令【转】
  2. C++_代码重用3-私有继承
  3. spring源码深度解析—Spring的整体架构和环境搭建
  4. printdocument python_python学习笔记之wxpython打印预览
  5. 人工智能3d建模算法_黑科技 | 3D人脸建模可以多简单?一张照片就搞定!
  6. 数据库加密乱码_加密数据库中的密码
  7. mvvm框架 android,mvvm框架原理 android 怎么使用mvvm框架
  8. 制作U盘启动盘 优启通
  9. 【冬瓜哥手绘】致敬龙芯!冬瓜哥手工设计了一个CPU译码器!
  10. 山东高中学业水平考试时间2020计算机,2020年山东省高中学业水平等级考试报名时间及科目...
  11. 关于hadoop运行成功但是无法链接web页面
  12. 创建数据库失败((Microsoft.SqlServer.Smo))执行Transact-SQL语句或批处理时发生了异常。
  13. 革新科技的TI+ST+XILINX嵌入式异构多核开发平台教育市场应用
  14. 【houdini 核心概念】Stamp
  15. java基础_题库详解
  16. 喝过红茶,热过烟花——张国荣《午后红茶》歌词解析
  17. 企业安全建设怎样防止供应商出现安全漏洞
  18. 国际奥委会主席巴赫考察冬奥场馆 为中国效率点赞
  19. pandas入门PPT
  20. 5、无线传输和卫星通信(物理层)

热门文章

  1. 特征值是否重根与特征向量及基础解系的关系
  2. 美国北亚利桑那大学计算机在线硕士,美国北亚利桑那大学在职研究生招生类型...
  3. 阿里云SDK和SpringBoot maven项目中jar包冲突的解决办法
  4. 在胸口凝成一颗鲜红的朱砂印
  5. 蓝魔法师——树形DP
  6. 文本合成图像栩栩如生,仿佛拥有人类的语言想象力:OpenAI祭出120亿参数魔法模型!...
  7. Android和win10的融合,微软Windows10更新版亮相 更好融合iOS、Android系统
  8. 看完,如果你不分享,是我的失败!
  9. Linux中使用命令分类型统计系统光盘中rpm包数量
  10. php使用常量和变量输出圆的面积,PHP常量和变量分别是什么?有什么区别?