Операционная система Microsoft Windows 3.1 для программиста -том 3


Листинг 3.12. Файл winhook/kbhook.cpp - часть 6


Перед установкой фильтров функция проверяет содержимое глобального флага bHooked. Этот флаг изначально находится в сброшенном состоянии и устанавливается только после встраивания фильтров. Проверка флага позволяет исключить ошибочное повторное встраивание фильтров.

Функция SetKbHook устанавливает два фильтра - типа WH_KEYBOARD и типа WH_GETMESSAGE. Оба фильтра встраиваются для всей системы в целом, так как последний параметр функции SetWindowsHookEx указан как NULL.

После встраивания фильтров устанавливается флаг bHooked, в глобальную переменную hwndClient записывается идентификатор окна, переданного функции SetKbHook в качестве параметра. Приложение WINHOOK передает идентификатор своего главного окна, пользуясь которым фильтр, расположенный в DLL-библиотеке, будет посылать приложению WINHOOK сообщение WM_KBHOOK.

Для удаления фильтров в DLL-библиотеке определена функция RemoveKbHook:

extern "C" void WINAPI _export RemoveKbHook(void) { if(bHooked) { UnhookWindowsHookEx(hhookMsg); UnhookWindowsHookEx(hhook); } }

Эта функция проверяет состояние флага bHooked, и, если фильтры были установлены, удаляет их, вызывая для каждого фильтра функцию UnhookWindowsHookEx.

Функция фильтра типа WH_KEYBOARD пропускает через себя все клавиатурные сообщения, определяя момент, когда пользователь нажмет подряд три раза клавишу <Control>.

Как только это произошло, функция фильтра инвертирует флаг bCyrillic и посылает приложению WINHOOK сообщение WM_KBHOOK. В качестве параметра wParam посылаемого сообщения используется значение флага bCyrillic, что позволяет определить приложению номер используемой раскладки клавиатуры:

PostMessage(hwndClient, WM_KBHOOK, (WPARAM)bCyrillic, 0L);

Фильтр типа WH_MSGFILTER расположен в функции MsgHookProc.

Если перехвачено сообщение WM_KEYDOWN, фильтр проверяет номер используемой раскладки клавиатуры. Если используется стандартная раскладка клавиатуры, сообщение "пропускается" через фильтр без изменений. Для дополнительной раскладки клавиатуры выполняется проверка кода виртуальной клавиши.

Если этот код соответствует клавишам русских букв или цифр в верхнем ряду клавиатуры, фильтр преобразует сообщение WM_KEYDOWN в сообщение WM_CHAR, пользуясь таблицами перекодировок, загруженным из ресурсов DLL-библиотеки. При этом учитывается состояние клавиш <Shift> и <Caps Lock>. Для определения состояния переключающих клавиш мы использовали функцию GetKeyState.

Таблицы перекодировки для прописных и строчных букв описаны в файле ресурсов DLL-библиотеки (листинг 3.13).




Начало  Назад  Вперед