Программирование на Visual C++. Архив рассылки - Алекс Jenter
Шрифт:
Интервал:
Закладка:
Этот хук используется для посылки Windows клавиатурных и мышиных сообщений таким образом, как будто они проходят через системную очередь. Основное назначение этого хука – проигрывание событий, записанных с помощью хука WH_JOURNALRECORD, но его можно также с успехом использовать для посылки сообщений другим приложениям. Когда к этому хуку прикреплены фильтрующие функции, Windows вызывает первый фильтр в цепочке, чтобы получить событие. Windows игнорирует движения мыши, пока в системе установлен хук WH_JOURNALPLAYBACK. Все остальные события от клавиатуры и мыши сохраняется до тех пор, пока у хука WH_JOURNALPLAYBACK не останется функций-фильтров. Фильтры для этого хука могут располагаться как в DLL, так и в .EXE-файле. Фильтры этого хука должны знать о существовании следующих кодов:
• HC_GETNEXT
• HC_SKIP
HC_GETNEXTWindows вызывает WH_JOURNALPLAYBACK с этим кодом, когда получает доступ к входной очереди потока. В большинстве случаев Windows посылает этот код несколько раз для одного и того же сообщения. В lParam фильтру передается указатель на структуру EVENTMSG (см. выше). Фильтрующая функция должна занести в эту структуру код сообщения message, paramL, и paramH. Обычно эти значения копируются из структур, записанных ранее с помощью хука WH_JOURNALRECORD.
Фильтрующая функция должна сообщить Windows когда нужно начинать обработку посланного сообщения. Windows необходимо для этого два значения: (1) период времени, на которое Windows должно задержать обработку сообщения; либо (2) точное время, когда это сообщение должно быть обработано. Обычно время ожидания обработки вычисляется как разница элементов time структуры EVENTMSG предыдущего сообщения и элемента time той же структуры текущего сообщения. Такой прием позволяет проигрывать сообщения на той же скорости, на которой они были записаны. Если сообщение необходимо проиграть немедленно, функция должна вернуть значение периода времен, равное нулю.
Точное значение времени, в которое нужно обработать сообщение, обычно вычисляется сложением времени, которое Windows должна подождать до начала обработки сообщения и текущего системного времени, получаемого функцией GetTickCount. Для немедленного проигрывания сообщения используйте значение, возвращаемое функцией GetTickCount.
Если система не находится в активном состоянии, Windows использует значения, переданные фильтром, для обработки события. Если система находится в активном состоянии, Windows проверяет системную очередь. Каждый раз, когда она это делает, Windows запрашивает то же самое событие с кодом HC_GETNEXT. Каждый раз, когда функция-фильтр получает код HC_GETNEXT, она должна вернуть новое значение времени ожидания, принимая во внимание время, прошедшее между вызовами функций. Элементы message, paramH и paramL, скорее всего, не потребуют изменений между вызовами.
HC_SKIPWindows вызывает хук WH_JOURNALPLAYBACK после окончания обработки сообщения, полученного от WH_JOURNALPLAYBACK. Это происходит в момент мнимого удаления события из системной очереди (мнимой, так как событие не находилось в системной очереди, а было сгенерировано хуком WH_JOURNALPLAYBACK). Этот код хука сигнализирует фильтрующей функции о том, что событие, возвращенное фильтром во время вызова предыдущего HC_GETNEXT, попало в приложение. Фильтрующая функция должна приготовиться вернуть следующее событие по приходу кода HC_GETEVENT. Когда фильтрующая функция определяет, что больше нечего проигрывать, она должна удалиться из цепочки фильтров хука во время обработки кода HC_SKIP.
WH_KEYBOARDWindows вызывает этот хук когда функции GetMessage или PeekMessage собираются вернуть сообщения WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, WM_SYSKEYDOWN, или WM_CHAR. Когда хук установлен как локальный, эти сообщения должны поступать из входной очереди потока, к которому прикреплен хук. Фильтрующая функция получает виртуальный код клавиши и состояние клавиатуры на момент вызова клавиатурного хука. Фильтры имеют возможность отменить сообщение. Фильтрующая функция, прикрепленная к этому хуку, должна знать о существовании следующих кодов:
• HC_ACTION
• HC_NOREMOVE
HC_ACTIONWindows вызывает хук WH_KEYBOARD с этим кодом при удалении события из системной очереди.
HC_NOREMOVEWindows вызывает хук WH_KEYBOARD с этим кодом, когда клавиатурное сообщение не удаляется из очереди, потому что приложение вызвало функцию PeekMessage с параметром PM_NOREMOVE. При вызове хука с этим кодом не гарантируется передача действительного состояние клавиатуры. Приложение должно знать о возможности возникновения подобной ситуации.
WH_MOUSEWindows вызывает этот хук после вызова функций GetMessage или PeekMessage при условии наличия сообщения от мыши. Подобно хуку WH_KEYBOARD фильтрующие функции получают код — индикатор удаления сообщения из очереди (HC_NOREMOVE), идентификатор сообщения мыши и координаты x и y курсора мыши. Фильтры имеют возможность отменить сообщение. Фильтры для этого хука должны находиться в DLL.
WH_MSGFILTERWindows вызывает этот хук, когда диалоговое окно, информационное окно, полоса прокрутки или меню получают сообщение, либо когда пользователь нажимает комбинацию клавиш ALT+TAB (или ALT+ESC) при активном приложении, установившем этот хук. Данный хук устанавливается для конкретного потока, поэтому его безопасно размещать как в самом приложении, так и в DLL. Фильтрующая функция этого хука получает следующие коды:
• MSGF_DIALOGBOX: Сообщение предназначено либо диалоговому, либо информационному окну.
• MSGF_MENU: Сообщение предназначено меню.
• MSGF_SCROLLBAR: Сообщение предназначено полосе прокрутки.
• MSGF_NEXTWINDOW: Происходит переключение фокуса на следующее окно.
В WINUSER.H определено больше MSGF_-кодов, но в настоящее время они не используются хуком WH_MSGFILTER.
В lParam передается указатель на структуру, содержащую информацию о сообщении. Хуки WH_SYSMSGFILTER вызываются перед хуками WH_MSGFILTER. Если какая-нибудь из фильтрующих функций хука WH_SYSMSGFILTER возвратит TRUE, хуки WH_MSGFILTER не будут вызваны.
WH_SHELLWindows вызывает этот хук при определенных действиях с окнами верхнего уровня – top-level windows (то есть, с окнами, не имеющими владельца). Когда хук установлен как локальный, он вызывается только для окон, принадлежащих потоку, установившему хук. Этот хук является информирующим, поэтому фильтры не могут изменять или отменять событие. В wParam передается хэндл окна; параметр lParam не используется. Для данного хука в WINUSER.H определены три кода:
• HSHELL_WINDOWCREATED: Windows вызывает хук WH_SHELL с этим кодом при создании окна верхнего уровня. Когда фильтр получает управление, это окно уже создано.
• HSHELL_WINDOWDESTROYED: Windows вызывает хук WH_SHELL с этим кодом перед удалением окна верхнего уровня.
• HSHELL_ACTIVATESHELLWINDOW: На данный момент этот код не используется.
WH_SYSMSGFILTERЭтот хук идентичен хуку WH_MSGFILTER за тем исключением, что он имеет системную область видимости. Windows вызывает этот хук, когда диалоговое окно, информационное окно, полоса прокрутки или меню получает сообщение, либо когда пользователь нажимает комбинации клавиш ALT+TAB или ALT+ESC. Фильтр получает те же коды, что и фильтры хука WH_MSGFILTER.
В lParam передается указатель на структуру, содержащую информацию о сообщении. Хуки WH_SYSMSGFILTER вызываются до хуков WH_MSGFILTER. Если любая из фильтрующих функций хука WH_SYSMSGFILTER вернет TRUE, фильтры хука WH_MSGFILTER не будут вызваны.
Это все на сегодня. Пока!
Алекс Jenter [email protected] Красноярск, 2001. Рассылка является частью проекта RSDN.Программирование на Visual C++
Выпуск №48 от 1 июля 2001 г.
Здравствуйте, уважаемые подписчики!
Прежде всего, конечно, хочу попросить прощения на трехнедельный перерыв. Защита выпускной работы – дело серъезное, особенно если на выполнение этой работы осталась всего пара недель ;) Но я успешно защитился, с чем себя и поздравляю. А так же поздравляю вас, дорогие друзья, поскольку сей факт дал вам возможность вновь лицезреть свежие выпуски любимой рассылки на своих мониторах.
Сегодня хочу предложить вашему вниманию одну забавную статью , которая, хотя и написана достаточно давно, во многом не потеряла своей актуальности. А живой язык автора делает чтение по-настоящему приятным.
СТАТЬЯ
Я никогда не буду использовать MFC
Автор: Dennis Crain
Перевод: Алекс Jenter
Источник: MSDN
Скачать программу-пример METAVIEW (22k)
Почему я?Программирование всегда доставляло мне удовольствие. То есть, программирование на C. Кто может сказать, что C не может дать человеку все, что нужно для выполнения работы? Мне казалось, что вся эта рекламная шумиха вокруг C++ и MFC – не более чем старание хитрецов из отдела по маркетингу оправдать свою зарплату. Ведь как бы то ни было, а я и во сне мог писать подпрограммы для Windows. Мне нравились изящные, плавные отступы массивных операторов switch, которые могли позаботиться обо всем, и даже больше, что могло прийти в голову любому Windows-приложению. Я был полон решимости не попасть в водоворот. Черная дыра абстракции меня не получит. Нет уж.