Delphi. Трюки и эффекты - страница 92

Шрифт
Интервал

стр.

10.1. Ловушки Windows

Из предыдущих глав вам должен быть понятен или, по крайней мере, известен механизм, который используется Windows для управления окнами приложений, – сообщения. Вероятно, большая мощь этого механизма и в то же время его уязвимость состоят в возможности посылки сообщений любым окнам (окнам одного процесса или окнам других процессов).

В Windows также предусмотрен мощный механизм, позволяющий следить за некоторыми важными событиями в системе и, конечно, производить мониторинг сообщений, получаемых различными окнами. Речь идет об установке так называемых ловушек. Ловушка представляет собой функцию, вызываемую при возникновении определенного события, например перед получением каким-либо окном нового сообщения, при нажатии клавиши, записи события в системный журнал и т. д.: все зависит от того, для каких событий разработчики предусмотрели ловушки. Интересен тот факт, что в Windows предусмотрены даже ловушки для отладки других ловушек.

Мы рассмотрим некоторые наиболее простые виды ловушек, перехватывающих сообщения окон. По глобальности действия рассмотренные нами ловушки являются устанавливаемыми на отдельный поток: при ошибке в функции-ловушке это безопаснее для системы.

Начинается создание ловушки с написания собственно функции-ловушки, имеющей следующий прототип:

...

function HookProc(code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT stdcall;

Параметр code используется для обозначения тех случаев, когда функция ловушки должна вызвать специальную API-функцию CallNextHookEx и вернуть значение, возвращенное ею. Назначения параметров wParamи lParam этой функции сильно зависят от того, для реакции на какое именно событие ловушка используется.

Для регистрации ловушки используется API-функция SetWindowsHookEx, имеющая следующий прототип:

...

function SetWindowsHookEx(idHook: Integer; //Тип ловушки

lpfn: TFNHookProc; //Адрес функции-ловушки

hmod: HINST; //Используемый модуль, в котором

//расположена функция ловушки

dwThreadId: DWORD //Идентификатор потока, для

//которого создается ловушка

): HHOOK; stdcall;

В случае успешного создания ловушки функция SetWindowsHookEx возвращает дескриптор новой ловушки (ненулевое значение).

Для удаления ловушки используется функция UnhookWindowsHookEx, принимающая единственный параметр – дескриптор ловушки, возвращенный функцией SetWindowsHookEx. Причем удаление ловушки нужно производить обязательно, поэтому по крайней мере при закрытии приложения не следует забывать вызывать функцию UnhookWindowsHookEx.

Теперь несколько слов о функции CallNextHookEx. Ее объявление имеет следующий вид:

...

function CallNextHookEx(hhk: HHOOK; nCode: Integer;

wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;

В чем важность этой функции? Она предназначена для продолжения передачи сообщения по цепочке ловушек (ведь одновременно несколько приложений могут создать несколько ловушек). Вызов этой функции настоятельно рекомендуется осуществлять в любом случае (независимо от значения параметра code функции-ловушки), только если целью не стоит блокирование других ловушек.

Виды ловушек

Приведем список некоторых простых типов ловушек, а именно констант из модуля Windows, их обозначающих и передаваемых в функцию SetWindowsHookEx:

• WH_CALLWNDPROC – функция ловушки вызывается каждый раз до вызова функции обработки сообщений окон, созданных наблюдаемым потоком;

• WH_CALLWNDPROCRET – вызывается каждый раз при возврате из функции обработки сообщений окон наблюдаемого потока;

• WH_KEYBOARD – функция ловушки вызывается перед обработкой сообщений WM_KEYDOWN и WM_KEYUP оконной функцией исследуемого потока;

• WH_MOUSE – вызывается перед обработкой оконной функцией наблюдаемого потока сообщений от манипулятора «мышь».

Рассмотрим, какое значение имеют параметры 1 Par am и wParam функции-ловушки в каждом из перечисленных случаев.

Перехват вызова оконной функции

Итак, для ловушки WH_CALLWNDPROC, которая, кстати, используется в рассматриваемом далее приложении, два последних параметра функции-ловушки трактуются следующим образом:

• wParam – равен нулю, если сообщение послано в окно тем же потоком, в котором исполняется функция ловушки, и не равен нулю, если сообщение послано другим потоком;


стр.

Похожие книги