问题
I'm writing a dynamic color palette for console terminal. The thing is to get ANSI ESC sequences to work within a default wincon terminal is enough to set those flags to the handles of the console:
DWORD dwRequestedOutModes = ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN;
DWORD dwRequestedInModes = ENABLE_VIRTUAL_TERMINAL_INPUT;
but using them is another thing. Right now my console engine outputs screen buffer made with CHAR_INFO
with WriteConsoleOutputW()
, but CHAR_INFO
itself supports only 16 default scheme colors.
Using CONSOLE_SCREEN_BUFFER_INFOEX
is again limited by 16 colors, but this time custom.
Using console ESC sequences is a good point, but the problem is I've found only examples of using printf()
. For my project printf is too slow and unreliable, is there any other way to assign ESC sequence to each symbol in buffer.
Here is an example of my code:
WriteConsoleOutputW(this->m_hConsole, this->localFrame, (COORD){ (short)this->m_nScreenWidth, (short)this->m_nScreenHeight }, (COORD){ 0,0 }, &this->m_rectWindow);
Drawing routine: localFrame is CHAR_INFO pointer
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;
}
}
It looks like C++ code, but this one is my self made C with classes, so it is ANSI-C wrap-up made for educational purposes.
The question is: How to colorize the output of the console with Escape sequences, and where to put them, with it being able to print something like this:
using ' ' char(space) and setting background color to ESC [48 ; 2 ; r ; g ; b or ESC [48 ; 5 ; s
回答1:
Turns out the low-level function can be done to write something in console without any checks. For this it's required only two things: char buffer and 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);
where hOut is a console handle. Turns out this one is being processed by the terminal and is fast, as it lasts only for couple thousands of ticks. I had to reverse the entire printf() to find this one out. Maybe there is something faster, but WriteFile is irreversible, it stops the execution when I reach out for assembly.
来源:https://stackoverflow.com/questions/55472554/how-to-use-esc-sequences-to-set-foreground-colors