Установка и удаление процедур фильтра (hook)
Вы можете установить процедуру фильтра при помощи вызова функции SetWindowsHookEx и определения типа фильтра (hook), вызывающего процедуру, который должен либо связать процедуру со всеми потоками одного и того же рабочего стола, как вызывающий поток, или с конкретным потоком и указателем на точку входа в процедуру.
Вы должны разместить процедуру глобального фильтра (hook) в динамически подключаемой библиотеке (DLL) отделенной от приложения, устанавливающего процедуру фильтра (hook). Устанавливающее приложение должно иметь дескриптор модуля DLL прежде, чем оно может установить процедуру фильтра (hook). Чтобы извлечь дескриптор модуля DLL, вызовите функцию LoadLibrary с именем DLL. После того, как Вы получите дескриптор, то можете вызвать функцию GetProcAddress, чтобы извлечь указатель на процедуру фильтра (hook). Наконец, используйте SetWindowsHookEx, чтобы установить адрес процедуры фильтра (hook) в соответствующую цепочку фильтра (hook). SetWindowsHookEx передает дескриптор модуля, указатель на точку входа в процедуру фильтра (hook) и 0 для идентификатора потока, указывая, что процедура фильтра (hook) должна быть связана со всеми потоками одного и того же рабочего стола, как вызывающего потока. Эта последовательность действий показывается в примере ниже.
HOOKPROC hkprcSysMsg; static HINSTANCE hinstDLL; static HHOOK hhookSysMsg; hinstDLL = LoadLibrary((LPCTSTR) "c:\\windows\\sysmsg.dll"); hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc"); hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER,hkprcSysMsg,hinstDLL,0); |
Вы можете избавиться от конкретной для потока процедуры фильтра (hook) (удалить ее адрес из цепочки фильтра (hook)) при помощи вызова функции UnhookWindowsHookEx, определяя дескриптор удаляемой процедуры фильтра (hook). Удаляйте процедуру фильтра (hook) как только ваше приложение больше в ней не нуждается.
Вы можете избавиться от процедуры глобального фильтра (hook), используя UnhookWindowsHookEx, но эта функция не освобождает DLL содержащую процедуры фильтра (hook). Это происходит так потому, что процедуры глобального фильтра (hook) вызываются в контексте процесса каждого приложения на рабочем столе, совершая неявный вызов функции LoadLibrary для всех этих процессов. Поскольку вызов функции FreeLibrary не может делаться для другого процесса, то тогда нет никакого способа освободить DLL. Система, в конечном счете, освобождает DLL после того, как все процессы, явно связанные с DLL или закончили работу, или вызвали FreeLibrary, а все процессы, которые обратились к процедуре фильтра (hook) возобновили обработку за пределами DLL.
Альтернативный метод для того, чтобы установить процедуру глобального фильтра (hook) состоит в том, чтобы предоставить инсталлирующую функцию в DLL, вместе с процедурой фильтра (hook). В этом методе, инсталлирующее приложение не нуждается в дескрипторе модуля DLL. Связываясь с DLL, программа получает доступ к инсталлирующей функции. Инсталлирующая функция может предоставить дескриптор модуля DLL и другие детали при вызове SetWindowsHookEx. DLL может также содержать и функцию, которая освобождает процедуру глобального фильтра (hook); приложение может вызвать эту избавляющую от фильтра (hook) функцию при завершении работы.