Resource icon

[C / C++] Ausgabe von ANSI Escapesequenzen auf Windows 10 aktivieren

Programmiersprache(n)
C
Betriebssystem(e)
Windows 10
Microsoft macht kleine Schritte sich in Teilbereichen in Richtung Open Source zu entwickeln und steht ihren Wettbewerbern im Open Source Bereich nicht mehr feindlich und mit kategorischer Ablehnung gegenüber. Auf einem Windows 10 kann das WSL (Windows Subsystem for Linux) aktiviert werden, sodass eine Linux Distribution nachinstalliert werden kann und auch native Linux Anwendungen ausgeführt werden können. Das hat auch eine Anpassung des Console Hosts zur Folge gehabt, sodass nun auch ANSI Escapesequenzen verarbeitet werden können. Dieses Feature wird von den Scriptinterpretern automatisch aktiviert. Stand-alone Konsoleanwendungen müssen das aber selbständig tun, falls dort mit dem sogenannten "Virtual Terminal" Modus gearbeitet werden soll.

Für alle die sich nicht mit der Windows API beschäftigen wollen, gibt es hier ein kleines Header-Source Paar mit nur einer Funktion die den Virtual Terminal Modus aktivieren bzw. deaktivieren kann, ansonsten aber die Windows API aus eurem sauberen C oder C++ Code ausschließt. Voraussetzung ist min. Windows Version 10.0.10586.

win10vt.h
C:
#ifndef WIN10VT_H_INCLUDED__
#define WIN10VT_H_INCLUDED__

#ifdef __cplusplus
extern "C"
#endif

/** \brief  Enable or disable Virtual Terminal processing of ANSI escape sequences.
  *   Virtual Terminal processing requires Windows version 10.0.10586 or newer, and the new Windows 10 console.
  *
  * \param   enable   Nonzero value to enable Virtual Terminal processing. Zero to disable Virtual Terminal processing.
  *
  * \return  int      Nonzero value if the function succeeded. Zero if the function failed. */
int UpdateVTMode(const int enable);

#endif // WIN10VT_H_INCLUDED__

win10vt.c
C:
#undef WINVER
#define WINVER 0x0A00
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0A00
#undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

// some implementations don't define them:
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
# define ENABLE_VIRTUAL_TERMINAL_PROCESSING ((DWORD)0x4)
#endif
#ifndef DISABLE_NEWLINE_AUTO_RETURN
# define DISABLE_NEWLINE_AUTO_RETURN ((DWORD)0x8)
#endif
#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
# define ENABLE_VIRTUAL_TERMINAL_INPUT ((DWORD)0x200)
#endif

int UpdateVTMode(const int enable)
{
  DWORD mode_out = 0ul, mode_in = 0ul;
  HANDLE h_out = GetStdHandle(STD_OUTPUT_HANDLE), h_in = GetStdHandle(STD_INPUT_HANDLE);
  if (GetConsoleMode(h_out, &mode_out) != FALSE && GetConsoleMode(h_in, &mode_in) != FALSE)
  {
    if (enable == 0)
    {
      mode_out &= ~(ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN);
      mode_in &= ~ENABLE_VIRTUAL_TERMINAL_INPUT;
    }
    else
    {
      mode_out |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN;
      mode_in |= ENABLE_VIRTUAL_TERMINAL_INPUT;
    }

    if (SetConsoleMode(h_out, mode_out) != FALSE && SetConsoleMode(h_in, mode_in) != FALSE)
      return 1;
  }

  return 0;
}

Kurzer Code zum Test:
Code:
#include <stdio.h>
#include "win10vt.h"

int main(void)
{
  puts("\x1B[42mHello World!\x1B[0m");

  if (UpdateVTMode(1) == 0)
    return 1;

  puts("\x1B[42mHello World!\x1B[0m");

  if (UpdateVTMode(0) == 0)
    return 1;

  puts("\x1B[42mHello World!\x1B[0m");

  return 0;
}
... ergibt ...

1556710708363.png


... wobei lediglich bei der zweiten Zeile der Virtual Terminal Modus aktiviert war.
Autor
German
First release
Last update
Bewertung
0,00 Stern(e) 0 Bewertungen

More resources from German

Oben