Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 6004.doc
Скачиваний:
20
Добавлен:
30.04.2022
Размер:
1.29 Mб
Скачать

5.1.2.Буфер клавиатуры

Буфер клавиатуры занимает 32 байта (40:1EН..40:3EН). Запись выполняет обработчик прерывания 09Н, чтение - обработчик прерывания 16Н. Буфер рассчитан на 15 двухбайтовых кодов вводимой строки и один двухбайтовый код для клавиши Enter, нажатие на которую служит признаком завершения ввода для интерпретатора команд ОС. Буфер организован как кольцевая очередь, доступ к которой осуществляется через два указателя, расположенных по адресам

0040:001AН - указатель "головы" (Нead Pointer),

0040:001CН - указатель "хвоста" (Tail Pointer).

Значения в указателях равны смещению от сегмента 0040Н. Tail Pointer показывает на первое свободное слово буфера, Нead Pointer показывает на начало очереди.

5.1.3.Схема работы буфера

При нажатии на клавишу код записывается в буфер и указатель "хвоста" увеличивается на два. Если значение указателя "хвоста" больше 003EН, то буфер считается переполненным, новые коды не принимаются и из динамика компьютера звучит предупреждающий сигнал.

Обработчик прерывания 16Н использует указатели "головы" и "хвоста" для ввода с клавиатуры. Функция АН = 0 (чтение буфера с разрушением информации) позволяет прочитать из буфера два байта и увеличивает значение указатель "головы" на два. Если значения указателей равны, это говорит о том, что буфер пуст. Обработчик прерывания выполняет бесконечный цикл ожидания до неравенства значений указателей.

Функция АН = 1 (чтение без разрушения) служит для передачи слова в программу. Значение указателя "головы" не меняется. Если значения указателей совпадают, то выставляется флаг CF = 1 и обработчик прерывания 16Н аварийно завершается.

Буфер клавиатуры - это классический пример использования кольцевой очереди для организации асинхронного взаимодействия двух программ по схеме "производитель-потребитель" (обработчик прерывания 09Н производит данные, а 16Н - потребляет).

5.1.4.Ввод информации с клавиатуры в Windows

Все приложения, написанные для Microsoft Windows, способны осуществлять ввод данных с клавиатуры. В основу работы приложения с клавиатурой положена следующая модель (рис. 26.).

Рис. 26. Схема взаимодействия приложения с клавиатурой

Windows обеспечивает независимую от устройств поддержку клавиатурного ввода с помощью установки драйвера клавиатуры. Также поддерживается языковая независимость входного потока. Драйвер клавиатуры получает скэн-коды, которые перетранслируются в виртуальные коды клавиш (virtual-key code) и формируют сообщения, пересылаемые в очередь системных сообщений. Специализированная задача обработки сообщений выбирает их из очереди и рассылает окнам-абонентам приложений. Выбор окна-абонента осуществляется в соответствии с временным свойством окна, называемым фокусом, поскольку общий клавиатурный поток должен быть разделен между всеми окнами. Задача может вызвать функцию GetFocus, чтобы определить, какое окно имеет в настоящий момент фокус ввода. Передача фокуса выполняется функцией SetFocus. При передаче фокуса от одного окна другому система посылает сообщение WM_KILLFOCUS тому окну, которое теряет фокус, и WM_SETFOCUS окну, получающему фокус. Нажатие на клавишу приводит к помещению в очередь сообщений WM_KEYDOWN или WM_SYSKEYDOWN, которые передаются окну, имеющему фокус ввода. Сообщения о нажатиях и отжатиях клавиш передаются в общем случае парами, однако, если пользователь держит клавишу на- датой в течении продолжительного времени так, что включается функция автоповтора, система генерирует множество сообщений WM_KEYDOWN или WM_SYSKEYDOWN и одно WM_KEYUP или WM_SYSKEYUP.

Сообщения о нажатиях на клавиши предоставляют разнообразную информацию, но не включают символьный код клавиши. Чтобы получить символьный код, приложение должно вызывать функцию TranslateMessage в цикле обработки сообщений. При этом проверяется виртуальный код и, если он соответствует символу, возвращается кодовый эквивалент с учетом состояния SНIFT и CAPS LOCK клавиш. Генерируется символьное сообщение, которое помещается в вершину очереди сообщений. Следующая итерация цикла обработки сообщений забирает его и передает ожидающему ввода окну.