Функция SetWindowsHookExA (winuser.h)

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

Синтаксис

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

Параметры

[in] idHook

Тип: int

Тип устанавливаемой процедуры перехватчика. Этот параметр может принимать одно из указанных ниже значений.

Значение Значение
WH_CALLWNDPROC
4

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

WH_CALLWNDPROCRET
12
Устанавливает процедуру перехватчика, которая отслеживает сообщения после их обработки процедурой окна назначения. Дополнительные сведения см. в процедуре перехватчика [функция обратного вызова HOOKPROC](nc-winuser-hookproc.md).
WH_CBT
5
Устанавливает процедуру перехватчика, которая получает уведомления, полезные для приложения CBT. Дополнительные сведения см. в разделе Процедура перехватчика CBTProc .
WH_DEBUG
9

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

WH_FOREGROUNDIDLE
11

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

WH_GETMESSAGE
3

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

WH_JOURNALPLAYBACK
1

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

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

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

WH_JOURNALRECORD
0

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

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

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

WH_KEYBOARD
2

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

WH_KEYBOARD_LL
13
Устанавливает процедуру перехватчика, которая отслеживает события ввода с клавиатуры низкого уровня. Дополнительные сведения см. в процедуре перехватчика [LowLevelKeyboardProc](/windows/win32/winmsg/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

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

Обработчики