SetWindowsHookExW 函数 (winuser.h)

将应用程序定义的挂钩过程安装到挂钩链中。 你将安装挂钩过程来监视系统的某些类型的事件。 这些事件与特定线程或调用线程位于同一桌面中的所有线程相关联。

语法

HHOOK SetWindowsHookExW(
  [in] int       idHook,
  [in] HOOKPROC  lpfn,
  [in] HINSTANCE hmod,
  [in] DWORD     dwThreadId
);

参数

[in] idHook

类型: int

要安装的挂钩过程的类型。 此参数的取值可为下列值之一:

含义
WH_CALLWNDPROC
4
安装一个挂钩过程,用于监视系统将消息发送到目标窗口过程之前的消息。 有关详细信息,请参阅 CallWndProc 挂钩过程。
WH_CALLWNDPROCRET
12
安装一个挂钩过程,用于在目标窗口过程处理消息后监视消息。 有关详细信息,请参阅 CallWndRetProc 挂钩过程。
WH_CBT
5
安装一个挂钩过程,该挂钩过程接收对 CBT 应用程序有用的通知。 有关详细信息,请参阅 CBTProc 挂钩过程。
WH_DEBUG
9
安装用于调试其他挂钩过程的挂钩过程。 有关详细信息,请参阅 DebugProc 挂钩过程。
WH_FOREGROUNDIDLE
11
安装将在应用程序的前景线程即将处于空闲状态时调用的挂钩过程。 此挂钩可用于在空闲时间执行低优先级任务。 有关详细信息,请参阅 ForegroundIdleProc 挂钩过程。
WH_GETMESSAGE
3
安装一个挂钩过程,用于监视发布到消息队列的消息。 有关详细信息,请参阅 GetMsgProc 挂钩过程。
WH_JOURNALPLAYBACK
1

警告

从 Windows 11 开始,不支持日记挂钩 API,将在将来的版本中删除。 因此,强烈建议改为调用 SendInput TextInput API。

安装一个挂钩过程,用于发布以前由 WH_JOURNALRECORD 挂钩过程记录的消息。 有关详细信息,请参阅 JournalPlaybackProc 挂钩过程。

WH_JOURNALRECORD
0

警告

从 Windows 11 开始,不支持日记挂钩 API,将在将来的版本中删除。 因此,强烈建议改为调用 SendInput TextInput API。

安装一个挂钩过程,用于记录发布到系统消息队列的输入消息。 此挂钩可用于录制宏。 有关详细信息,请参阅 JournalRecordProc 挂钩过程。

WH_KEYBOARD
2
安装监视击键消息的挂钩过程。 有关详细信息,请参阅 KeyboardProc 挂钩过程。
WH_KEYBOARD_LL
13
安装用于监视低级别键盘输入事件的挂钩过程。 有关详细信息,请参阅 LowLevelKeyboardProc 挂钩过程。
WH_MOUSE
7
安装监视鼠标消息的挂钩过程。 有关详细信息,请参阅 MouseProc 挂钩过程。
WH_MOUSE_LL
14
安装用于监视低级别鼠标输入事件的挂钩过程。 有关详细信息,请参阅 LowLevelMouseProc 挂钩过程。
WH_MSGFILTER
-1
安装一个挂钩过程,用于监视对话框、消息框、菜单或滚动条中输入事件生成的消息。 有关详细信息,请参阅 MessageProc 挂钩过程。
WH_SHELL
10
安装一个挂钩过程,该挂钩过程接收对 shell 应用程序有用的通知。 有关详细信息,请参阅 ShellProc 挂钩过程。
WH_SYSMSGFILTER
6
安装一个挂钩过程,用于监视对话框、消息框、菜单或滚动条中输入事件生成的消息。 挂钩过程监视与调用线程位于同一桌面中的所有应用程序的消息。 有关详细信息,请参阅 SysMsgProc 挂钩过程。

[in] lpfn

类型: HOOKPROC

指向挂钩过程的指针。 如果 dwThreadId 参数为零或指定由其他进程创建的线程的标识符, 则 lpfn 参数必须指向 DLL 中的挂钩过程。 否则, lpfn 可以指向与当前进程关联的代码中的挂钩过程。

[in] hmod

类型: HINSTANCE

包含 lpfn 参数指向的挂钩过程的 DLL 的句柄。 如果 dwThreadId 参数指定由当前进程创建的线程,并且挂钩过程位于与当前进程关联的代码中,则必须将 hMod 参数设置为 NULL

[in] dwThreadId

类型:DWORD

要与之关联的挂钩过程的线程的标识符。 对于桌面应用,如果此参数为零,则挂钩过程与调用线程在同一桌面上运行的所有现有线程相关联。 对于 Windows 应用商店应用,请参阅“备注”部分。

返回值

类型: HHOOK

如果函数成功,则返回值是挂钩过程的句柄。

如果函数失败,则返回值为 NULL。 要获得更多的错误信息,请调用 GetLastError。

注解

SetWindowsHookEx 可用于将 DLL 注入另一个进程。 不能将 32 位 DLL 注入 64 位进程,64 位 DLL 无法注入 32 位进程。 如果应用程序需要在其他进程中使用挂钩,则需要 32 位应用程序调用 SetWindowsHookEx 将 32 位 DLL 注入 32 位进程,而 64 位应用程序调用 SetWindowsHookEx 将 64 位 DLL 注入 64 位进程。 32 位和 64 位 DLL 必须具有不同的名称。

由于挂钩在应用程序的上下文中运行,因此它们必须与应用程序的“位性”匹配。 如果 32 位应用程序在 64 位 Windows 上安装全局挂钩,则会将 32 位挂钩注入每个 32 位进程, (通常的安全边界应用) 。 在 64 位进程中,线程仍标记为“已挂钩”。但是,由于 32 位应用程序必须运行挂钩代码,因此系统会在挂钩应用的上下文中执行挂钩;具体而言,在名为 SetWindowsHookEx 的线程上。 这意味着挂钩应用程序必须继续泵送消息,或者可能会阻止 64 位进程的正常运行。

如果 64 位应用程序在 64 位 Windows 上安装全局挂钩,则会将 64 位挂钩注入到每个 64 位进程中,而所有 32 位进程都使用挂钩应用程序的回调。

若要挂钩 64 位 Windows 安装桌面上的所有应用程序,请安装一个 32 位全局挂钩和一个 64 位全局挂钩,每个连接来自相应进程,并确保在挂钩应用程序中保持抽水消息,以避免阻止正常运行。 如果已有 32 位全局挂钩应用程序,并且不需要在每个应用程序的上下文中运行,则可能需要创建 64 位版本。

如果 hMod 参数为 NULLdwThreadId 参数为零或指定由另一个进程创建的线程的标识符,则可能会出现错误。

调用 CallNextHookEx 函数以链接到下一个挂钩过程是可选的,但强烈建议这样做:否则,已安装挂钩的其他应用程序将不会收到挂钩通知,因此行为不正确。 除非绝对需要防止其他应用程序看到通知,否则应调用 CallNextHookEx

在终止之前,应用程序必须调用 UnhookWindowsHookEx 函数来释放与挂钩关联的系统资源。

挂钩的范围取决于挂钩类型。 某些挂钩只能使用全局范围进行设置;其他人也可以仅为特定线程设置,如下表所示。

挂钩 范围
WH_CALLWNDPROC 线程或全局
WH_CALLWNDPROCRET 线程或全局
WH_CBT 线程或全局
WH_DEBUG 线程或全局
WH_FOREGROUNDIDLE 线程或全局
WH_GETMESSAGE 线程或全局
WH_JOURNALPLAYBACK 仅限全局
WH_JOURNALRECORD 仅限全局
WH_KEYBOARD 线程或全局
WH_KEYBOARD_LL 仅限全局
WH_MOUSE 线程或全局
WH_MOUSE_LL 仅限全局
WH_MSGFILTER 线程或全局
WH_SHELL 线程或全局
WH_SYSMSGFILTER 仅限全局
 

对于指定的挂钩类型,首先调用线程挂钩,然后调用全局挂钩。 请注意,可以在安装了挂钩的线程上调用WH_MOUSE、WH_KEYBOARD、WH_JOURNAL*、WH_SHELL和低级别挂钩。 对于这些挂钩,如果 32 位挂钩位于挂钩链中的 64 位挂钩前面,则调用 32 位和 64 位挂钩。

全局挂钩是共享资源,安装一个挂钩会影响调用线程所在的同一桌面中的所有应用程序。 所有全局挂钩函数都必须位于库中。 全局挂钩应限制为特殊用途应用程序,或在应用程序调试期间用作开发援助。 不再需要挂钩的库应删除其挂钩过程。

Windows 应用商店应用开发如果 dwThreadId 为零,则 Windows 应用商店应用进程和Windows 运行时中转站进程不会加载窗口挂钩 DLL,除非 UIAccess 进程 (辅助功能工具) 安装它们。 通知在安装程序的线程上传递这些挂钩:

  • WH_JOURNALPLAYBACK
  • WH_JOURNALRECORD
  • WH_KEYBOARD
  • WH_KEYBOARD_LL
  • WH_MOUSE
  • WH_MOUSE_LL
此行为类似于挂钩 DLL 与目标应用程序进程之间存在体系结构不匹配的情况,例如,当挂钩 DLL 为 32 位和应用程序进程 64 位时。

示例

有关示例,请参阅 安装和释放挂钩过程

注意

winuser.h 标头将 SetWindowsHookEx 定义为别名,该别名根据 UNICODE 预处理器常量的定义自动选择此函数的 ANSI 或 Unicode 版本。 将非中性编码别名与非编码中性代码混合使用可能会导致编译或运行时错误不匹配。 有关详细信息,请参阅 函数原型的约定

要求

   
最低受支持的客户端 Windows 2000 Professional [仅限桌面应用]
最低受支持的服务器 Windows 2000 Server [仅限桌面应用]
目标平台 Windows
标头 winuser.h (包括 Windows.h)
Library User32.lib
DLL User32.dll
API 集 在 Windows 8) 中引入的 ext-ms-win-ntuser-window-l1-1-0 (

另请参阅

CBTProc

CallNextHookEx

CallWndProc

CallWndRetProc

概念性

DebugProc

ForegroundIdleProc

GetMsgProc

挂钩

JournalPlaybackProc

JournalRecordProc

KeyboardProc

LowLevelKeyboardProc

LowLevelMouseProc

MessageProc

MouseProc

参考

ShellProc

SysMsgProc

UnhookWindowsHookEx