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

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

WH_JOURNALRECORD
0

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

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

Устанавливает процедуру перехватчика, которая записывает входные сообщения, опубликованные в системной очереди сообщений. Этот обработчик полезен для записи макросов. Дополнительные сведения см. в статье Процедура перехватчика 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

Устанавливает процедуру перехватчика, которая получает уведомления, полезные для приложений оболочки. Дополнительные сведения см. в разделе Процедура перехватчика 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 следует вызывать, если не требуется, чтобы уведомления не видели другие приложения.

Перед завершением работы приложение должно вызвать функцию 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 Professional [только классические приложения]
Минимальная версия сервера Windows 2000 Server [только классические приложения]
Целевая платформа Windows
Header 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

Основные понятия

Обработчики