Организация низкоуровнего консольного ввода-вывода
Низкий уровень консольного ввода-вывода по сравнению с высоким уровнем обладает более широкими и гибкими возможностями. Низкоуровневые функции консольного ввода-вывода обеспечивают прямой доступ к входному и экранным буферам консоли, предоставляя приложению доступ к событиям мыши и клавиатуры, а также к информации об изменении размеров окна консоли. Функции низкоуровневого ввода-вывода позволяют приложению иметь доступ по чтению-записи к указанному числу последовательных символьных ячеек в экранном буфере или к прямоугольному блоку символьных ячеек в указанной позиции экранного буфера.
Обсудим возможности низкоуровневого ввода-вывода на примере работы с входным буфером (входной очередью) и буферами экрана. Отметим, для работы с ними существуют разные группы команд. Так, для работы с входным буфером используются функции низкоуровневого ввода-вывода – WriteConsolelnputXRead-Consolelnput. Группа функций для работы с буферами экрана будет конспективно рассмотрена в конце этого раздела.
Поддержка работы с мышью в консоли
Большое достоинство консольных приложений – встроенная средствами Windows поддержка мыши. Она реализуется с помощью функции ReadConsolelnput. Важно отметить, что эта функция используется для получения информация о событиях не только мыши, но и о событиях клавиатуры, изменении размера окна и т. д.
B00L ReadConsoleInput(HANDLE hConsolelnput. PINPUT_RECORD lpBuffer, DWORD nLength. LPDWORD lpNumberOfEventsRead);
Параметры этой функции:
- Consolelnput – стандартный дескриптор ввода, полученный функцией GetStdHandle;
- lpBuffer – указатель на буфер, в который записывается информация о событии мыши, – эта область памяти имеет структуру, называемую INPUT_ RECORD, ее формат рассмотрен чуть ниже (необходимо заметить, что возможно групповое чтение информации из входного буфера, поэтому указатель ipBuffer может указывать на массив структур; информация о том, сколько событий будет читаться в этот массив структур, определяется параметром nLength);
- nLength – размер во входных записях буфера, на который указывает указатель lpBuffer;
- lpNumberOfEventsRead – определяет переменную, в которую записывается действительное число прочитанных записей входного буфера.
Запись входного буфера консоли имеет структуру, называемую INPUTRECORD. Ее описание на языке C++ выглядит так:
typedef struct _INPUT_RECORD { WORD EventType; union { KEYJVENT_RECORD KeyEvent; MOUSE_EVENT_RECORD MouseEvent; WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; MENU_EVENT_RECORD MenuEvent: FOCUSJVENT_RECORD FocusEvent; } Event: } INPUT_RECORD;
В этой структуре первое поле EventType размером в слово содержит тип события, а второе поле Event является объединением различных структур. Поля какой из структур будут заполнены, определяется типом события, то есть первым полем, которое может принимать значения:
- KEY_EVENT=0001h – поле Event содержит структуру KEYEVENTRECORD с информацией относительно события клавиатуры;
- MOUSE_EVENT=0002h – ноле Event содержит структуру MOUSEEVENTRECORD с информацией относительно движения мыши или нажатия кнопки;
- WINDOW_BUFFER_SIZE_EVENT-O004h – поле Event содержит структуру WINDOW_ BUFFER_SIZE_RECORD с информацией относительно нового размера экранного буфера;
- MENU_EVENT=OOO8h – поле Event содержит структуру MENUEVENTRECORD (это событие используется внутри Windows и должно игнорироваться);
- FOCUS_EVENT=0010h – поле Event содержит структуру FOCUSEVENTRECORD (это событие используется внутри Windows и должно игнорироваться).
Для обработки события мыши структура MOUSEEVENTRECORD выглядит так:
typedef struct _MOUSE_EVENT_RECORD { COORD dwMousePosition; DWORD dwButtonState; DWORD dwControlKeyState: DWORD dwEventFlags; } MOUSE_EVENT_RECORD;