Have you tried to print colored text in a console or put the text at a specific position? You know then that STL or CRT does not provide that functionality.
Windows API however, contains a set of functions for working with console windows. The list of these functions is available in MSDN.
However, to simplify the use of these functions I have created a template, wrapper class that provides methods and overloaded operators to:
- change the color for text and background
- set the cursor position
- write to the console
- read from the console
The class is called basic_console, and is a template class. There are two specializations, one for ANSI, called console, and one for UNICODE, called wconsole.
typedef basic_console< char, std::char_traits< char >> console; typedef basic_console< wchar_t, std::char_traits< wchar_t >> wconsole;
You can change the position on both horizontal and vertical or on only one of the two:
void GoTo(int x, int y) void GoToX(int x) void GoToY(int y) console_pos GetConsolePos()
There is also an overloaded operator for changing the position, specified with a console_pos structure.
_Myt& operator<<(const console_pos& pos)
For the color, you can change the text and background color, using one of these functions:
void SetForeColor(text_color::Color crText) void SetBackColor(bg_color::Color crBack) void SetColors(text_color::Color crText, bg_color::Color crBack) void SetColors(WORD colors) void SetColors(WORD crText, WORD crBack) void UseDefaultColors() _Myt& operator<<(const console_colors& col)
Number of colors are limited, but we can combine them to produce more. Windows defines separate flags for the text and background colors.
I have created two classes text_color and back_color to define mnemonics for colors based on these flags.
class text_color
{
public:
enum Color
{
Black = 0,
White = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED,
Blue = FOREGROUND_BLUE,
Green = FOREGROUND_GREEN,
Red = FOREGROUND_RED,
Yellow = FOREGROUND_RED | FOREGROUND_GREEN,
Magenta = FOREGROUND_RED | FOREGROUND_BLUE,
LightWhite = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY,
LightBlue = FOREGROUND_BLUE | FOREGROUND_INTENSITY,
LightGreen = FOREGROUND_GREEN | FOREGROUND_INTENSITY,
LightRed = FOREGROUND_RED | FOREGROUND_INTENSITY,
LightYellow = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
LightMagenta = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
};
};
class bg_color
{
public:
enum Color
{
Black = 0,
White = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED,
Blue = BACKGROUND_BLUE,
Green = BACKGROUND_GREEN,
Red = BACKGROUND_RED,
Yellow = BACKGROUND_RED | BACKGROUND_GREEN,
Magenta = BACKGROUND_RED | BACKGROUND_BLUE,
LightWhite = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY,
LightBlue = BACKGROUND_BLUE | BACKGROUND_INTENSITY,
LightGreen = BACKGROUND_GREEN | BACKGROUND_INTENSITY,
LightRed = BACKGROUND_RED | BACKGROUND_INTENSITY,
LightYellow = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY,
LightMagenta = BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY,
};
};
Let's see several examples. The first one, shows how to print text with different colors. Moreover, the colored text is always displayed starting with column 40.
int main()
{
console con;
con.SetForeColor(text_color::White);
con << "Processing with files";
con.GoToX(40);
con << "OK" << "n";
con.SetForeColor(text_color::White);
con << "Looking for templates";
con.GoToX(40);
con.SetForeColor(text_color::LightYellow);
con << "Not found" << "n";
con.SetForeColor(text_color::White);
con << "Creating new account";
con.GoToX(40);
con.SetForeColor(text_color::LightRed);
con << "Failed" << "n";
return 0;
}
Here is the output for this program

A second example shows how to print numbers starting from 1 to N and back to 1 to form a rhomb.
int main()
{
console con;
int depth;
con << "Depth (1-9)? ";
con >> depth;
int middle = 20;
for(int i = 1; i <= depth; ++i)
{
con.GoToX(middle-i+1);
for(int j = 1; j<=i; ++j)
{
con << i << " ";
}
con << "n";
}
for(int i = depth-1; i >=1; --i)
{
con.GoToX(middle-i+1);
for(int j = 1; j<=i; ++j)
{
con << i << " ";
}
con << "n";
}
return 0;
}
And here is the output, when the selected depth is 9:

The same can be achived using the overloaded operator<< for console_pos.
int main()
{
console con;
int depth;
con << "Depth (1-9)? ";
con >> depth;
int x = 20;
int y = 2;
for(int i = 1; i <= depth; ++i)
{
con << console_pos(x-i+1, y++);
for(int j = 1; j<=i; ++j)
{
con << i << " ";
}
}
for(int i = depth-1; i >=1; --i)
{
con << console_pos(x-i+1, y++);
for(int j = 1; j<=i; ++j)
{
con << i << " ";
}
}
return 0;
}
A third and last examples shows how to read a matrix on rows and columns.

int main()
{
console con;
int rows;
int cols;
con << "rows: "; con >> rows;
con << "cols: "; con >> cols;
std::vector< int > numbers;
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < cols; ++j)
{
con.GoTo(j*4, i+2);
con << "[_]";
}
}
int val;
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < cols; ++j)
{
con.GoTo(j*4+1, i+2);
con >> val;
numbers.push_back(val);
}
}
return 0;
}
Of course, this basic_console class does not carry all the possible functionality you can imagine, but it should be good enough for basic operations.
Here is the file with the source code.









