Хуки в Windows #2
Доброго времени суток, уважаемые подписчики. Сегодня мы подробнее рассмотрим возможности Windows-хуков.
Вначале следует заметить, что существует два разных типа хуков, локальные и глобальные. Не смотря на то, что работают они одинаково, между ними существует огромная разница в исполнении. Тогда как хук-процедуры локальных хуков могут находится где угодно, хук-процедуры глобальных хуков ДОЛЖНЫ находиться в динамической библиотеки. Именно это даёт им возможность быть загруженными в адресное пространство любого приложения, а это, в свою очередь, означает возможность перехватывать сообщения всех приложений одновременно. Как было упомянуто в прошлом выпуске, хуки бывают следующих типов:
WH_CALLWNDPROC - Перехватывает ВСЕ сообщения ДО того как их получает процедура окна
WH_CALLWNDPROCRET - Перехватывает ВСЕ сообщения ПОСЛЕ того как их обработала процедура окна
WH_CBT - Перехватывает сообщения связанные с изменениями окна
WH_DEBUG - Перехватывает ВСЕ сообщения прежде чем они попадают к хук-процедурам
WH_KEYBOARD - Перехватывает "клавиатурные" сообщения, такие как нажатие клавиши
WH_MOUSE - Перехватывает сообщения мышки
WH_MSGFILTER - Перехватывает сообщение посланые диалогом, MessageBox-ом, меню или ScrollBar-ом
WH_SHELL - Перехватывает сообщения оболочки (то есть Windows), такие как изменение текущего языка ввода текста
|
Сегодня мы рассмотрим использование этих типов (кроме WH_CBT) хуков и их процедур.
Первый тип хуков, это WM_CALLWNDPROC. Он вызывается если любое сообщение отправлено (была вызвана функция SendMessage, PostMessage и т.п.), перед тем, как его получает окно. Сообщение нельзя изменять. Хук-процедура получает 3 параметра, хук-код, флаг текущего процесса и указатель на структуру CWPSTRUCT,
CWPSTRUCT struc
lParam dd ?
wParam dd ?
message dd ?
hWnd dd ?
CWPSTRUCT endp
|
Флаг текущего процесса равно нулю, если сообщение не относится к текущему процессу.
Следующий тип, WM_CALLWNDPROCRET отличается нем, что вызывается после обработки сообщения процедурой окна, и тем, что получает указатель на структуру CWPRETSTRUCT вместо CWPSTRUCT.
CWPRETSTRUCT struc
lResult dd ?
lParam dd ?
wParam dd ?
message dd ?
hWnd dd ?
CWPRETSTRUCT endp
|
Такие хуки имеет смысл устанавливать тогда, когда нужен полный контроль за тем, что происходит в системе.
Установка хука с типом WH_DEBUG позволяет программисту решать, какие сообщения будут получены хук-процедурами, а какие нет. Такая хук-процедура вызывается перед вызовом других хук-процедур и от её результата зависит будут ли другие хук-процедуры вызваны. Она получает 3 параметра, хук-код, тип хука, который был перехвачен, и указатель на структуру DEBUGHOOKINFO.
DEBUGHOOKINFO struc
idThread dd ?
idThreadInstaller dd ?
lParam dd ?
wParam dd ?
code dd ?
DEBUGHOOKINFO ends
|
Здесь lParam третий параметр, которой будет получен хук-процедурой (если функция возвращает ненулевое значение, то хук-процедура не будет вызвана и параметр получен не будет), wParam - второй параметр, code, первый параметр.
Хук-процедуры типа WM_MOUSE получают три параметра, хук-код, флаг текущего процесса и указатель на структуру MOUSEHOOKSTRUCT
MOUSEHOOKSTRUCT struc
pt POINT <>
hWnd dd ?
wHitTestCode dd ?
dwExtraInfo dd ?
MOUSEHOOKSTRUCT ends
|
Здесь pt, точка, над которой находится мышка, hWnd - окно которому будет передано сообщение, wHitTestCode - код определяющий нахождение мышки по отношению к окнам, который может принимать одно из следующих значений:
Код | Название | Место нахождения мышки |
-2 | HTERROR | На разделительной полосе между двумя окнами или на рабочем столе, Нажатие мышки в таком мете сопровождается Beep-ом |
-1 | HTTRANSPARENT | На окне, которое закрыто другим окном |
0 | HTNOWHERE | На разделительной полосе между двумя окнами или на рабочем столе |
1 | HTCLIENT | На клиентской части окна (Client Area) |
2 | HTCAPTION | На Title bar-е окна |
3 | HTSYSMENU | Над системным меню или на кнопке закрытия дочерного окна |
4 | HTGROWBOX | Мышкой можно изменять размер окна |
5 | HTMENU | Над меню |
6 | HTHSCROLL | Над горизонтальным Scroll bar-ом |
7 | HTVSCROLL | Над вертикальным Scroll bar-ом |
8 | HTMINBUTTON | Над кнопкой минимизации окна |
9 | HTMAXBUTTON | Над кнопкой максимизации окна |
10 | HTLEFT | Над левым краем окна |
11 | HTRIGHT | Над правым краем окна |
12 | HTTOP | Над верхним краем окна |
13 | HTTOPLEFT | Над верхним левым углом окна |
14 | HTTOPRIGHT | Над верхним правым углом окна |
15 | HTBOTTOM | Над нижнем краем окна |
16 | HTBOTTOMLEFT | Над нижним левым углом окна |
17 | HTBOTTOMRIGHT | Над нижним правым углом окна |
18 | HTBORDER | Над краем окна, размер которого нельзя изменять |
Если хук-процедура возвращает ненулевое значение то сообщение не будет отправлено окну.
Хук процедура WM_SHELL имеет три параметра, но они очень отличаются для WinNT/Win2K/WinXP и Win95/Win98/WinMe. В первом случае следующие сообщение доступны (они передаются первым параметром):
Код | Название | Описание | Второй параметр |
1 | HSHELL_WINDOWCREATED | Произошло создание переднего окна | handle созданного окна |
2 | HSHELL_WINDOWDESTROYED | Происходит уничтожение переднего окна | handle уничтожаемого окна |
3 | HSHELL_ACTIVATESHELLWINDOW | Оболочка (Windows) активизирует своё главное окно | не используется |
Третий параметр не используется. В случае Win95/Win98/WinMe кроме этих сообщений могут быть получены следующие:
Код | Название | Описание | Третий параметр |
4 | HSHELL_WINDOWACTIVATED | Активное окно сменилось | Флаг полноэкранности |
5 | HSHELL_GETMINRECT | Окно минимизировано или максимизировано, система определяет размер окна | указатель на структкру RECT |
6 | HSHELL_REDRAW | Название окна перерисовывается | не используется |
8 | HSHELL_LANGUAGE | Изменён текущий язык | не используется |
Второй параметр - handle окна.
На сегодня это всё. В следующем уроке рассмотрим хук-процедуру WH_CBT. Если есть какие вопросы, пишите. Пишите на Dark_Lord@RusFAQ.ru или Dark_Lord@land.ru.