Иллюстрированный самоучитель по задачам и примерам Assembler

Организация низкоуровнего консольного ввода-вывода

Исходя из вышесказанного структура 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, когда клавиша отпущена.

Выход из программы – при выполнении любых действий с мышью.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.