Для начала работы с консолью необходимо получить ее дескриптор.
Функция получения дескриптора стандартного устройства ввода, вывода или ошибки в зависимости от переданного константного параметра:
nStdHandle может принимать значения
- STD_INPUT_HANDLE = -10; // устройство ввода
- STD_OUTPUT_HANDLE = -11; // устройство вывода
- STD_ERROR_HANDLE = -12; // ошибка
Использование русского языка в консоли с помощью API
Для указания кодовой страницы используются функции
Кодовая страница консоли вывода
BOOL WINAPI SetConsoleOutputCP(UINT wCodePageID);Кодовая страница консоли ввода
BOOL WINAPI SetConsoleCP(UINT wCodePageID);
где wCodePageID — номер кодовой страницы.
Для перекодировки на русский язык используется кодовая страница wCodePageID=1251.
Для перекодировки русского текста, введенного в Win-коде также может использоваться функция
- lpszSrc – указатель на строку-источник;
- lpszDst/strong> – указатель на строку-приемник
Возвращаемое значение 1 в случае успешной перекодировки.
Чтение/запись данных в консоль/файл
Для чтения и записи данных в консоль используются функции
- Чтение данных
BOOL WINAPI ReadFile(
_In_ HANDLE hFile,
_Out_ LPVOID lpBuffer,
_In_ DWORD nNumberOfBytesToRead,
_Out_ LPDWORD lpNumberOfBytesRead,
_Inout_ LPOVERLAPPED lpOverlapped); - Запись данных
BOOL WINAPI WriteFile(
_In_ HANDLE hFile,
_In_ LPCVOID lpBuffer,
_In_ DWORD nNumberOfBytesToWrite,
_Out_ LPDWORD lpNumberOfBytesWritten,
_Inout_ LPOVERLAPPED lpOverlapped);
В случае успешного завершения функции возвращают ненулевое значение.
Аргументы функций
- hFile -дескриптор файла/консоли. Файл/консоль должен иметь доступ для чтения для функции ReadFile() и доступ для записи для функции WriteFile().
- lpBuffer — указатель на буфер (строку) для чтения/записи данных.
- nNumberOfBytesToWrite — число байтов, которые будут записаны в файл.
- lpNumberOfBytesWritten — указатель на переменную, которая получает число считанных/записанных байтов.
- lpOverlapped — указатель на структуру OVERLAPPED, которая используется в операциях асинхронного ввода-вывода (например, получение данных по интерфейсу связи). Для синхронного ввода-вывода данный указатель имеет значение NULL.
Установка заголовка окна консоли
Функция установки заголовка окна консоли
lpConsoleTitle – указатель на строку имени консоли с завершающим нуль-символом.
Установка цвета символов и фона в консоли
Цвет символов и фона задается с помощью констант, определяющих тетрады символов.
Цвет символов
- FOREGROUND_BLUE = 0x01
- FOREGROUND_GREEN = 0x02
- FOREGROUND_RED = 0x04
- FOREGROUND_INTENSITY = 0x08
Фон символов
- BACKGROUND_BLUE = 0x10
- BACKGROUND_GREEN = 0x20
- BACKGROUND_RED = 0x40
- BACKGROUND_INTENSITY = 0x80
Каждая тетрада, определяющая цвет символов или фона, представляет собой значение от 0 до 15, задаваемая логической суммой соответствующих констант.
Например, цвет символов с кодом 13 задается как
FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY.
Функция определения атрибутов вводимых символов в окне консоли
__in HANDLE hConsoleOutput,
__in WORD wAttributes);
- hConsoleOutput – дескриптор буфера консоли вывода;
- wAttributes – цвет букв и фона, получаемый путем комбинации констант
Функция, задающая цвет фона консоли(путем закрашивания фона отдельных символов)
__in HANDLE hConsoleOutput,
__in WORD wAttribute,
__in DWORD nLength,
__in COORD dwWriteCoord,
__out LPDWORD lpNumberOfAttrsWritten);
- hConsoleOutput – дескриптор буфера вывода консоли; wAttribute – атрибут цвета фона символа в консоли;
- nLength – количество ячеек символов, фон которых устанавливается заданным цветом;
- dwWriteCoord – координаты первой закрашиваемой ячейки;
- lpNumberOfAttrsWritten – указатель на идентификатор, в который записывается количество реально закрашенных ячеек.
Для того чтобы изменить цвет всего окна консоли необходимо задать цвет символов, количество которых определяется размером окна консоли. Размер стандартного окна консоли 80×25 = 2000 символов.
Установка позиции курсора
Функция установки позиции курсора в окне консоли
__in HANDLE hConsoleOutput,
__in COORD dwCursorPosition);
hConsoleOutput – дескриптор буфера вывода консоли; dwCursorPosition – структура координат COORD, определяющая позицию курсора.
Структура координат представляет собой
{
short X;
short Y;
};
Пример на Си
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <windows.h>
int main()
{
DWORD l;
COORD point;
point.X = 0; point.Y = 0;
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hin = GetStdHandle(STD_INPUT_HANDLE);
char title[73093; = "Консольная программа";
CharToOem(title, title);
SetConsoleTitle(title);
SetConsoleOutputCP(1251);
SetConsoleTextAttribute(hout, FOREGROUND_RED | FOREGROUND_INTENSITY);
FillConsoleOutputAttribute(hout, 0, 2000, point, &l); // очистка экрана
for (int y = 0; y < 16; y++) {
point.Y = y;
FillConsoleOutputAttribute(hout, y << 4, 80, point, &l);
SetConsoleCursorPosition(hout, point);
}
char c;
ReadFile(hin, &c, 1, &l, NULL);
return 0;
}
Результат выполнения
Примечание: для корректной компиляции программы необходимо изменить тип кодировки проекта на многобайтовую.
Visual C++ 2008 Express. На строчке HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE); Вылетает ошибка: «error C2275: HANDLE: недопустимое использование этого типа в качестве выражения c:\program files\microsoft sdks\windows\v6.0a\include\winnt.h(402): см. объявление ‘HANDLE’».
Дальше (поскольку не смог объявить hout) валом валят другие обишки (C2275 повторяется ещё раз):
error C2146: синтаксическая ошибка: отсутствие «;» перед идентификатором «hout»
error C2065: hout: необъявленный идентификатор
warning C4047: =: ‘int’ отличается по уровням косвенного обращения от ‘HANDLE’
error C2275: HANDLE: недопустимое использование этого типа в качестве выражения c:\program files\microsoft sdks\windows\v6.0a\include\winnt.h(402): см. объявление ‘HANDLE’
Чего ему не хватает-то?!
Всё, разобрался. Объявления должны стоять до инициализирующих конструкций. В статье сначала идёт присваивание point.X и point.Y, а затем объявление хендлов. Поменял местами, сгруппировал все объявления (которые с указанием типа),в начале функции main() — и ошибки исчезли.