Рейтинговые книги
Читем онлайн Программирование на Visual C++. Архив рассылки - Алекс Jenter

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 69 70 71 72 73 74 75 76 77 ... 156

Прикрепление одной или нескольких фильтрующих функций к какому-нибудь хуку называется установкой хука. Если к одному хуку прикреплено несколько фильтрующих функций, Windows реализует очередь функций, причем функция, прикрепленная последней, оказывается в начале очереди, а самая первая функция – в ее конце.

Когда к хуку прикреплена одна или более функций-фильтров и происходит событие, приводящее к срабатыванию хука, Windows вызывает первую функцию из очереди функций-фильтров. Это действие называется вызовом хука. К примеру, если к хуку CBT прикреплена функция и происходит событие, после которого срабатывает хук (допустим, идет создание окна), Windows вызывает CBT-хук, то есть первую функцию из его очереди.

Для установки и доступа к фильтрующим функциям приложения используют функции SetWindowsHookEx и UnhookWindowsHookEx.

Хуки предоставляют мощные возможности для приложений Windows. Приложения могут использовать хуки в следующих целях:

• Обрабатывать или изменять все сообщения, предназначенные для всех диалоговых окон (dialog box), информационных окон (message box), полос прокрутки (scroll bar), или меню одного приложения (WH_MSGFILTER).

• Обрабатывать или изменять все сообщения, предназначенные для всех диалоговых окон, информационных окон, полос прокрутки, или меню всей системы (WH_SYSMSGFILTER).

• Обрабатывать или изменять все сообщения в системе (все виды сообщений), получаемые функциями GetMessage или PeekMessage (WH_GETMESSAGE).

• Обрабатывать или изменять все сообщения (любого типа), посылаемые вызовом функции SendMessage (WH_CALLWNDPROC).

• Записывать или проигрывать клавиатурные и мышиные события (WH_JOURNALRECORD, WH_JOURNALPLAYBACK).

• Обрабатывать, изменять или удалять клавиатурные события (WH_KEYBOARD).

• Обрабатывать, изменять или отменять события мыши (WH_MOUSE).

• Реагировать на определенные действия системы, делая возможным разработку приложений компьютерного обучения – computer-based training (WH_CBT).

• Предотвратить вызов другой функции-фильтра (WH_DEBUG).

Приложения уже используют хуки для следующих целей:

• Добавить поддержку кнопки F1 для меню, диалоговых и информационных окон (WH_MSGFILTER).

• Обеспечить запись и воспроизведение событий мыши и клавиатуры, часто называемых макросами. Например, программа Windows Recorder использует хуки для записи и воспроизведения (WH_JOURNALRECORD, WH_JOURNALPLAYBACK).

• Следить за сообщениями, чтобы определить, какие сообщения предназначены определенному окну или какие действия генерирует сообщение (WH_GETMESSAGE, WH_CALLWNDPROC). Утилита Spy из Win32T Software Development Kit (SDK) for Windows NTT использует для этих целей хуки. Исходные тексты Spy можно найти в SDK.

• Симулировать мышиный и клавиатурный ввод (WH_JOURNALPLAYBACK). Хуки – единственный надежный способ симуляции этих действий. Если попытаться имитировать их через посылку сообщений, не будет происходить обновление состояния клавиатуры или мыши во внутренних структурах Windows, что может привести к непредсказуемому поведению. Если для воспроизведения клавиатурных или мышиных событий используются хуки, эти события обрабатываются в точности так, как и настоящий ввод с клавиатуры или мыши. Microsoft Excel использует хуки для реализации макрофункции SEND.KEYS.

• Сделать возможным использование CBT приложениями Windows (WH_CBT). Хук WH_CBT значительно облегчает разработку CBT-приложений.

Как пользоваться хуками

Чтобы пользоваться хуками, вам необходимо знать следующее:

• Как использовать функции Windows для добавления и удаления фильтрующих функций из очереди функций хука.

• Какие действия должна будет выполнить фильтрующая функция, которую вы устанавливаете.

• Какие существуют виды хуков, что они могут делать, и какую информацию (параметры) они передают вашей функции.

Функции Windows для работы с хуками

Приложения Windows используют функции SetWindowsHookEx, UnhookWindowsHookEx, и CallNextHookEx для управления очередью функций-фильтров хука. До версии 3.1 Windows предоставляла для управления хуками функции SetWindowsHook, UnhookWindowsHook, и DefHookProc. Хотя эти функции до сих пор реализованы в Win32, у них меньше возможностей, чем у их новых (Ex) версий. Всегда старайтесь использовать только эти новые функции в своих проектах.

SetWindowsHookEx и UnhookWindowsHookEx описаны ниже. Обратитесь к разделу "Вызов следующей функции в очереди фильтрующих функций" за информацией по CallNextHookEx.

SetWindowsHookEx

Функция SetWindowsHookEx добавляет функцию-фильтр к хуку. Эта функция принимает четыре аргумента:

Целочисленный код, описывающий хук, к которому будет прикреплена фильтрующая функция. Эти коды определены в WINUSER.H и будут описаны позднее.

Адрес функции-фильтра. Эта функция должна быть описана как экспортируемая включением ее в секцию EXPORTS файла определения приложения или библиотеки динамической линковки (DLL), или использованием соответствующих опций компилятора.

Хэндл модуля, содержащего фильтрующую функцию. В Win32 (в отличие от Win16), этот параметр должен быть NULL при установке хука на поток (см. ниже), но данное требование не является строго обязательным, как указано в документации. При установке хука для всей системы или для потока в другом процессе, нужно использовать хэндл DLL, содержащей функцию-фильтр.

Идентификатор потока, для которого устанавливается хук. Если этот идентификатор ненулевой, установленная фильтрующая функция будет вызываться только в контексте указанного потока. Если идентификатор равен нулю, установленная функция имеет системную область видимости и может быть вызвана в контексте любого потока в системе. Приложение или библиотека могут использовать функцию GetCurrentThreadId для получения идентификатора текущего потока.

Некоторые хуки могут быть установлены только с системной областью видимости, некоторые можно устанавливать как для всей системы, так и для одного потока, как показано в следующей таблице.

Хук Область видимости WH_CALLWNDPROC Поток или вся система WH_CBT Поток или вся система WH_DEBUG Поток или вся система WH_GETMESSAGE Поток или вся система WH_JOURNALRECORD Только система WH_JOURNALPLAYBACK Только система WH_FOREGROUNDIDLE Поток или вся система WH_SHELL Поток или вся система WH_KEYBOARD Поток или вся система WH_MOUSE Поток или вся система WH_MSGFILTER Поток или вся система WH_SYSMSGFILTER Только система

Для любого данного типа хука, первыми вызываются хуки потоков, и только затем системные хуки.

Есть несколько причин, по которым лучше использовать потоковые хуки вместо системных. Хуки потоков:

• Не создают лишней работы приложениям, которые не заинтересованы в вызове хука.

• Не помещают все события, относящиеся к хуку, в очередь (так, чтобы они поступали не одновременно, а одно за другим). Например, если приложение установит клавиатурный хук для всей системы, то все клавиатурные сообщения будут пропущены через фильтрующую функцию этого хука, оставляя неиспользованными системные возможности многопотоковой обработки ввода. Если эта функция прекратит обрабатывать клавиатурные события, система будет выглядеть зависшей, хотя на самом деле и не зависнет. Пользователь всегда сможет использовать комбинацию CTRL+ALT+DEL для того, чтобы выйти из системы (log-out) и решить проблему, но ему это вряд ли понравится. К тому же, пользователь может не знать, что подобную ситуацию можно решить, войдя в систему под другим именем (log-out/log-in).

• Не требуют нахождения функции-фильтра в отдельной DLL. Все системные хуки и хуки для потоков в другом приложении должны находиться в DLL.

• Им не нужно разделять данные между DLL, загруженными в разные процессы. Фильтрующие функции с системной областью видимости, которые обязаны находиться в DLL, должны к тому же разделять необходимые данные с другими процессами. Так как такое поведение не является типичным для DLL, вы должны принимать специальные меры предосторожности при реализации системных фильтрующих функций. Если функция-фильтр не умеет разделять данные и неправильно использует данные в другом процессе, этот процесс может рухнуть.

SetWindowsHookEx возвращает хэндл установленного хука (тип hhook). Приложение или библиотека должны использовать этот хэндл для вызова функции UnhookWindowsHookEx. SetWindowsHookEx возвращает null если она не смогла добавить функцию к хуку. SetWindowsHookEx также устанавливает код последней ошибки в одно из следующих значений для индикации неудачного завершения функции.

1 ... 69 70 71 72 73 74 75 76 77 ... 156
На этой странице вы можете бесплатно читать книгу Программирование на Visual C++. Архив рассылки - Алекс Jenter бесплатно.
Похожие на Программирование на Visual C++. Архив рассылки - Алекс Jenter книги

Оставить комментарий