Поделиться через


Функция 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

Устанавливает процедуру перехватчика, которая отслеживает сообщения после их обработки процедурой целевого окна. Дополнительные сведения см. в процедуре обратного вызова HOOKPROC .

WH_CBT
5

Устанавливает процедуру перехватчика, которая получает уведомления, полезные для приложения CBT. Дополнительные сведения см. в процедуре CBTProc перехватчика.

WH_DEBUG
9

Устанавливает процедуру перехватчика, полезную для отладки других процедур перехватчика. Дополнительные сведения см. в процедуре перехватчика DebugProc.

WH_FOREGROUNDIDLE
11

Устанавливает процедуру перехватчика, которая будет вызываться, когда поток переднего плана приложения будет неактивен. Этот перехватчик полезен для выполнения задач с низким приоритетом во время простоя. Дополнительные сведения см. в процедуре перехватчика ForegroundIdleProc.

WH_GETMESSAGE
3

Устанавливает процедуру перехватчика, которая отслеживает сообщения, размещенные в очереди сообщений. Дополнительные сведения см. в процедуре перехватчика GetMsgProc.

WH_JOURNALPLAYBACK
1

Предупреждение

API перехватчиков журналов не поддерживаются начиная с Windows 11 и будут удалены в будущем выпуске. Из-за этого мы настоятельно рекомендуем вместо этого вызывать API SendInput SendInput TextInput.

Устанавливает процедуру перехватчика, которая публикует сообщения, записанные ранее процедурой перехватчика WH_JOURNALRECORD. Дополнительные сведения см. в процедуре перехватчика JournalPlaybackProc.

WH_JOURNALRECORD
0

Предупреждение

API перехватчиков журналов не поддерживаются начиная с Windows 11 и будут удалены в будущем выпуске. Из-за этого мы настоятельно рекомендуем вместо этого вызывать API SendInput SendInput TextInput.

Устанавливает процедуру перехватчика, которая записывает входные сообщения, размещенные в системной очереди сообщений. Этот перехватчик полезен для записи макросов. Дополнительные сведения см. в процедуре JournalRecordProc перехватчика.

WH_KEYBOARD
2

Устанавливает процедуру перехватчика, которая отслеживает сообщения нажатия клавиш. Дополнительные сведения см. в процедуре перехватчика KeyboardProc.

WH_KEYBOARD_LL
13

Устанавливает процедуру перехватчика, которая отслеживает события ввода клавиатуры низкого уровня. Дополнительные сведения см. в процедуре перехватчика LowLevelKeyboardProc.

WH_MOUSE
7

Устанавливает процедуру перехватчика, которая отслеживает сообщения мыши. Дополнительные сведения см. в процедуре перехватчика MouseProc.

WH_MOUSE_LL
14
Устанавливает процедуру перехватчика, которая отслеживает события ввода с низкоуровневой мышью. Дополнительные сведения см. в процедуре перехватчика LowLevelMousePro c.
WH_MSGFILTER
-1

Устанавливает процедуру перехватчика, которая отслеживает сообщения, созданные в результате входного события в диалоговом окне, поле сообщения, меню или полосе прокрутки. Дополнительные сведения см. в процедуре перехватчика MessageProc.

WH_SHELL
10

Устанавливает процедуру перехватчика, которая получает уведомления, полезные для приложений оболочки. Дополнительные сведения см. в процедуре перехватчика ShellProc.

WH_SYSMSGFILTER
6
Устанавливает процедуру перехватчика, которая отслеживает сообщения, созданные в результате входного события в диалоговом окне, поле сообщения, меню или полосе прокрутки. Процедура перехватчика отслеживает эти сообщения для всех приложений на одном рабочем столе с вызывающим потоком. Дополнительные сведения см. в процедуре перехватчика SysMsgProc.

[in] lpfn

Тип: HOOKPROC

Указатель на процедуру перехватчика. Если параметр dwThreadId равен нулю или задает идентификатор потока, созданного другим процессом, параметр lpfn должен указывать на процедуру перехватчика в библиотеке DLL. В противном случае lpfn может указывать на процедуру перехватчика в коде, связанном с текущим процессом.

[in] hmod

Тип: HINSTANCE

Дескриптор библиотеки DLL, содержащий процедуру перехватчика, на которую указывает параметр lpfn. Параметр hMod должен иметь значение NULL, если параметр dwThreadId указывает поток, созданный текущим процессом, и если процедура перехватчика находится в коде, связанном с текущим процессом.

[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 имеет значение NULL, а параметр dwThreadId равен нулю или указывает идентификатор потока, созданного другим процессом.

Вызов функции CallNextHookEx для цепочки с следующей процедурой перехватчика является необязательным, но настоятельно рекомендуется; в противном случае другие приложения, которые установили перехватчики, не получат уведомления об перехватчиках и могут вести себя неправильно в результате. Вы должны вызывать CallNextHookEx, если вам не потребуется предотвратить просмотр уведомления другими приложениями.

В приложениях .NET необходимо убедиться, что обратный вызов не перемещается сборщиком мусора (в противном случае приложение завершится сбоем с помощью ExecutionEngineException). Одним из способов этого является обратный вызов статического метода класса.

Перед завершением приложение должно вызвать функцию 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 равно нулю, библиотеки DLL-интерфейсов перехватчика окон не загружаются в процессе для процессов приложений Магазина Windows и процесса брокера среды выполнения Windows, если они не установлены процессами UIAccess (средствами специальных возможностей). Уведомление поставляется в потоке установщика для этих перехватчиков:

  • WH_JOURNALPLAYBACK
  • WH_JOURNALRECORD
  • WH_KEYBOARD
  • WH_KEYBOARD_LL
  • WH_MOUSE
  • WH_MOUSE_LL
Это поведение аналогично тому, что происходит при несоответствии архитектуры между библиотекой DLL перехватчика и целевым процессом приложения, например, если библиотека DLL перехватчика имеет 32-разрядную версию и процесс приложения 64-разрядный.

Примеры

Пример см. в разделе Установка и освобождение процедур перехватчика.

Заметка

Заголовок winuser.h определяет SetWindowsHookEx как псевдоним, который автоматически выбирает версию ANSI или Юникод этой функции на основе определения константы препроцессора ЮНИКОДа. Сочетание использования псевдонима, нейтрального для кодирования, с кодом, не зависящим от кодирования, может привести к несоответствиям, которые приводят к ошибкам компиляции или среды выполнения. Дополнительные сведения см. в соглашениях о прототипах функций.

Требования

Требование Ценность
минимальные поддерживаемые клиентские Windows 2000 Профессиональный [только классические приложения]
минимальный поддерживаемый сервер Windows 2000 Server [только классические приложения]
целевая платформа Виндоус
заголовка winuser.h (включая Windows.h)
библиотеки User32.lib
DLL User32.dll
набор API ext-ms-win-ntuser-window-l1-1-0 (представлено в Windows 8)

См. также

функция CallNextHookEx

функции CallWindowProc

функция UnhookWindowsHookEx

CBTProc

CallWndProc

CallWndRetProc

DebugProc

ForegroundIdleProc

GetMsgProc

JournalPlaybackProc

JournalRecordProc

KeyboardProc

LowLevelKeyboardProc

LowLevelMouseProc

MessageProc

MouseProc

ShellProc

SysMsgProc

концептуальные

крючки