调用<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
不知道写库函数的人是怎么想的,只给定三原色......^_^