ою функції DispatchMessage віконної процедури, що робить обробку повідомлень для вікна, де в даний момент зосереджений фокус вводу. Фокус введення - атрибут, який може присвоюватися вікну, створеному додатком або Windows. Якщо вікно має фокус введення, відповідна функція цього вікна отримує все клавіатурні повідомлення з системної черги. Додаток може передавати фокус введення від одного вікна іншому, наприклад, при перемиканні на інший додаток за допомогою комбінації Alt + Tab.
Перед функцією DispatchMessage зазвичай викликається функція TranslateMessage, яка на основі повідомлень WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, WM_SYSKEYUP створює символьні повідомлення WM_CHAR, WM_SYSCHAR, WM_DEADCHAR і WM_SYSDEADCHAR. Освічені символьні повідомлення переносяться у чергу повідомлень додатка, причому оригінальні клавіатурні повідомлення з цієї черги не видаляються.
1.5 Масиви стану клавіш клавіатури
Одним із завдань при розробці моделі апаратного введення Windows було забезпечення її відмовостійкості. Відмовостійкість забезпечується незалежної обробкою введення потоками, що запобігає несприятливий вплив одного потоку на інший. Але цього недостатньо для надійної ізоляції потоків один від одного, тому система підтримує додаткову концепцію - локальне стан введення. Кожен потік володіє власним станом введення, відомості про який зберігаються в структурі THREADINFO. У інформацію про цей стан включаються дані про чергу віртуального введення потоку, а також група змінних. Останні містять керуючу інформацію про стан введення. Щодо клавіатури підтримуються такі відомості: яке вікно перебуває у фокусі клавіатури, яке вікно активно в даний момент, які клавіші натиснуті, який стан курсору введення.
Інформація про те, які клавіші натискати, зберігається в масиві синхронного стану клавіш. Цей масив включається в змінні локального стану вводу кожного потоку. У той же час масив асинхронного стану клавіш, в якому міститься аналогічна інформація, - тільки один, і він розділяється всіма потоками. Масиви відображають стан усіх клавіш на даний момент, і функція GetAsyncKeyState дозволяє визначити, чи натиснута зараз задана клавіша. GetAsyncKeyState завжди повертає 0 (натиснута), якщо її викликає інший потік, а не той, який створив вікно, що знаходиться зараз у фокусі введення.
Функція GetKeyState відрізняється від GetAsyncKeyState тим, що повертає стан клавіатури на той момент, коли з черги потоку витягнуто останні повідомлення від клавіатури. Цю функцію можна викликати в будь-який момент; для неї неважливо, яке саме вікно у фокусі.
1.6 Клавіатурні пастки
В операційній системі Microsoft Windows пасткою, або хуком (hook) називається механізм перехоплення подій з використанням особливої ??функції (таких як передача повідомлень Windows, введення з миші або клавіатури) до того, як вони дійдуть до додатка. Ця функція може потім реагувати на події і, в деяких випадках, змінювати або скасовувати їх.
Функції, які отримують повідомлення про події, називаються фільтруючими функціями і розрізняються за типами перехоплюваних ними подій. Для того щоб Windows змогла викликати функцію-фільтр, ця функція повинна бути прикріплена до хуку (наприклад, до клавіатурного хуку). Прикріплення однієї або декількох фільтруючих функцій до якого-небудь хуку називається установкою хука. Для установки і видалення фільтруючих функцій додатки використовують функції Win32 API SetWindowsHookEx і UnhookWindowsHookEx. Деякі хукі можна встановлювати як для всієї системи, так і для одного конкретного потоку.
Якщо до одного хуку прикріплено кілька фільтруючих функцій, Windows реалізує чергу функцій, причому функція, прикріплена останньої, виявляється на початку черги, а найперша функція - в її кінці. Черга функцій-фільтрів (див. Рис.5) підтримується самої Windows, що дозволяє спростити написання фільтруючих функцій і поліпшити продуктивність операційної системи.
Малюнок 5. Черга функцій-фільтрів (хуков)
Система підтримує окремі ланцюжки для кожного типу хуков. Ланцюжок хуков - це список покажчиків на фільтруючі функції (спеціальні функції зворотного виклику, що визначаються додатком). Коли відбувається деяке подія, пов'язана з конкретним типом хука, система послідовно передає повідомлення кожної фільтруючої функції в ланцюжку хуков. Дія, яку може виконати фільтруюча функція, залежить від типу пастки: деякі функції можуть тільки відслідковувати виникнення подій, інші можуть модифікувати параметри повідомлень або навіть зупинити обробку повідомлень, заблокувавши виклик наступної фільтруючої функції в ланцюжку хуков або функції обробки повідомлень вікна-призначення.
Коли до хуку прик...