Excel. Трюки и эффекты
Шрифт:
В случае успешного создания ловушки функция SetWindowsHookEx возвращает дескриптор новой ловушки (ненулевое значение).
Для удаления ловушки используется функция UnhookWindowsHookEx, принимающая единственный параметр – дескриптор ловушки, возвращенный функцией SetWindowsHookEx. Причем удаление ловушки нужно производить обязательно, поэтому по крайней мере при закрытии приложения не следует забывать вызывать функцию UnhookWindowsHookEx.
Теперь несколько слов о функции CallNextHookEx. Ее объявление имеет следующий вид:
function CallNextHookEx(hhk: HHOOK; nCode: Integer;
wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
В
Виды ловушек
Приведем список некоторых простых типов ловушек, а именно констант из модуля Windows, их обозначающих и передаваемых в функцию SetWindowsHookEx:
• WH_CALLWNDPROC – функция ловушки вызывается каждый раз до вызова функции обработки сообщений окон, созданных наблюдаемым потоком;
• WH_CALLWNDPROCRET – вызывается каждый раз при возврате из функции обработки сообщений окон наблюдаемого потока;
• WH_KEYBOARD – функция ловушки вызывается перед обработкой сообщений WM_KEYDOWN и WM_KEYUP оконной функцией исследуемого потока;
• WH_MOUSE – вызывается перед обработкой оконной функцией наблюдаемого потока сообщений от манипулятора «мышь».
Рассмотрим, какое значение имеют параметры 1 Par am и wParam функции-ловушки в каждом из перечисленных случаев.
Перехват вызова оконной функции
Итак, для ловушки WH_CALLWNDPROC, которая, кстати, используется в рассматриваемом далее приложении, два последних параметра функции-ловушки трактуются следующим образом:
• wParam – равен нулю, если сообщение послано в окно тем же потоком, в котором исполняется функция ловушки, и не равен нулю, если сообщение послано другим потоком;
• lParam – указатель на структуру TCWPStruct, содержащую информацию о сообщении, которое передано окну (и будет передано в оконную функцию).
Объявление структуры TCWPStruct с описанием ее полей выглядит следующим образом:
type TCWPStruct = packed record
lParam: LPARAM; //Параметр сообщения
wParam: WPARAM; //Параметр сообщения
message: UINT; //Код сообщения
hwnd: HWND; //Окно, которому адресовано сообщение
end;
Ниже приводится пример преобразования параметра lParam функции ловушки к указателю на структуру с последующей проверкой кода сообщения (фрагмент программы):
var hook_data : hook_data: ^TCWPStruct;
begin
hook_data := Pointer(lParam);
if hook_data^.message = WM_SIZE then
begin
//Реагируем на изменение размера окна
end;
end;
Получение
доступа к данным, передаваемым в остальные функции ловушки (а именно, несложное преобразование типов у операции с указателем), осуществляется аналогичным образом, поэтому более демонстрироваться не будет.Перехват возврата из оконной процедуры
Для ловушки WH_CALLWNDPROCRET параметры wParam и lParam функции-ловушки следует трактовать следующим образом:
• wParam – равен нулю, если сообщение послано другим процессом, и не равен нулю в противном случае;
• lParam – указатель на структуру TCWPRetStruct, содержащую информацию о сообщении, которое передано окну (и будет передано в оконную функцию).
Объявление структуры TCWPRetStruct с описанием ее полей выглядит следующим образом:
type TCWPRetStruct = packed record
lResult: LRESULT; //Значение, возвращенное оконной функцией
lParam: LPARAM; //Параметр сообщения
wParam: WPARAM; //Параметр сообщения
message: UINT; //Код сообщения
hwnd: HWND; //Дескриптор окна-получателя
end;
Перехват сообщений клавиатурного ввода
Для ловушки WH_KEYBOARD параметры wParam и lParam функции-ловушки следует трактовать следующим образом:
• wParam – код нажатой клавиши;
• lParam – первые 16 бит этого параметра означают количество повторений нажатия; старшие 16 бит используются для дополнительного описания состояния клавиатуры в момент нажатия клавиши.
Параметры wParam и lParam полностью аналогичны параметрам сообщений WM_KEYDOWN И WM_KEYUP.
Перехват сообщений от мыши
В ловушку WH_KEYBOARD в параметрах wParam и lParam передаются следующие значения:
• wParam – код сообщения мыши;
• lParam– указатель на структуру TMouseHookStruct.
Объявление структуры TMouseHookStruct с описанием полей выглядит следующим образом:
type TMouseHookStruct = packed record
pt: TPoint; //Экранные координаты указателя мыши
hwnd: HWND; //Дескриптор окна-получателя сообщения
wHitTestCode: UINT; //Код, возвращенный оконной функцией
//в ответ на сообщение WM_NCHITTEST
dwExtraInfo: DWORD; //Дополнительные данные
end;
Если вы забыли, какое значение имеет для окна coo6nreHHeWM_NCHITTEST, то можете вновь обратиться к гл. 1.
Расположение функции-ловушки и DLL
Теперь поговорим немного о расположении функции-ловушки.
Казалось бы, что здесь может быть такого: написал функцию в модуле, строго соответствующую приведенному ранее прототипу, передал ее адрес в функцию SetWindowsHookEx и используй ловушку. Но не так все просто. Функция ловушки может находиться в исполняемом файле только в том случае, если предполагается использовать ее для перехвата сообщений потока (потоков) того же процесса. Тогда в функцию создания ловушки в качестве параметра hmod следует передавать нулевое значение.