Создание "ловушек" в Delphi
Автор: Chris Cummings (http://wibblovia.topcities.com)
К статье прилагается исходник (~36Kb)
Рано или поздно каждый программист
сталкивается с таким понятим как ловушки. Чтобы
приступить к ипользованию ловушек необходимо
обзавестись windows SDK, который можно так же скачать
с сайта Microsoft. В прилагаемом к статье архиве
содержатся два проекта: hooks.dpr - это пример
приложения работающего с ловушками, а hookdll.dpr -
собственно сама DLL.
Что такое ловушки (Hooks)?
Проще говоря, ловушка - это функция, которая
является частью DLL или часть Вашего приложения,
при помощи которой можно контролировать 'происходящее'
внутри окошек операционной системы. Идея состоит
в том, чтобы написать функцию, которая будет
вызываться каждый раз, когда будет возникать
определённое событие - например, когда
пользователь нажмёт клавишу или переместит
мышку. Ловушки были задуманы Microsoft в первую
очередь, чтобы облегчить программистам отладку
приложений. Однако существует множество
способов использования ловушек - например, чаще
всего при помощи ловушек пишутся клавиатурные
шпионы.
Итак, существует два типа ловушек - глобальные и
локальные. Локальная ловушка отслеживает
только те события, которые происходят только в
одной программе (или потоке). Глобальная
ловушка отслеживает события во всей системе (во
всех потоках). Оба типа ловушек устанавливаются
одинаково, однако единственно отличие
заключается в том, что локальная ловушка
вызывается в пределах Вашего приложения, в то
время как глобальную ловушку необходимо хранить
и вызывать из отдельной DLL.
Процедуры ловушки
Далее следует краткое описание каждой процедуры
и структуры, необходимой для ловушки.
функция The SetWindowsHookEx
Функция SetWindowsHookEx необходима для установки
ловушки. Давайте посмотрим на аргументы данной
функции:
Name
|
Type
|
Description
|
idHook |
Integer |
Число,
представляющее тип ловушки - например WH_KEYBOARD |
lpfn |
TFNHookProc |
Адрес в
памяти функции ловушки |
hMod |
Hinst |
Дескриптор
dll в которой находится функция. Если это
локальная ловушка, то этот параметр 0. |
dwThreadID |
Cardinal |
'id потока',
который Ваша программа будет контролировать.
Если это глобальная ловушка, то параметр должен
быть 0. |
SetWindowsHookEx возвращает дескриптор (т.е.
идентификатор) текущей ловушки, который можно
использовать в функции UnhookWindowsHookEx для
последующего удаления ловушки.
Функция hook
Функция hook это процедура, которая вызывает в
случае, если необходимое нам событие происходит.
Например, если установлена ловушка типа WH_KEYBOARD,
то окно будет передавать в ловушку информацию о
том, какая клавища была нажата. Для Вашей
процедуры hook необходимы следующие аргументы:
Name
|
Type
|
Description
|
Code |
Integer |
Указывает
на то, что означают следующие два параметра |
wParam |
word |
Параметр
размером в 1 слово (word) |
lParam |
longword |
Параметр
размером в 2 слова |
Функция hook возвращает значение типа
longword.
Функция CallNextHookEx
Данная функция предназначена для работы с
цепочкой функций ловушек. Когда ловушка
установлена на определённое событие, то может
возникнуть такая ситуация, когда кто-нибудь тоже
захочет установить ловушку на это же событие.
Когда Вы устанавливаете ловушку при помощи
SetWindowsHookEx, то Ваша процедура ловушки добавляется
в начало списка процедур ловушек. Поэтому
основная задача функции CallNextHookEx заключается в
том, чтобы вызвать следующий в списке обработчик
ловушки. Когда Ваша процедура ловушки завершится,
то она должна вызовать CallNextHookEx, а затем вернуть
заданное значение, в зависимости от типа ловушки.
Функция UnhookWindowsHookEx
Данная функция просто напросто удаляет Вашу
ловушку. Единственный аргумент этой функции - это
дескриптор ловушки, возвращаемы функцией
SetWindowsHookEx.
Локальная ловушка
Сперва давайте создадим локальную ловушку.
Необходимый для неё код содержится в 'local.pas'. При
запуске Hooks.exe будет отображена небольшая форма.
Для использования локальной ловушки достаточно
нажать кнопку Add/Remove Local Hook на этой форме. После
установки локальной ловушки, Вы заметите, что при
нажатии и отпускании любой клавиши будет
раздаваться звуковой сигнал (естевственно, когда
hooks.exe будет иметь фокус. Ведь это локальная
ловушка).
Самая первая функция в local.pas - SetupLocalHook, которая
соственно и создаёт локальную ловушку, указывая
на процедуру ловушки KeyboardHook. В данном случае это
простой вызов SetWindowsHookEx, и, если возвращённый
дескриптор > 0, указывающий на то, что процедура
работает, то сохраняет этот дескриптор в CurrentHook и
возвращает true, иначе будет возвращено значение
false. Далее идёт функция RemoveLocalHook, которая получает
в качестве параметра сохранённый дескриптор в
CurrentHook и использует его в UnhookWindowsHookEx для удаления
ловушки. Последняя идёт процедура hook, которая
всего навсего проверяет - была ли отпущена
клавиша и если надо, то выдаёт звуковой сигнал.
Глобальная ловушка
Глобальная ловушка выглядит немного сложнее. Для
создания глобальной ловушки нам понадобится два
проекта - певый для создания исполняемого файла и
второй для создания DLL, содержащей процедуру
ловушки. Глобальная ловушка, которая
представлена в примере, сохраняет в файле log.txt
каждые 20 нажатий клавиш. Чтобы использовать
глобальную ловушку, достаточно на форме hook.exe
нажать кнопку add/remove global hook. Затем, например, в
записной книжке (notepad) достаточно набрать какой-нибудь
текст, и Вы увидите, что в log.txt этот текст
сохранится.
Наша Dll содержит две процедуры. Первая - это
процедура hook, которая идентична для той, которую
мы рассмотрели для локальной ловушки. Вторая
процедура необходима инициализации dlls, и
содержит текущий номер клавиши, которая была
нажата, а также дескриптор ловушки, которая была
создана.
Исполняемый файл сперва должен загрузить
процедуры из DLL, а затем использовать SetWindowsHookEx,
чтобы создать глобальную ловушку.
В заключении...
Представленный пример объясняет - как
перехватывать события клавиатуры. Чтобы узнать,
как использовать ловушки других типов, таких как
WH_MOUSE, необходимо разобраться с windows SDK.
|