Работа с окном консоли и буфером экрана
Работа с окном консоли и буфером экрана ПМ. 01 «Разработка программных модулей системного программного обеспечения» МДК 01. 01 «Системное программирование» vk. com/erina_m erina_m@pisem. net
1. Функции для работы с курсором Функция Get. Console. Cursor. Infо – информация о положении и видимости курсора: BOLL Get. Console. Cursor. Infо( HANDLE h. Console. Output, // дескриптор буфера экрана PCONSOLE_CURSOR_INFO lp. Console. Cursor. Info // информация о курсоре ); При успехе возвращает ненулевое значение, иначе — FALSE. lp. Console. Cursor. Info – информация о курсоре: typedef struct _CONSOLE_CURSOR_INFO { DWORD dw. Size; BOOL b. Visible; } CONSOLE_CURSOR_INFO, * PCONSOLE_CURSOR_INFO ; dw. Size – размер курсора в процентах от размера клетки для символа (от 1 до 100) b. Visible – видимость курсора (=true – видим, =false — невидим). 1/22/2018 vk. com/erina_m erina_m@pisem. net 2
2. Функции для работы с курсором Функция Set. Console. Cursor. Info - размер и видимость курсора: BOOL Set. Console. Cursor. Info ( HANDLE h. Console. Output, // дескриптор буфера экрана // информация о курсоре CONST CONSOLE_CURSOR_INFO *lp. Console. Cursor. Info ); Функция Set. Console. Cursor. Position – установить позицию курсора в буфере экрана: BOOL Set. Console. Cursor. Position( HANDLE h. Console. Output, // дескриптор буфера экрана COORD dw. Cursor. Position // новая позиция курсора ); 1/22/2018 vk. com/erina_m erina_m@pisem. net 3
Пример 1. Чтение и установка параметров курсора #include
Пример 2. Установка курсора в новую позицию #include
3. Чтение и установка атрибутов консоли Функция Fill. Console. Output. Attribute – установить атрибуты консоли: BOOL Fill. Console. Output. Attribute( HANDLE h. Console. Output, // дескриптор буфера экрана WORD w. Attributes, // цвет фона и цвет текста DWORD n. Length, // количество заполняемых клеток COORD dw. Write. Coord, // координаты первой клетки LPDWORD lp. Number. Of. Attrs. Written // количество заполненных клеток ); 1/22/2018 vk. com/erina_m erina_m@pisem. net 6
Пример 3. Заполнение консоли новыми атрибутами #include
4. Чтение и установка атрибутов консоли Функция Set. Console. Text. Attributes - установить атрибуты символов, которые пишутся в буфер экрана функциями Write. File и Write. Console, а также отображаются на экране при чтении функциями Read. File и Read. Console: BOOL Setconsoie. Text. Attributes ( HANDLE h. Console. Output, // дескриптор буфера экрана WORD w. Attribute // цвет фона и цвет текста ); 1/22/2018 vk. com/erina_m erina_m@pisem. net 8
Пример 4. Установка атрибутов текста консоли #include
5. Чтение и установка атрибутов консоли Функция Write. Console. Output. Attribute - установка разных атрибутов в последовательные клетки буфера экрана: BOOL Write. Console. Output. Attribute ( HANDLE h. Console. Output, // дескриптор буфера экрана CONST WORD *lp. Attribute, // указатель на атрибуты DWORD n. Length, // количество заполняемых клеток COORD dw. Write. Coord, // координаты первой клетки LPDWORD lp. Number. Of. Attrs. Written // количество заполненных клеток ); lp. Attribute – массив атрибутов, которые будут заноситься в последовательные клетки буфера экрана. Функция Read. Console. Output. Attribute - чтение атрибутов текста буфера экрана из последовательных ячеек: BOOL Read. Console. Output. Attribute( HANDLE h. Console. Output, // дескриптор буфера экрана LPWORD lp. Attribute, // указатель на атрибуты DWORD n. Length, // количество читаемых клеток COORD dw. Write. Coord, // координаты первой клетки LPDWORD lp. Number. Of. Attrs. Read // количество прочитанных клеток ); 1/22/2018 vk. com/erina_m erina_m@pisem. net 10
Пример 5. Установка и чтение атрибутов текста консоли #include
6. Ввод-вывод высокого уровня К функциям ввода-вывода высокого уровня относятся следующие функции: Write. Console, Read. Console, Write. File и Read. File. Функция Read. Console - для чтения строки символов из входного буфера консоли экрана: BOOL Read. Console( HANDLE h. Console. Input, // дескриптор буфера экрана CONST VOID *lp. Buffer, // массив для ввода символов DWORD n. Number. Of. Chars. To. Read, // количество читаемых символов LPDWORD lp. Number. Of. Chars. Read, // количество прочитанных символов LPVOID lp. Reserved // зарезервировано ); В процессе ввода игнорируются все события ввода, которые отличаются от ввода символа. Функция Write. Console - для записи строки символов в буфер экрана: BOOL Write. Console ( HANDLE h. Console. Output, // дескриптор буфера экрана CONST VOID *lp. Buffer, // массив с символами для вывода DWORD n. Number. Of. Chars. To. Write, // количество записываемых символов LPDWORD lp. Number. Of. Chars. Written, // количество записанных символов LPVOID lp. Reserved // зарезервировано ); 1/22/2018 vk. com/erina_m erina_m@pisem. net 12
Пример 6. Чтение и запись на консоль Read. Console, Write. Console #include
7. Ввод-вывод высокого уровня Ввод-вывод на консоль при помощи функций Read. File и Write. File выполняется аналогично функциям Read. Console и Write. Console. Последний параметр указывает на синхронный или асинхронный ввод-вывод. В случае с консолью функции Write. File, Read. File, Write. Console и Read. Console читают и записывают символы потоком. Функции Read. File и Write. File работают только с символами в кодировке ASCII. Функции Read. Console и Write. Console работают также с символами в кодировке Unicode и не обрабатывают управляющие символы при вводе-выводе на консоль. 1/22/2018 vk. com/erina_m erina_m@pisem. net 14
Пример 7. Чтение и запись на консоль Read. File и Write. File #include
Пример 7. Чтение и запись на консоль Read. File и Write. File // цикл чтения for (; ; ) { // выводим сообщение о вводе строки if (!Write. File( h. Std. Out, // дескриптор стандартного вывода lpsz. Prompt 2, // строка, которую выводим lstrlen(lpsz. Prompt 2), // длина строки &c. Written, // количество записанных байтов NULL)) // синхронный вывод { Message. Box(NULL, "Write file failed", "Win 32 API error", MB_OK | MB_ICONINFORMATION); return Get. Last. Error(); } // вводим строку с клавиатуры и дублируем ее на экран if (!Read. File( h. Std. In, // дескриптор стандартного ввода ch. Buffer, // буфер для чтения 80, // длина буфера &c. Read, // количество прочитанных байтов NULL)) // синхронный ввод { Message. Box(NULL, "Write file failed", "Win 32 API error", MB_OK | MB_ICONINFORMATION); return Get. Last. Error(); } // выводим сообщение о вводе строки std: : cout << "You are input: n" << ch. Buffer << "n"; // выход из программы if (ch. Buffer[0] == 'q') return 1; } return 0; } 1/22/2018 vk. com/erina_m erina_m@pisem. net 16
8. Ввод низкого уровня Функции ввода низкого уровня работают непосредственно с записями входного буфера консоли: Read. Console. Input, Peek. Console. Input, Write. Console. Input, Get. Number. Of. Console. Input. Events и Flush. Console. Input. Buffer. Функция Read. Console. Input - для чтения записей из входного буфера: BOOL Read. Console. Input( HANDLE h. Console. Input, // дескриптор входного буфера консоли PINPUT_RECORD lp. Buffer, // буфер данных DWORD n. Length, // количество читаемых записей LPDWORD lp. Number. Of. Events. Read // количество прочитанных записей ); После чтения записи из входного буфера консоли она удаляется оттуда. h. Console. Input – дескриптор входного буфера консоли. lp. Buffer – указатель на область памяти, в которую будут читаться записи из входного буфера консоли. n. Length – количество записей, которые пользователь хочет прочитать из входного буфера консоли. lp. Number. Of. Events. Read – адрес, куда записать количество прочитанных записей из буфера консоли. Функция Peek. Console. Input - для чтения записей из входного буфера консоли, не удаляя их оттуда. Параметры те же. 1/22/2018 vk. com/erina_m erina_m@pisem. net 17
Пример 8. Чтение записей входного буфера консоли # include
Пример 8. Чтение записей входного буфера консоли // функция обработки сообщения об изменении размеров окна VOID Resize. Event. Proc(WINDOW_BUFFER_SIZE_RECORD wbsr) { cout << "t. Resize Event: " << endl << dec; // изменяем размеры буфера вывода Set. Console. Screen. Buffer. Size(h. Std. Out, wbsr. dw. Size); } int main() { INPUT_RECORD ir; // входная запись DWORD c. Num. Read; // для количества прочитанных записей // получить дескрипторы стандартного ввода и вывода h. Std. In = Get. Std. Handle(STD_INPUT_HANDLE); if (h. Std. In == INVALID_HANDLE_VALUE) { cout << "Get standard input handle failed. " << endl; return Get. Last. Error(); } h. Std. Out = Get. Std. Handle(STD_OUTPUT_HANDLE); if (h. Std. Out == INVALID_HANDLE_VALUE) { cout << "Get standard output handle failed. " << endl; return Get. Last. Error(); } // начинаем обработку событий ввода cout << "Begin input event queue processing. " << endl; cout << "Input 'q' to quit. "<< endl; 1/22/2018 vk. com/erina_m erina_m@pisem. net 19
Пример 8. Чтение записей входного буфера консоли // цикл обработки событий ввода while (b. Read) { // ждем событие ввода Wait. For. Single. Object(h. Std. In, INFINITE); // читаем запись ввода if (!Read. Console. Input( h. Std. In, // дескриптор ввода &ir, // буфер для записи 1, // читаем одну запись &c. Num. Read)) // количество прочитанных записей { cout << "Read console input failed. " << endl; break; } // вызываем соответствующий обработчик switch(ir. Event. Type) { case KEY_EVENT: // событие ввода с клавиатуры Key. Event. Proc(ir. Event. Key. Event); break; case MOUSE_EVENT: // событие ввода с мыши Mouse. Event. Proc(ir. Event. Mouse. Event); break; case WINDOW_BUFFER_SIZE_EVENT: // изменения размеров окна Resize. Event. Proc(ir. Event. Window. Buffer. Size. Event); break; case FOCUS_EVENT: // события фокуса ввода игнорируем break; case MENU_EVENT: // события меню игнорируем break; default: // неизвестное событие cout << "Unknown event type. "; break; } } return 0; } 1/22/2018 vk. com/erina_m@pisem. net 20
9. Запись событий ввода во входной буфер консоли Функция Write. Console. Input – запись событий ввода во входной буфер консоли: BOOL Write. Console. Input( HANDLE h. Console. Input, // дескриптор входного буфера консоли CONST INPUT_RECORD *lp. Buffer, // указатель на буфер с записями DWORD n. Length, // количество записываемых записей LPDWORD lp. Number. Of. Events. Written // количество записанных записей ); h. Console. Input – дескриптор входного буфера консоли. lp. Buffer – указатель на область памяти, из которой будут записываться записи во входной буфер консоли. n. Length – количество записей, которые пользователь хочет записать во входной буфер консоли. lp. Number. Of. Events. Written - адрес, куда записать количество записей во входном буфере консоли. Функция Get. Number. Of. Consolelnput. Events – для чтения количества записей, находящихся во входном буфере консоли BOOL Get. Number. Of. Consolelnput. Events( HANDLE hconsoleinput, // дескриптор входного буфера консоли LPDWORD lp. Number. Of. Events // указатель на количество записей ); lp. Number. Of. Events - адрес для записи количества записей, находящихся в буфере ввода консоли. Функция Flush. Console. Input. Buffer - очистка буфера ввода консоли BOOL Flush. Console. Input. Buffer( HANDLE h. Console. Input, // дескриптор входного буфера консоли ); 1/22/2018 vk. com/erina_m@pisem. net 21
Пример 9. Запись в буфер ввода, кол-во записей и очистка буфера #include
Пример 9. Запись в буфер ввода, кол-во записей и очистка буфера // записываем запись в буфер ввода if (!Write. Console. Input(h. Std. In, &ir, 1, &dw. Number. Written)) { cout << "Write console input failed. " << endl; return Get. Last. Error(); } cout << "Write one record into the input buffer. " << endl; // подсчитываем записи в буфере ввода if (!Get. Number. Of. Console. Input. Events(h. Std. In, &dw. Number)) { cout << "Get number of console input events failed. " << endl; return Get. Last. Error(); } // печатаем количество событий ввода cout << "Number of console input events = " << dw. Number << endl; // очищаем входной буфер cout << "Flush console input buffer. " << endl; if (!Flush. Console. Input. Buffer(h. Std. In)) { cout << "Flush console input buffer failed. " << endl; return Get. Last. Error(); } // подсчитываем записи в буфере ввода if (!Get. Number. Of. Console. Input. Events(h. Std. In, &dw. Number) ) { cout << "Get number of console input events failed. " << endl; return Get. Last. Error(); } // печатаем количество событий ввода cout << "Number of console input events = " << dw. Number << endl; return 0; } 1/22/2018 vk. com/erina_m erina_m@pisem. net 23
10. Определение количества кнопок у мыши Функция Get. Number. Of. Console. Mouse. Button - для определения количества кнопок у мыши: BOOL Get. Numberof. Consoie. Mouse. Button( LPDWORD Ip. Number. Of. Mouse. Buttons // количество кнопок у мыши ); При успешном завершении по адресу, заданному параметром lp. Number. Of. Mouse. Buttons заносится количество кнопок у мыши. 1/22/2018 vk. com/erina_m erina_m@pisem. net 24
Пример 10. Определение количества кнопок у мыши #include
11. Вывод низкого уровня Функции вывода низкого уровня работают непосредственно с элементами буфера экрана. Три группы: 1. Чтение и запись последовательности символов: l Readconsoieoutputcharacter — чтение последовательности символов из буфера экрана; l Write. Console. Output. Character — запись последовательности символов в буфер экрана. 2. Заполнение буфера экрана заданным символом: l Filiconsoieoutputcharacter — заполнение буфера экрана. 3. Чтение и запись прямоугольных областей символов: l Readconsoieoutput — чтение прямоугольной области символов из буфера экрана; l writeconsoieoutput — запись прямоугольной области символов в буфер экрана. 1/22/2018 vk. com/erina_m erina_m@pisem. net 26
12. Вывод низкого уровня Функции из первой группы предназначены для работы с последовательностями символов. Функция Read. Console. Output. Character – Для ввода последовательности символов из буфера экрана BOOL Read. Console. Output. Character( HANDLE h. Console. Output, // дескриптор буфера экрана LPTSTR lp. Character, // указатель на буфер с символами DWORD n. Length, // количество читаемых символов COORD dw. Read. Coord, // координаты первого читаемого символа LPDWORD lp. Number. Of. Chars. Read // количество прочитанных символов ); h. Console. Output этой функции должен содержать дескриптор буфера экрана. lp. Character должен указывать на область памяти, в которую будет читаться содержимое буфера экрана. n. Length должен содержать количество читаемых символов из буфера экрана. dw. Read. Coord должен содержать координаты первого символа, который будет читаться из буфера экрана. Поля X и Y структуры COORD задают соответственно индексы строки и столбца первого читаемого элемента. По адресу, заданному lp. Number. Of. Chars. Read запишется количество прочитанных символов из буфера экрана. 1/22/2018 vk. com/erina_m erina_m@pisem. net 27
Пример 11. Чтение последователь- ности символов из буфера экрана # include
13. Запись последовательности символов в буфер экрана Для записи последовательности символов в буфер экрана используется функция Write. Console. Output. Character: BOOL Write. Console. Output. Character( HANDLE h. Console. Output, // дескриптор буфера экрана LPCTSTR lp. Character, // указатель на массив символов DWORD n. Length, // количество записываемых символов COORD dw. Write. Coord, // координаты первого символа в буфере экрана LPDWORD lp. Number. Of. Chars. Written // количество символов, // записанных в буфер экрана ); Эта функция записывает последовательность символов, на которую указывает параметр lp. Character, в буфер экрана, начиная с позиции, на которую указывает параметр dw. Write. Coord. Количество записываемых символов задается параметром n. Length, а количество фактически записанных символов возвращает по адресу, заданному параметром lp. Number. Of. Chars. Written. 1/22/2018 vk. com/erina_m erina_m@pisem. net 29
Пример 12. Запись последователь- ности символов в буфер экрана #include
14. Заполнение буфера экрана определенным символом Для заполнения всего или части буфера экрана определенным символом используется функция Fill. Console. Output. Character: BOOL Fill. Console. Output. Character( HANDLE h. Console. Output, // дескриптор буфера экрана TCHAR c. Character, // символ-заполнитель DWORD n. Length, // длина заполняемой области COORD dw. Write. Coord, // координаты первой клетки буфера экрана LPDWORD lp. Number. Of. Chars. Written // количество заполненных клеток ); 1/22/2018 vk. com/erina_m erina_m@pisem. net 31
Пример 13. Заполнение буфер экрана заданным символом #include
Пример 13. Заполнение буфер экрана заданным символом // заполняем буфер экрана символом-заполнителем if (!Fill. Console. Output. Character( h. Std. Out, // стандартный дескриптор вывода c, // символ заполнения dw. Length, // длина буфера в символах coord, // индекс первой клетки &dw. Written)) // количество заполненных клеток { cout << "Fill console output character failed. " << endl; return Get. Last. Error(); } // ждем команды на очищение буфера экрана cout << "In order to clear screen buffer, press any char: "; cin >> c; // очищаем буфер экрана пробелами if (!Fill. Console. Output. Character( h. Std. Out, // стандартный дескриптор вывода 1, // символ заполнения dw. Length, // длина буфера в символах coord, // индекс первой клетки &dw. Written)) // количество заполненных клеток { cout << "Fill console output character failed. " << endl; return Get. Last. Error(); } return 0; } 1/22/2018 vk. com/erina_m erina_m@pisem. net 33
15. Чтение областей символов и их атрибутов из буфера экрана Функция Readconsoie. Output предназначена для чтения прямоугольных областей символов и их атрибутов из буфера экрана: BOOL Read. Console. Output( HANDLE h. Console. Output, // дескриптор буфера экрана PCHAR_INFO lp. Buffer, // указатель на буфер с данными COORD dw. Buffer. Size, // размер буфера с данными COORD dw. Buffer. Coord, // координаты для первого элемента в буфере PSMALL_RECT lp. Read. Region // область ввода в буфере экрана ); h. Console. Output - дескриптор буфера экрана. lp. Buffer должен указывать на область памяти, в которую будет читаться содержимое буфера экрана. Причем эта область памяти рассматривается как двумерный массив, элементами которого являются структуры типа CHAR_INFO. Размерность этого массива задается параметром dw. Buffersize. Поля Х и Y структуры COORD задают соответственно количество столбцов и строк этого массива. Параметр lp. Read. Region является указателем на структуру типа SMALL_RECT, которая содержит координаты левого верхнего и правого нижнего углов прямоугольника в буфере экрана, содержимое которого будет прочитано в область памяти, заданную параметром lp. Buffer. 1/22/2018 vk. com/erina_m erina_m@pisem. net 34
Пример 14. Чтение прямоугольной области из буфера экрана #include
Для записи прямоугольных областей символов и их атрибутов в буфер экрана используется функция Write. Console. Output: BOOL Write. Console. Output( HANDLE h. Console. Output, // дескриптор буфера экрана CONST CHAR_INFO *lp. Buffer, // указатель на буфер с данными COORD dw. Buffer. Size, // размер буфера с данными COORD dw. Buffer. Coord, // координаты первого элемента в буфере PSMALL_RECT lp. Write. Region // область вывода в буфере экрана ); В случае успешного завершения функция возвращает ненулевое значение, а в случае неудачи — значение false. Эта функция записывает символы и их атрибуты из буфера, на который указывает параметр Ip. Buffer, в область вывода буфера экрана, на которую указывает параметр lp. Write. Region. Остальные параметры этой функции имеют тот же смысл, что и параметры функции Read. Console. Output. 1/22/2018 vk. com/erina_m erina_m@pisem. net 36
Пример 15. Заполнение прямо- угольной области в буфере экрана #include
Режимы ввода-вывода консоли Функции ввода-вывода на консоль могут работать в нескольких режимах, которые устанавливаются функцией setconsole. Mode: BOOL Setconsole. Mode( HANDLE h. Console. Handle, // дескриптор ввода или вывода DWORD dw. Mode // режим ввода или вывода ); Если параметр h. Console. Handle является дескриптором входного буфера, то режим ввода, который описывается параметром dw. Mode, может быть произвольной комбинацией следующих флагов: □ ENABLE_LINE_INPUT — фу. НКЦИЙ Read. File И Read. Console ЧИТа. ЮТ СИМВОЛЫ до тех пор, пока не встретят символ enter. В противном случае читается доступное количество символов во входном буфере; □ ENABLE_ECHO_INPUT — СИМВОЛЫ, Прочитанные ФУНКЦИЯМИ Read. File И Read. Console, выводятся на экран. Этот режим может использоваться только совместно с режимом enable_line_input; □ enable_processed_input — комбинация клавиш
Пример 16. Отключение режима эхо-вывода #include
Прокрутка буфера экрана Для перемещения блоков данных внутри буфера экрана используется функция scroiiconsoie. Screen. Buffer, которая имеет следующий прототип: BOOL Scroiiconsoie. Screen. Buffer( HANDLE h. Console. Output, // дескриптор буфера экрана CONST SMALL_RECT *lp. Scroll. Rectangle, // исходный прямоугольник CONST SMALL_RECT *lp. Clip. Rectangle, // прямоугольник отсечения COORD dw. Destination. Origin, // целевой прямоугольник CONST CHAR_INFO *lp. Fill // символ-заполнитель ); В случае успешного завершения эта функция возвращает ненулевое значение, а в случае неудачи — false. Кратко опишем назначение параметров этой функции. В параметре hconsoie. Output должен быть установлен дескриптор буфера экрана. Параметр lp. Scroii. Rectangie должен указывать на прямоугольник, который будет перемещаться внутри буфера экрана. Параметр lpciip. Rectangie должен указывать на прямоугольник, внутри которого выполняется изменение буфера экрана при перемещении исходного прямоугольника. За пределами этого прямоугольника изменения в буфере экрана производиться не будут. Такой процесс называется отсечением изменений вне прямоугольника, а сам прямоугольник называется прямоугольником отсечения. Параметр dw. Destination. Origin ДОЛЖен указывать на ПРЯМОУГОЛЬНИК, В КО- торый будет переписано содержимое исходного прямоугольника. Параметр lp. Fiii должен указывать на символ-заполнитель. Этим символом будут заполняться те области целевого прямоугольника, которые не перекрываются исходным прямоугольником. Главным образом фу. НКЦИЯ Scroiiconsoie. Screen. Buf fer ИСПОЛЬЗует. СЯ ДЛЯ прокрутки буфера экрана. 1/22/2018 vk. com/erina_m erina_m@pisem. net 40
Пример 17. Прокрутка буфера экрана #include
Спасибо за внимание! vk. com/erina_m erina_m@pisem. net

