2

How can I get ANSI escape codes to output coloured terminal outputs in the Windows CMD console using a C++ console application?

This is what I've tried so far:

 #include <windows.h>
 #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
 #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
 #endif

 int main()
 {
    HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
    SetConsoleMode(h, ENABLE_VIRTUAL_TERMINAL_PROCESSING);
    printf("%c[%dm foo!\n", 0x1B, 32);              // 1
    printf("\e[31m foo \e[0m bar\n");               // 2
    printf("^\u0001b[31m foo \u0001b[0m bar\n");    // 3
    printf("^[[31m foo");                           // 4
    printf("\033[1;31m foo \e[0m bar\n");           // 5

 };
  1. Following this thread, in C++, printf("%c[%dmHELLO!\n", 0x1B, 32); should work, but it doesn't - for me, it outputs [32MHELLO!.
  2. printf("\e[31m foo \e[0m bar"); should output a red foo and a default bar, but just prints ?[31m foo ?[0m bar.
  3. Replacing \e with \u001b does nothing.
  4. Copying the functioning string from the cmd window ^[[31m foo and using that in printf
  5. Going with a different escape character, printf("\033[1;32m foo \e[0m bar");

I also tested output using both printf("foo") and std::out << "foo"; for all examples listed above. Nothing works. I could understand if the full XTERM colours weren't supported, but ANSI is a basic expectation, in my opinion. As far as I know, ANSI codes are supported in the default command prompt window. Which is why I'm confused over this.

ctrl+[ followed by 31m in the Windows CMD window does allow for ANSI colouration in the window - so why can't I do this from C++?

This isn't a particularly pressing issue, but it's one that's been troubling me anyway. I'm certain it should be possible, but I just can't get it working.

genpfault
  • 51,148
  • 11
  • 85
  • 139
  • 1
    Note that this is a feature of the terminal displaying your program's output, regardless of which programming language that program is implemented in... – DevSolar Mar 04 '20 at 12:36
  • @DevSolar - fair point, I've adjusted my question to try and make it a bit clearer. Hopefully it makes a bit more sense now. – Alan Lovell Mar 04 '20 at 12:46
  • They MIGHT be supported. It users settings determined and only later builds of Windows 10. This technique is the ONLY one that will work on all Windows version using standard API calls https://winsourcecode.blogspot.com/2019/12/colourtext-changes-colour-of-text-to-be.html –  Mar 04 '20 at 17:35

1 Answers1

1

ENABLE_VIRTUAL_TERMINAL_PROCESSING applies to the output buffer. This works:

HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
SetConsoleMode(hInput, ENABLE_VIRTUAL_TERMINAL_INPUT);
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleMode(hOutput, ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
TTimo
  • 1,276
  • 1
  • 13
  • 20