c - 如何使用 ESC 序列设置前景色?
问题描述
我正在为控制台终端编写一个动态调色板。问题是让 ANSI ESC 序列在默认的 wincon 终端中工作足以将这些标志设置为控制台的句柄:
DWORD dwRequestedOutModes = ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN;
DWORD dwRequestedInModes = ENABLE_VIRTUAL_TERMINAL_INPUT;
但使用它们是另一回事。现在我的控制台引擎输出用CHAR_INFO
with制作的屏幕缓冲区WriteConsoleOutputW()
,但CHAR_INFO
它本身只支持 16 种默认方案颜色。
使用CONSOLE_SCREEN_BUFFER_INFOEX
再次受到 16 种颜色的限制,但这次是定制的。
使用控制台 ESC 序列是一个好点,但问题是我只找到了使用printf()
. 对于我的项目 printf 太慢且不可靠,有没有其他方法可以将 ESC 序列分配给缓冲区中的每个符号。
这是我的代码示例:
WriteConsoleOutputW(this->m_hConsole, this->localFrame, (COORD){ (short)this->m_nScreenWidth, (short)this->m_nScreenHeight }, (COORD){ 0,0 }, &this->m_rectWindow);
绘图例程:localFrame 是 CHAR_INFO 指针
void PrintFrameW(void* self, int x, int y, wchar_t character, short color)
{
struct c_class* this = self;
if (x >= 0 && x < this->nFrameLength&&y >= 0 && y < this->nFrameHeight)
{
this->localFrame[y*this->nFrameLength + x].Char.UnicodeChar = character;
this->localFrame[y*this->nFrameLength + x].Attributes = color;
}
}
它看起来像 C++ 代码,但这是我自制的带有类的 C,所以它是为教育目的而制作的 ANSI-C 总结。
问题是:如何使用转义序列为控制台的输出着色,以及将它们放在哪里,它能够打印如下内容:
使用 ' ' char(space) 并将背景颜色设置为 ESC [48 ; 2; r; G ; b 或 ESC [48 ; 5; s
解决方案
事实证明,可以在控制台中编写一些低级函数而无需任何检查。为此,它只需要两件事:char buffer 和 WriteFile()。
char lfbuf[5120U] = { '\x1b','[','3','8',';','2',';','1','0','0',';','0',';','0','m','w','\0' };
DWORD const lfbuf_length = (DWORD)(17);
DWORD written;
WriteFile(hOut, lfbuf, lfbuf_length, &written, NULL);
其中 hOut 是控制台句柄。事实证明,这是由终端处理的,而且速度很快,因为它只持续几千个滴答声。我不得不反转整个 printf() 才能找到这个。也许有更快的东西,但 WriteFile 是不可逆的,当我伸手组装时它会停止执行。
推荐阅读
- python - 如何让我的代码中的访客计数器显示在客户端,或者如何让我的值变为整数
- reactjs - 将文章滚动到视图之外并隐藏它的最佳方法
- apache - 同一服务器上的两个域的配置
- javascript - Vue多选模板槽清除不起作用
- javascript - 如何替换javascript数组的对象
- python - Python '返回向量 if vector.shape else vector.item()'
- android - 在特定应用程序中打开自定义文件扩展名
- java - 如何重置 JTable 列箭头
- javascript - 为什么所有网络播放器都不支持 akamaid m3u8 链接
- html - 无法显示与伪类混合的背景图像