我正在为控制台终端编写动态调色板。问题是让ANSI ESC序列在默认的wincon终端中工作就足以将这些标志设置到控制台的句柄:
DWORD dwRequestedOutModes = ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN;
DWORD dwRequestedInModes = ENABLE_VIRTUAL_TERMINAL_INPUT;
但使用它们是另一回事。现在我的控制台引擎输出用CHAR_INFO
和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总结。
问题是:如何使用Escape序列为控制台的输出着色,以及在何处放置它们,它能够打印出如下内容:
使用''char(空格)并将背景颜色设置为ESC [48; 2; r; G ; b或ESC [48; 5;小号
事实证明,可以在没有任何检查的情况下在控制台中写入一些低级功能。为此,它只需要两件事:char缓冲区和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是不可逆转的,当我伸出装配时它会停止执行。