I am engaged in a school project in which I often need to change the color of the text. The goal of the project is currently a console application for Windows only. Using Codeblocks with MinGW for debugging. I'm not a noob, but intermediate-ish.
Therefore, using this everywhere in the code was ugly:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), __col._colour_code);
Even if I wrapped it in a function, it is still cumbersome and ugly because you cannot continue your cout chain. You split the chain like you should call SetColour in the new expression, for example:
SetColour(GRAY); cout << setcol(PURPLE) << " ID:["; SetColour(AQUA); cout << song.GetID(); SetColour(GRAY); cout << "]" << " "; SetColour(GREEN); cout << song.GetTitle(); SetColour(WHITE); cout << " by "; SetColour(BRIGHT); cout << song.GetArtist() << "\n";
What I wanted was functionality like setw , setprecision , etc. So I opened iomainp.h and looked for some hints:
struct _Setw { int _M_n; }; inline _Setw setw(int __n) { return { __n }; } template<typename _CharT, typename _Traits> inline basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, _Setw __f) { __is.width(__f._M_n); return __is; } template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, _Setw __f) { __os.width(__f._M_n); return __os; }
Thus, I created a new function myself in a 100% way:
enum Colour { BLACK=0x00, DARK_GREEN=0x02, WHITE=0x07, GRAY, BLUE=0x09, GREEN, AQUA, RED, PURPLE, YELLOW, BRIGHT }; struct _colour_struct { uint8_t _colour_code; }; inline _colour_struct setcolour (Colour colour_foregrnd, Colour colour_backgrnd =BLACK) { uint8_t colour_code = colour_backgrnd; colour_code <<= 4; colour_code |= colour_foregrnd; return { colour_code }; } namespace std { template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, _colour_struct __col) { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), __col._colour_code); return __os; } }
SURPRISE! (for me) His work !! eg:.
cout << setcolour(GRAY) << " ID:[" << setcolour(AQUA) << song.GetID() << setcolour(GRAY) << "]" << " " << setcolour(GREEN) << song.GetTitle() << setcolour(WHITE) << " by "<< setcolour(BRIGHT) << song.GetArtist() << "\n";
But consider the output of this code:
std::cout << std::setw(20) << setcolour(AQUA) << "1st time" << "\n"; std::cout << "2nd time" << "\n"; std::cout << "3rd time" << "\n";
Note that setw DID NOT stick, this was a Reset in the second line. How?? (Debugging did not show that an additional call was made before Reset.)
But my SetColour DID is for the rest of the program. What for?? (Although its 100% similar to setw ).
How to make SetColour same as setw ??? I need this function to make my program cleaner and more logical.
I also found the following: Which iomanip manipulators are sticky
But the answers and comments only confused me. Apparently setw calls cout.width (0), but debugging did not show such a call, and such a line of code was not found in iomanip.h . And did not understand the answer there. Please explain.
EDIT
Perhaps I was not a direct question in the question. How cout.width(0) (in the context of setw ) is called every time,
How can I make my SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0) (in the context of SetColour ) called every time? How do I approach this problem?