Если вам доводилось делать попытки написания игр в виде "консольных" приложений Windows, то возможно вас интересовал вопрос,
А нельзя ли, к примеру, раскрасить выводимый текст?
И, стоит заметить, ответ на него не так уж и глубоко спрятан. Как факт, на MSDN есть целая секция, посвященная работе с консолями. Правда, она немного запутанная. И на английском. Но в остальном, нужную документацию в ней можно найти методом перебора функций из списка доступных. Но данная статья посвящена выводу цветного текста а не перебору, поэтому вернемся к нему.
Непосредственная "раскраска" текста выполняется через одну функцию Windows.h, именуемую SetConsoleTextAttribute. Возможно, было бы проще назвать ее "SetConsoleColor", дабы пользователь не тратил некое количество времени на угадывание имени функции в случае отсутствия документации, но она служит и для других целей (например подчеркивания текста), так что особо не пожалуешься.
Функция принимает два аргумента, обозначающие дескриптор вывода консоли и набор флагов соответственно.
Придерживаясь традиции запутанного изложения документации, описание функции не говорит нам, откуда можно было бы получить данный дескриптор, но на практике все просто. Поскольку в большинстве случаев перекрашенный текст должен выводиться на stdout, можно воспользоваться GetStdHandle:
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
В качестве второго аргумента в функцию подается набор флагов (или целочисленная, если вы любите магические числа). Интересующие нас значения включают BACKGROUND_ и FOREGROUND_, обозначающие цвет фона и текста соответственно. То есть, при наличии ранее приведенной строки кода, вывод зеленого текста на экран может быть реализован так:
SetConsoleTextAttribute(hStdOut, FOREGROUND_GREEN); printf("Green\n");
Если же нам нужно вывести, к примеру, желтый текст, это делается совмещением флагов:
SetConsoleTextAttribute(hStdOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY); printf("Yellow\n")
Для раскраски фона дела обстоят аналогично:
SetConsoleTextAttribute(hStdOut, BACKGROUND_BLUE | BACKGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); printf("White on blue");
Так же стоит заметить, что при переносе строки или очистке экрана текущий цвет заполнит остаток строки или экран соответственно.
А теперь немного о самих цветах. Как-то так сложилось, что для консольных приложений выделяется целых 16 цветов, представленных в WinAPI 4-мя битами, отвечающими за красный, синий, и зеленый компоненты, и дополнительный бит "яркости" цвета.
В результате, доступная цветовая палитра выглядит где-то так:
Где RGBI - красный, зеленый, синий, интенсивность.
Посматривая на данную таблицу, можно задать логичный вопрос,
А что, если я хочу больше цветов?
И, стоит отметить, что в данном отношении не все так ужасно. В стандартной кодовой таблице символов для "совмещения цветов" есть три символа с индексами 176, 177, и 178 соответственно. Символ 177 является "клеточкой" для 50% совмещения, в то время как 176 и 178 содержат диагональные линии, представляющие заполнение в ~25% и ~75% соответственно. В результате, с помощью вывода данных символов с разными цветами фона и текста, мы можем получить некоторое разнообразие цветов:
Всего около 736 цветов, многие из которых вы, наверное, не хотели бы использовать.
Если это имеет интерес, исходный код вывода вышеприведенной иллюстрации можно взять ниже.