1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
|
// Copyright 2013 Michael Thomas Greer.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file
// LICENSE_1_0.txt
// or copy at
// http://www.boost.org/LICENSE_1_0.txt )
#ifndef WINCONCOLOR_HPP
#define WINCONCOLOR_HPP
/*
Provides the following ostream manipulators
colors() -- reset both colors to the initial color
colors( int fg, int bg ) -- set both colors at once
color ( int fg )
fgcolor( int fg ) -- set the foreground color
bgcolor( int bg ) -- set the background color
The way that high-intensity background colors appear on your terminal
depends on your user's environment. Modern Windows systems will use the
specified color, but older ones may use the darker color and cause the
foreground color to blink. There is no way to fix this without obtrusive
dinking around with Windows internals. Sorry.
Example:
#include <iostream>
#include <limits>
#include "winconcolor.hpp"
using namespace std;
int main()
{
string user_name;
cout << "What is your "
<< console::color( console::dark_cyan ) << "name"
<< console::colors() << "? ";
cout << console::color( console::light_cyan );
cin >> user_name;
cin.ignore( numeric_limits <streamsize> ::max(), '\n' );
cout << console::colors() << "Hello "
<< console::color( console::dark_cyan ) << user_name
<< console::colors() << "!\n";
return 0;
}
Notice that color changes are PERSISTENT, and that INPUT is also affected
by colors.
At the end of your program, the console colors are automatically reset to
their initial values (when your program started).
*/
#include <iostream>
#define NO_MINMAX
#include <windows.h>
namespace console
{
enum
{
black,
dark_blue,
dark_green,
dark_cyan,
dark_red,
dark_magenta,
dark_yellow,
light_gray,
dark_gray,
light_blue,
light_green,
light_cyan,
light_red,
light_magenta,
light_yellow,
white
};
struct colors_t
{
HANDLE hstdout;
int initial;
colors_t():
hstdout( GetStdHandle( STD_OUTPUT_HANDLE ) ),
initial( get() )
{ }
~colors_t()
{
set( initial );
}
int get() const
{
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo( hstdout, &csbi );
return csbi.wAttributes;
}
colors_t& set( int color )
{
SetConsoleTextAttribute( hstdout, color );
return *this;
}
colors_t& set( int fg, int bg )
{
return set( ((bg & 0x0F) << 4) | (fg & 0x0F) );
}
int fg() const
{
return get() & 0x0F;
}
colors_t& fg( int color )
{
int current_colors = get();
return set( (current_colors & 0xF0) | (color & 0x0F) );
}
int bg() const
{
return (get() >> 4) & 0x0F;
}
colors_t& bg( int color )
{
int current_colors = get();
return set( ((color & 0x0F) << 4) | (current_colors & 0x0F) );
}
};
colors_t& get_colors()
{
static colors_t colors;
return colors;
}
struct ostream_color_t
{
int fg;
int bg;
ostream_color_t( int fg, int bg ): fg( fg ), bg( bg ) { }
};
std::ostream& operator << ( std::ostream& outs, const ostream_color_t& c )
{
get_colors().set(
(c.fg < 0) ? get_colors().fg() : c.fg,
(c.bg < 0) ? get_colors().bg() : c.bg
);
return outs;
}
ostream_color_t colors()
{
return ostream_color_t(
get_colors().initial & 0x0F,
get_colors().initial >> 4
);
}
ostream_color_t colors( int fg, int bg ) { return ostream_color_t( fg, bg ); }
ostream_color_t color ( int color ) { return ostream_color_t( color, -1 ); }
ostream_color_t fgcolor( int color ) { return ostream_color_t( color, -1 ); }
ostream_color_t bgcolor( int color ) { return ostream_color_t( -1, color ); }
} // namespace console
#endif
|