UnhookWindowsHookEx
Для удаления функции-фильтра из очереди хука вызовите функцию UnhookWindowsHookEx. Эта функция принимает хэндл хука, полученный от SetWindowsHookExи возвращает логическое значение, показывающее успех операции. На данный момент UnhookWindowsHookExвсегда возвращает TRUE.
Фильтрующие функции
Фильтрующие ( хуковые ) функции – это функции, прикрепленные к хуку. Из-за того, что эти функции вызываются Windows, а не приложением, их часто называют функциями обратного вызова (callback functions). Из соображений целостности изложения, эта статья использует термин фильтрующие функции (или функции-фильтры ).
Все фильтрующие функции должны быть описаны следующим образом:
LRESULT CALLBACK FilterFunc(int nCode, WPARAM wParam, LPARAM lParam)
Все функции-фильтры должны возвращать LONG. Вместо FilterFunc должно стоять имя вашей фильтрующей функции.
Параметры
Фильтрующие функции принимают три параметра: nCode (код хука), wParam , и lParam . Код хука – это целое значение, которое передает функции дополнительную информацию. К примеру, код хука может описывать событие, которое привело к срабатыванию хука.
В первых версиях Windows (до 3.1), код хука указывал, должна функция-фильтр обработать событие сама или вызвать DefHookProc. Если код хука меньше нуля, фильтр не должен был обрабатывать событие, а должен был вызвать DefHookProc, передавая ей три своих параметра без изменений. Windows использовала отрицательные коды для организации цепочки функций-фильтров с помощью приложений.
Windows 3.1 также требует при отрицательном коде хука вызывать CallNextHookExс неизмененными параметрами, плюс к тому функция должна вернуть значение, которое вернет CallNextHookEx. Но Windows 3.1 никогда не посылает фильтрующим функциям отрицательных кодов.
Второй параметр функции-фильтра, wParam , имеет тип WPARAM, и третий параметр, lParam , имеет тип LPARAM. Эти параметры передают информацию фильтрующим функциям. У каждого хука значения wParam и lParam различаются. Например, фильтры хука WH_KEYBOARD получают в wParam виртуальный код клавиши, а в lParam – состояние клавиатуры на момент нажатия клавиши. Фильтрующие функции, прикрепленные к хуку WH_MSGFILTER получают в wParam значение NULL, а в lParam – указатель на структуру, описывающую сообщение. За полным описанием значений аргументов каждого типа хука обратитесь к Win32 SDK for Windows NT, руководствуясь списком фильтрующих функций, приведенным ниже.
Хук |
Имя статьи с описанием фильтрующей функции в SDK |
WH_CALLWNDPROC |
CallWndProc |
WH_CBT |
CBTProc |
WH_DEBUG |
DebugProc |
WH_GETMESSAGE |
GetMsgProc |
WH_JOURNALRECORD |
JournalRecordProc |
WH_JOURNALPLAYBACK |
JournalPlaybackProc |
WH_SHELL |
ShellProc |
WH_KEYBOARD |
KeyboardProc |
WH_MOUSE |
MouseProc |
WH_MSGFILTER |
MessageProc |
WH_SYSMSGFILTER |
SysMsgProc |
Вызов следующей функции в цепочке фильтрующих функций
Когда хук уже установлен, Windows вызывает первую функцию в очереди, и на этом ее ответственность заканчивается. После этого функция ответственна за то, чтобы вызвать следующую функцию в цепочке. В Windows имеется функция CallNextHookExдля вызова следующего фильтра в очереди фильтров. CallNextHookExпринимает четыре параметра.
Первый параметр – это значение, возвращенное функцией SetWindowsHookEx. В настоящее время Windows игнорирует это значение, но в будущем это может измениться.
Следующие три параметра – nCode, wParam , и lParam – Windows передает дальше по цепочке функций.
Windows хранит в своих внутренних структурах цепочку фильтрующих функций и следит за тем, какая функция вызывается в настоящий момент. При вызове CallNextHookExwindows определяет следующую функцию в очереди и вызывает ее.
Иногда функции-фильтры могут не пожелать передать обработку события другим фильтрам в той же цепочке. В частности, когда хук позволяет функции отменить событие и функция решает так поступить, она не должна вызывать CallNextHookEx. Когда фильтрующая функция модифицирует сообщение, она может решить не передавать его остальным функциям, ожидающим в очереди.
Из-за того, что фильтры никак не сортируются при помещении их в очередь, вы не можете быть уверены, где находится ваша функция в любой момент времени кроме момента установки, когда ваша функция помещается в самое начало очереди. В результате, вы никогда не можете точно знать, что каждое событие в системе дойдет до вашего фильтра. Фильтрующая функция перед вашей функцией в цепочке – то есть функция, которая была установлена позже вашей – может не передать вам обработку события.
Читать дальше