Хуки в 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.