Организация низкоуровнего консольного ввода-вывода
Исходя из вышесказанного структура INPUTRECORD для обработки событий мыши в программе на ассемблере должна выглядеть так:
INPUT_RECORD struc EventType dw 0 dwMousePosition struc x dw 0 у dw 0 ends dwButtonState dw 0 dwControlKeyState dw 0 DwEventFlags dw 0 ends
Поле EventType для события мыши содержит значение MOUSE_EVENT=0002h, а поля структуры MOUSEEVENTRECORD соответственно означают следующее:
- dwMousePosition – координаты мыши в окне консоли (в символьных координатах);
- dwButtonState – состояние кнопок мыши в момент возникновения события, при нажатии кнопок устанавливаются следующие биты (при одновременном нажатии устанавливается несколько соответствующих битов):
- если установлен бит 0 ноля dwButtonState, то в момент наступления события была нажата левая кнопка мыши;
- если установлен бит 1 поля dwButtonState, то в момент наступления события была нажата правая кнопка мыши;
- если установлен бит 2 поля dwButtonState, то в момент наступления события была нажата средняя кнопка мыши, если она есть;
- dwControlKeyState – поле описывает состояние управляющих клавиш клавиатуры в момент наступления события мыши (если одновременно нажато несколько клавиш, то значение в этом поле является результатом операции логического сложения ИЛИ перечисленных ниже значений):
- RIGHT_ALT_PRESSED=0001h – нажата правая клавиша ALT;
- LEFT_ALT_PRESSED=0002h – нажата левая клавиша ALT;
- RIGHT_CTRL_PRESSED=0004h – нажата правая клавиша CTRL;
- LEFT_CTRL_PRESSED=0008h – нажата левая клавиша CTRL;
- SHIFT_PRESSED=0010h – нажата любая клавиша SHIFT;
- NUMLOCK_ON=0020h – индикатор NumLock включен;
- SCROLLLOCK_ON=0040h – индикатор ScrollLock включен;
- CAPSLOCK_ON=0080h – индикатор CapsLock включен;
- ENHANCED_KEY=0100h – нажата клавиша расширенной клавиатуры (101 и 102 клавиши): Ins, Del, Home, End, Page Up, Page Down, ←, ↑, ↓ →, / или Enter;
- dwEventFl ags – поле содержит одно из двух значений:
- MOUSE_MOVED=0001h – перемещение мыши;
- DOUBLE_CLICK=0002h – выполнен двойной щелчок мыши.
Например, можно написать демонстрационную программу обработки событий мыши (prg05_13 .asm), которые отслеживаются следующим образом: нажатие левой кнопки приводит к выводу сообщения в позиции нажатия, нажатие правой кнопки приводит к завершению работы программы.
В заключение обращу внимание читателя на то, что API Win32 имеет функцию Mouse_Event, которая позволяет генерировать события, соответствующие реальным движениям мыши и щелчкам ее кнопок. Тем самым API Win32 предоставляет механизм для создания обучающих и демо-версий программ.
Формат этой функции:
VOID mouse_event(DWORD dwFlags. DWORD dx. DWORD dy, DWORD dwData. DWORD dwExtralnfo)
Расширенная поддержка клавиатуры в консоли
Функции работы с текстом высокого уровня не дают других возможностей работы с клавиатурой, кроме как примитивного ввода текста. При разработке программ текстового режима часто требуется информация о состоянии управляющих клавиш, о факте удержания клавиши, что может свидетельствовать о желании пользователя повторить ввод некоторого символа или просто о желании получить тривиальный скан-код клавиши. Эти и другие события клавиатуры доступны программе посредством описанной выше функции ReadConsolelnput.
События клавиатуры генерируются при нажатии любой клавиши. Процесс их обработки аналогичен обработке событий мыши. В первую очередь заполняется о нажатии некоторых управляющих клавиш. Для всех остальных клавиш просто фиксируется факт нажатия. При этом необходимо помнить, что однократному нажатию клавиши реально соответствуют два события – нажатие и отпускание клавиши. В связи с этим программа выводит два сообщения.
На практике этого можно избежать, анализируя поле bKeyDown:
- bKeyDown=1, когда клавиша нажата;
- bKeyDown=0, когда клавиша отпущена.
Выход из программы – при выполнении любых действий с мышью.