| Если ты плохо воспринимаешь Си-шный код, на Delphi заголовок выглядит так:SetWindowsHookEx(idHook: Integer; lpfn: TFNHookProc; hmod: HINST; dwThreadId:DWORD): HHOOK;Функция SetWindowsHookEx() в случае установки hook\'a возвращает его дескриптор, в случае ошибки возвращает 0.Разберем подробней все входящие параметры этой функции: 1. idHook - константа, определяет типа устанавливаемого hook\'а. Может принимать одно из ниже перечисленных значений: WH_CALLWNDPROC - Следит за сообщениями до отправки в оконную функцию и вызывается, когда процедуре окна посылается сообщение. Ловушка срабатывает при каждом вызове функции SendMessage. WH_CALLWNDPROCRET - Контролирует сообщения после их отправки в оконную функцию. WH_CBT - Вызывается перед обработкой большинства сообщений окон, мыши и клавиатуры (созданием окон, активация окон, уничтожением окон, сменой размера окон, перед установкой фокуса и.т.п.) WH_DEBUG - Вызывается перед любой другой ловушкой. Полезно для отладки hook\'ов. WH_GETMESSAGE - Вызывается, когда из очереди приложения считывается сообщение. WH_HARDWARE - Вызывается, когда из очереди приложения считывается сообщение установленного на компьютере оборудования. WH_JOURNALPLAYBACK - Вызывается, когда из очереди системы считывается сообщение. Применяется для добавления в очередь системных событий. WH_JOURNALRECORD - Вызывается, когда из очереди системы запрашивается какое-нибудь событие. Применяется для регистрации системных событий. WH_KEYBOARD - Вызывается, когда из очереди приложения считывается сообщения WM_Keydown или WM_Keyup. Одна из самых распространенных ловушек -). WH_MOUSE - Вызывается, когда из очереди приложения считывается сообщение мыши. WH_MSGFILTER - Вызывается, когда сообщение должно быть обработано диалоговым окном приложения, меню или окном приложения. WH_SHELL - Вызывается, когда создаются и разрушаются окна верхнего уровня или когда приложению-оболочке требуется стать активным. 2. lpfn - указатель на саму hook функцию. Ее заголовок:function HOOKFUNCTION(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULTstdcall;Значения входящих параметров зависят от типа hook\'a. Если ставится глобальный hook, эта функция должна обязательно находиться в dll. 3. hmod - принимает значение hInstance или дескриптор DLL (в глобальных ловушках). 4. dwThreadId - идентифицирует поток, в который вставляется ловушка. В глобальных hook\'ах этот параметр должен быть равен 0. Для удаления установленной ловушки существует функция UnhookWindowsHookEx(). В качестве параметра нужно использовать указатель (дескриптор) на hook функцию (значение, которое возвращает функция SetWindowsHookEx()). Ну вот и все, с основами ты ознакомлен. Теперь напишем маленькую шуточную программу, ставящую hook на считывания сообщений мыши (WH_MOUSE). Сделаем так, чтобы при нажатии на правую кнопку мыши скрывалась кнопка \"Пуск\", при нажатии на левую - появлялась, среднею - изменялся заголовок активного окна. Сама hook функция будет находиться в dll. Кроме того, в dll будут находиться две процедуры - sethook() и removehook(), соответственно устанавливающие и удаляющие ловушку.Привожу код dll библиотеки: --- lib.dll --- library lib; uses windows,messages; var H : THandle; {Hook-функция} function hook(c0de, wParam, lParam : integer): Lresult; stdcall; {Объявления переменных} var w : THandle; hw: hwnd; begin {Если c0de не меньше 0, все в порядке, продолжаем} if c0de >= 0 then begin { Если wParam = WM_RBUTTONUP, т.е. нажата правая кнопка мыши, получаем хендл (handle) кнопки \"Пуск\" и скрываем ее } case wParam of WM_RBUTTONUP : begin W:= FindWindow(\'Shell_TrayWnd\', nil); W:= FindWindowEx(W, HWND(0),\'Button\', nil); ShowWindow(W, SW_hide); end; { Если wParam = WM_LBUTTONUP, т.е. нажата левая кнопка мыши, получаем хендл кнопки пуск и показываем ее } WM_LBUTTONUP: begin W:= FindWindow(\'Shell_TrayWnd\', nil); W:= FindWindowEx(W, HWND(0),\'Button\', nil); ShowWindow(W, SW_SHOW); end; { Если wParam = WM_MBUTTONUP, т.е. нажата средняя кнопка мыши, получаем указатель на заголовок активного окна и изменяем его } WM_MBUTTONUP: begin hw:=GetForegroundWindow; SetWindowText(hw,\'EXAMPLE OF WINDOWS HOOK (WH_MOUSE) - by Dark Lord \'); end; end; end else {Если c0de меньше 0} begin {Вызываем следующую ловушку в цепочке ловушек Windows и выходим из процедуры} result := CallNextHookEx(H, c0de, wParam, lParam); exit; end; {Вызываем следующую ловушку в цепочке ловушек Windows} result := CallNextHookEx(H, c0de, wParam, lParam); End; { Процедура установки ловушки, если не удалось установить - выводим сообщение об ошибке } procedure sethook; begin H:= SetWindowsHookEx(WH_MOUSE, @hook, hInstance, 0); if H = 0 then messagebox(0,\'hmmm..\',\'ERROR\',mb_iconhand); end; { Процедура удаления ловушки } procedure removehook; begin UnhookWindowsHookEx(H); end; { Экспорт процедур установки и удаления hook\'a } exports sethook index 1 name \'sethook\', removehook index 2 name \'removehook\'; end. --- lib.dll --- В самой программе ловушка будет устанавливаться вызовом из dll процедуры sethook, удаляться - вызовом процедуры removehook. Пример установки и удаления hook\'а, а также исходник dll библиотеки есть в прилагающемся архиве.В данной статье были рассмотрены только основы установки ловушек. Есть немалое количество нюансов и возникающих проблем при установке нескольких hook\'ов, установки hook\'ов в разных ОС (особенно это касается глобальных ловушек). Для получения подробностей по этим вопросам рекомендую использовать Win32 API Reference или MSDN (если нет дисков с MSDN - прогуляйся наhttp://msdn.microsoft.com, здесь правда не вся информация, но большая ее часть). Ну что же, на сегодня это все. Будь здоров! -)Исходники
|