文章目录
前言
建议在观看此文章前先观看【C++】Windows控制台API基本使用(上)。
十三、控制台字体
二、字体不支持当前代码页
这应该是新版控制台的一项限制,在旧版控制台,笔者并未见过某些字体因不支持中文而不能切换,所以程序可以通过更改代码页以使用字体。
笔者电脑中安装有 Cascadia Code 字体,这里使用这款字体做演示。
#include <stdio.h>
#include <Windows.h>
int main() {
// 切换编码
SetConsoleOutputCP(437);
SetConsoleCP(437);
// 设置字体
CONSOLE_FONT_INFOEX fontInfo;
fontInfo.cbSize = sizeof(fontInfo);
// 获取字体信息
GetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &fontInfo);
// 自定义设置
fontInfo.dwFontSize.X = 8;
fontInfo.dwFontSize.Y = 20;
wcscpy_s(fontInfo.FaceName, L"Cascadia Code");
// 让更改生效
SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &fontInfo);
printf("Test....\n");
getchar();
return 0;
}
字体生效了。
十四、填充指定行
Windows 控制台特性,若程序频繁朝控制台输出文本,则当用户标记了指定区域并复制会导致输出错位。
填充指定行可以补救这种问题。要填充指定行有两种方法,一种直接输出,另一种用API。
一、直接输出
直接使用cout或printf输出,这种方法简单,易用,并且可以跨平台,请看例子。
#include <stdio.h>
#include <Windows.h>
int main() {
// 获取控制台缓冲区大小
// 获取输出句柄
HANDLE outputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(outputHandle, &info);
// 输出要被删除的文本
printf("这行文本会在按下回车后删除。");
getchar();
// 移动光标到上一行
printf("\033[1A");
// 删除文本
printf("\r");
int rangeI = 0;
for (; rangeI < info.dwSize.X; rangeI++) {
printf(" ");
}
return 0;
}
这种方法的优缺点:
优点:
1. 跨平台。
2. 易写,易用。
缺点:
1. 在填充最后一行时光标会换行,让第一行离开显示范围。
2. Windows 旧版控制台(新版不知道有没有这个特性)特性会导致填充后,光标后的第一个字符出现残缺。
二、使用API
使用 (旧版API)FillConsoleOutputCharacter 可以使用指定字符填充行,下面是此 API 的原型:
BOOL WINAPI FillConsoleOutputCharacter(
_In_ HANDLE hConsoleOutput, // 输出句柄
_In_ TCHAR cCharacter, // 要填充的字符
_In_ DWORD nLength, // 填充长度
_In_ COORD dwWriteCoord, // 要写入的第一个位置的坐标
_Out_ LPDWORD lpNumberOfCharsWritten // 返回实际填充的字符的数量
);
此函数执行成功将会返回非0值。利用这个函数和上次介绍的 GetConsoleScreenBufferInfo 可以填充一行。
#include <stdio.h>
#include <Windows.h>
int main() {
// 获取控制台缓冲区大小
// 获取输出句柄
HANDLE outputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO info {
0}; // 缓冲区信息
// 输出要被删除的文本
printf("#include <stdio.h>\n");
printf("int main() {\n");