本文为转载文档,源文档地址:http://blog.csdn.net/bnb45/article/details/7997603
效果
[cpp] view plaincopy
- #include "MyConsole.h"
- #include <stdio.h>
- int main()
- {
- CMyConsole myConsole;
- SMALL_RECT rc = {5, 5, 20, 20};
- myConsole.DrawBox(rc);
- system("pause");
- return 0;
- }
边框并不是用线条画出来的,实际上控制台好像还不能画线条。边框的制作是用字符堆集起来的,有的字符是一条横线,有的是一条折线。把它们按照矩形的顺序摆放,就画出框了。原理有点像下面一幅图(草泥马の鄙视):
┏┛┻━━━━┛┻┓
┃ ┃
┃ ━ ┃
┃ ┳┛ ┗┳ ┃
┃ ┃
┃ ┻ ┃
┃ ┃
┗━┓ ┏━┛
┃ ┃
┃ ┃
┃ ┗━━━━┓
┃ ┣┓
┃ ┏┛
┗━┓┓┏━━┳┓┏━┛
┃┫┫ ┃┫┫
┗┻┛ ┗┻┛
千里马常有,而伯乐不常有,因而伯乐相比千里马更为珍贵(扯远了Orz)。线条状的字符不是都可以找得到,用得出来。在Unicode编码下,我就不知道哪个字符编码代表线条,就算是使用ASCII有时候也无法正常显示。其原因在于,为了扩展原本短小精悍的字符集,微软使用了代码页。不同代码页可以显示各种字符(同时也意味着不能显示各种字符),比如使用437 DOS不能显示中文;而使用936简体中文则无法画出边框。控制台设置代码页的函数是:SetConsoleOutputCP。
代码页(Code page) | 说明 |
1258 | 越南文 |
1257 | 波罗的海文 |
1256 | 阿拉伯文 |
1255 | 希伯来文 |
1254 | 土耳其语 |
1253 | 希腊文 |
1252 | 拉丁文(ANSI) |
1251 | 斯拉夫文 |
1250 | 中欧文 |
950 | 繁体中文 |
949 | 韩文 |
936 | 简体中文 |
932 | 日文 |
874 | 泰文 |
850 | 使用多种语言(MS-DOS拉丁文) |
437 | MS-DOS美语/英语 |
[cpp] view plaincopy
- // ---- 画边框 ---- 第二个参数为true,则画双线边框
- void CMyConsole::DrawBox(SMALL_RECT rc, bool bDouble)
- {
- char chBox[6]; // 边框线字符
- COORD pos;
- // -- 设置代码页 -- 在437代码页中,以下字符编码才会代表线条字符
- SetConsoleOutputCP(437);
- if (bDouble) // 双线的字符
- {
- chBox[0] = (char)0xc9; // 左上角点
- chBox[1] = (char)0xbb; // 右上角点
- chBox[2] = (char)0xc8; // 左下角点
- chBox[3] = (char)0xbc; // 右下角点
- chBox[4] = (char)0xcd; // 水平
- chBox[5] = (char)0xba; // 坚直
- }
- else
- {
- chBox[0] = (char)0xda; // 左上角点
- chBox[1] = (char)0xbf; // 右上角点
- chBox[2] = (char)0xc0; // 左下角点
- chBox[3] = (char)0xd9; // 右下角点
- chBox[4] = (char)0xc4; // 水平
- chBox[5] = (char)0xb3; // 坚直
- }
- // -- 画上下边界
- for (pos.X = rc.Left; pos.X <= rc.Right; ++pos.X)
- {
- if (pos.X == rc.Left)
- {
- pos.Y = rc.Top; // 设置坐标 -> 左上角
- // -- 复制一段文本到缓冲区中
- // @param HANDLE [in] 句柄
- // @param LPCTSTR [in] 文本指针
- // @param DWORD [in] 文本的长度
- // @param COORD [in] 开始的坐标
- // @param LPDWORD [out] 接收已写入的字符数量
- WriteConsoleOutputCharacter(hOut, &chBox[0], 1, pos, NULL);
- pos.Y = rc.Bottom; // 设置坐标 -> 左下角
- WriteConsoleOutputCharacter(hOut, &chBox[2], 1, pos, NULL);
- }
- else if (pos.X == rc.Right)
- {
- pos.Y = rc.Top; // 设置坐标 -> 右上角
- WriteConsoleOutputCharacter(hOut, &chBox[1], 1, pos, NULL);
- pos.Y = rc.Bottom; // 设置坐标 -> 右下角
- WriteConsoleOutputCharacter(hOut, &chBox[3], 1, pos, NULL);
- }
- else
- {
- pos.Y = rc.Top; // 上水平线
- WriteConsoleOutputCharacter(hOut, &chBox[4], 1, pos, NULL);
- pos.Y = rc.Bottom; // 下水平线
- WriteConsoleOutputCharacter(hOut, &chBox[4], 1, pos, NULL);
- }
- }
- // -- 画左右边界
- for (pos.Y = rc.Top+1; pos.Y < rc.Bottom; ++pos.Y)
- {
- pos.X = rc.Left; // 画左边线条
- WriteConsoleOutputCharacter(hOut, &chBox[5], 1, pos, NULL);
- pos.X = rc.Right; // 画右边线条
- WriteConsoleOutputCharacter(hOut, &chBox[5], 1, pos, NULL);
- }
- }