调用<windows.h>库中几个最常用的WINAPI函数,重载了操作符<<,使得cout可以定位输出以及设置颜色。
用法: cout<<Goto(x,y)<<setC(foreColor,bgColor)<<“输出内容”<<cr;
Goto(x,y) 定位到坐标(x,y) ,控制台窗口的左上角第一格坐标为(0,0);
Goto(x) 定位坐标到本行的 x ,即默认y为当前行;
Goto() 回到本行行首,即回车不换行。
cr() 回车且换行,与std::endl等效。
setC(foreColor,bgColor) 设置前景色和背景色;
setC(foreColor) 只设置前景色,背景色不变;
setC() 前景色和背景色恢复到控制台默认值。
foreColor,bgColor 取值范围 0 ~ 15,对应颜色值如下:
/* setC()设置的颜色值与 DOS内部命令COLOR的相类似
如下列表中,只要把其中的A~F换成10~15即可:
D:\CPP>color /?
设置默认的控制台前景和背景颜色。
0 = 黑色 8 = 灰色
1 = 蓝色 9 = 淡蓝色
2 = 绿色 A = 淡绿色
3 = 浅绿色 B = 淡浅绿色
4 = 红色 C = 淡红色
5 = 紫色 D = 淡紫色
6 = 黄色 E = 淡黄色
7 = 白色 F = 亮白色
*/
源代码:
#include <iostream> #include <windows.h> #define Stream std::basic_ostream<T1, T2>& using namespace std; struct HannsC { DWORD fc; DWORD bg; }; struct HannXy { SHORT pX; SHORT pY; }; HannsC setC(DWORD fc = 7, DWORD bg = 0) { return {fc % 16, bg % 16 *16}; } HannXy Goto(SHORT x = 0, SHORT y = -1) { return {x, y}; } template<typename T1, typename T2> Stream operator<<(Stream _os, HannsC _mc) { HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hConsole,_mc.fc|_mc.bg); return _os; } template<typename T1, typename T2> Stream operator<<(Stream _os, HannXy _xy) { CONSOLE_SCREEN_BUFFER_INFO pBuffer; COORD position = {_xy.pX, _xy.pY}; HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); if (position.Y==-1){ GetConsoleScreenBufferInfo(hConsole, &pBuffer); position.Y = pBuffer.dwCursorPosition.Y; } SetConsoleCursorPosition(hConsole, position); return _os; } template<typename T1, typename T2> Stream cr(Stream _out) { _out.put('\n'); _out.flush(); return _out; } int main(void) { cout << setC(23,3) << "abcdefghijklmnopqrstuvwxyz" << cr; cout << Goto(16,3) << setC(14,9) << "abcdefghijkl" << setC(9,14) << Goto(30) << 123 << cr << cr; cout << setC(13,6) << 12312303236131230 << cr; cout << setC(3,15) << Goto(18,10) << "3.14159265358979323"; cout << Goto(30) << setC(12) << "END!" << Goto() << "cr && !lf"; cout << setC() << cr; return 0; }
输出效果:
DOS颜色命令COLOR的色号着实有点难记,顺便吐槽一下微软翻译的颜色中文名;还是自己动手宏定义这些颜色名称吧:
源代码稍微作改进,既方便颜色的记忆也增加了代码的可阅读性:
#include <iostream> #include <windows.h> using namespace std; #define cBlack 0 #define cNavy 1 #define cGreen 2 #define cTeal 3 #define cMaroon 4 #define cPurple 5 #define cOlive 6 #define cSliver 7 #define cGray 8 #define cBlue 9 #define cLime 10 #define cCyan 11 #define cRed 12 #define cMagenta 13 #define cYellow 14 #define cWhite 15 struct HannsC { DWORD fc; DWORD bg; }; struct HannXy { SHORT pX; SHORT pY; }; HannsC setC(DWORD fc = cSliver, DWORD bg = cBlack) { return {fc % 16, bg % 16 *16}; } HannXy Goto(SHORT x = 0, SHORT y = -1) { return {x, y}; } ostream& operator<<(ostream& _os, HannsC _mc) { HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hConsole,_mc.fc|_mc.bg); return _os; } ostream& operator<<(ostream& _os, HannXy _xy) { CONSOLE_SCREEN_BUFFER_INFO pBuffer; COORD position = {_xy.pX, _xy.pY}; HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); if (position.Y==-1){ GetConsoleScreenBufferInfo(hConsole, &pBuffer); position.Y = pBuffer.dwCursorPosition.Y; } SetConsoleCursorPosition(hConsole, position); return _os; } ostream& cr(ostream& _out) { _out.put('\n'); _out.flush(); return _out; } int main(void) { cout << setC(cNavy,cLime) << "abcdefghijklmnopqrstuvwxyz" << cr; cout << Goto(16,3) << setC(cYellow,cBlue) << "abcdefghijkl" << setC(cBlue,cYellow) << Goto(30) << 123 << cr << cr; cout << setC(cMagenta,cOlive) << 12312303236131230 << cr; cout << setC(cGreen,cWhite) << Goto(18,9) << "3.1415926535897932384626"; cout << Goto(30) << setC(cRed) << "END!" << Goto() << "cr && !lf"; cout << setC(cCyan) << cr << cr << "my C++ version: " << __cplusplus ; cout << setC() << cr; return 0; }
附录:SetConsoleTextAttribute:
函数原型:
WINBASEAPI WINBOOL WINAPI SetConsoleTextAttribute(HANDLE hConsoleOutput,WORD wAttributes);
函数用法:
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hConsole,foregroundColor|backgroundColor);
只有三原色用以下宏常量设置:
FOREGROUND_RED 表示设置前景色为红色。
FOREGROUND_GREEN 表示设置前景色为绿色。
FOREGROUND_BLUE 表示设置前景色为蓝色。
BACKGROUND_RED 表示设置背景色为红色。
BACKGROUND_GREEN 表示设置背景色为绿色。
BACKGROUND_BLUE 表示设置背景色为蓝色。
其他颜色就用此6个宏及以下两个宏,做或运算得到。
FOREGROUND_INTENSITY 表示设置前景色为高亮显示。
BACKGROUND_INTENSITY 表示设置背景色为高亮显示。
例如设置高亮白色字体,用以下代码:
FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE
不知道写库函数的人是怎么想的,只给定三原色......^_^