Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Virtuelle Terminalsequenzen sind Steuerzeichensequenzen, mit denen Cursorbewegungen, Konsolenfarbe und andere Vorgänge gesteuert werden können, wenn sie in den Ausgabedatenstrom geschrieben werden. Sequenzen können auch im Eingabedatenstrom als Reaktion auf eine Informationssequenz zur Ausgabedatenstromabfrage oder als Codierung der Benutzereingabe empfangen werden, wenn der entsprechende Modus festgelegt wird.
Sie können getConsoleMode- und SetConsoleMode-Funktionen verwenden, um dieses Verhalten zu konfigurieren. Am Ende dieses Dokuments finden Sie ein Beispiel für die vorgeschlagene Methode zum Aktivieren des virtuellen Terminalverhaltens.
Das Verhalten der folgenden Sequenzen basiert auf den VT100- und abgeleiteten Terminal-Emulatortechnologien, insbesondere dem xterm-Terminal-Emulator. Weitere Informationen zu Terminalsequenzen finden Sie unter http://vt100.net und unter http://invisible-island.net/xterm/ctlseqs/ctlseqs.html.
Ausgabesequenzen
Die folgenden Terminalsequenzen werden beim Schreiben in den Ausgabedatenstrom vom Konsolenhost abgefangen, wenn das ENABLE_VIRTUAL_TERMINAL_PROCESSING Flag auf dem Bildschirmpufferhandle mithilfe der SetConsoleMode-Funktion festgelegt wird. Beachten Sie, dass das DISABLE_NEWLINE_AUTO_RETURN-Flag möglicherweise auch beim Emulieren der Cursorpositionierung und des Bildlaufverhaltens anderer Terminalemulatoren in Bezug auf Zeichen, die in die letzte Spalte in einer beliebigen Zeile geschrieben wurden, hilfreich sein kann.
Einfache Cursorpositionierung
In allen folgenden Beschreibungen ist ESC immer der hexadezimale Wert 0x1B. Es sind keine Leerzeichen in Terminalsequenzen enthalten. Einzelne Terminalsequenzen können an beliebiger Zeichen- oder Byteposition über mehrere sequenzielle Aufrufe von WriteFile oder WriteConsole aufgeteilt werden, es empfiehlt sich jedoch, die gesamte Sequenz in einen Aufruf einzuschließen. Ein Beispiel dafür, wie diese Sequenzen in der Praxis verwendet werden, finden Sie im Beispiel am Ende dieses Themas.
In der folgenden Tabelle werden einfache Escapesequenzen mit einem einzelnen Aktionsbefehl direkt hinter dem ESC-Zeichen beschrieben. Diese Sequenzen haben keine Parameter und werden sofort wirksam.
Alle Befehle in dieser Tabelle entsprechen im Allgemeinen dem Aufrufen der SetConsoleCursorPosition-Konsolen-API zum Platzieren des Cursors.
Die Cursorbewegung wird vom aktuellen Viewport in den Puffer gebunden. Scrollen (sofern verfügbar) tritt nicht auf.
| Reihenfolge | Kurzschrift | Verhalten |
|---|---|---|
| ESC M | RI | Umgekehrter Index – Führt den umgekehrten Vorgang von \naus, verschiebt den Cursor um eine Zeile nach oben, behält die horizontale Position bei, scrollt bei Bedarf puffert* |
| ESC 7 | DECSC | Cursorposition im Arbeitsspeicher speichern** |
| ESC 8 | DECSR | Cursorposition aus Speicher wiederherstellen** |
Hinweis
* Wenn Bildlaufränder festgelegt sind, scrollt RI innerhalb der Ränder nur durch den Inhalt der Seitenränder und lässt den Viewport unverändert. (Siehe Bildlaufränder)
**Es wird bis zur ersten Verwendung des Speicherbefehls kein Wert im Arbeitsspeicher gespeichert. Die einzige Möglichkeit für den Zugriff auf den gespeicherten Wert ist der Befehl "Wiederherstellen".
Cursorpositionierung
Die folgenden Tabellen umfassen CSI-Typensequenzen (Control Sequence Introducer). Alle CSI-Sequenzen beginnen mit ESC (0x1B) gefolgt von [ (linke Klammer, 0x5B) und können Parameter variabler Länge enthalten, um weitere Informationen für jeden Vorgang anzugeben. Dies wird durch die Kurzform <n> dargestellt. Jede tabelle unten wird nach Funktionalität mit Notizen unterhalb jeder Tabelle gruppiert, in der erläutert wird, wie die Gruppe funktioniert.
Für alle Parameter gelten die folgenden Regeln, sofern nicht anders angegeben:
- <n> stellt den Abstand zum Verschieben dar und ist ein optionaler Parameter.
- Wenn <n> ausgelassen wird oder gleich 0 ist, wird sie als 1 behandelt.
- <n> darf nicht größer als 32.767 sein (maximaler kurzer Wert)
- <n> kann nicht negativ sein
Alle Befehle in diesem Abschnitt entsprechen im Allgemeinen dem Aufrufen der SetConsoleCursorPosition-Konsolen-API .
Die Cursorbewegung wird vom aktuellen Viewport in den Puffer gebunden. Scrollen (sofern verfügbar) tritt nicht auf.
| Reihenfolge | Programmcode | BESCHREIBUNG | Verhalten |
|---|---|---|---|
| ESC [ <n> A | CUU | Cursor nach oben | Cursor nach oben um <n> |
| ESC [ <n> B | Wiedergekäutes Futter | Cursor nach unten | Cursor nach unten um <n> |
| ESC [ <n> C | CUF | Cursor vorwärts | Cursor vorwärts (rechts) um <n> |
| ESC [ <n> D | JUNGE | Cursor rückwärts | Cursor rückwärts (links) um <n> |
| ESC [ <n> E | CNL | Cursor nächste Zeile | Cursor nach unten <n> Zeilen von der aktuellen Position |
| ESC [ <n> F | CPL | Cursor vorherige Zeile | Cursor um n> Zeilen von der aktuellen Position nach oben < |
| ESC [ <n> G | CHA | Cursor horizontal absolut | Der Cursor wird horizontal in der aktuellen Zeile zur <n>. Position verschoben. |
| ESC [ <n> d | VPA | Vertikale Linienposition absolut | Der Cursor wird vertikal zur <n>- Position in der aktuellen Spalte verschoben. |
| ESC [ <y> ; <x> H | TASSE | Cursorposition | *Cursor wird zu <x> verschoben; <y-Koordinate> innerhalb des Viewports, wobei <x> die Spalte der <y-Linie> ist |
| ESC [ <y> ; <x> f | HVP | Horizontale vertikale Position | *Cursor wird zu <x> verschoben; <y-Koordinate> innerhalb des Viewports, wobei <x> die Spalte der <y-Linie> ist |
| ESC [ s | ANSISYSSC | Cursor speichern – Ansi.sys Emulation | **Ohne Parameter führt einen Speichercursorvorgang wie DECSC aus. |
| ESC [ u | ANSISYSRC | Cursor wiederherstellen – Ansi.sys Emulation | **Ohne Parameter führt einen Wiederherstellungscursorvorgang wie DECRC aus. |
Hinweis
*<x> - und <y-Parameter> haben die gleichen Einschränkungen wie <n> oben. Wenn <x> und <y> weggelassen werden, werden sie auf 1;1 festgelegt.
**ANSI.sys historische Dokumentation finden Sie unter https://msdn.microsoft.com/library/cc722862.aspx und wird zur Benutzerfreundlichkeit/Kompatibilität implementiert.
Cursorsichtbarkeit
Mit den folgenden Befehlen wird die Sichtbarkeit des Cursors und dessen blinkender Zustand gesteuert. Die DECTCEM-Sequenzen entsprechen im Allgemeinen dem Aufrufen der SetConsoleCursorInfo-Konsolen-API zum Umschalten der Cursorsichtbarkeit.
| Reihenfolge | Programmcode | BESCHREIBUNG | Verhalten |
|---|---|---|---|
| ESC [ ? 12 h | ATT160 | Textcursor Aktivieren des Blinkens | Starten des Cursors blinkend |
| ESC [ ? 12 l | ATT160 | Textcursor Blinken deaktivieren | Beenden des Blinkens des Cursors |
| ESC [ ? 25 h | DECTCEM | Textcursor Aktivieren der Moduspräsentation | Cursor anzeigen |
| ESC [ ? 25 l | DECTCEM | Textcursor Modus ausblenden | Ausblenden des Cursors |
Tipp
Die Aktivierungssequenzen enden in einem Kleinbuchstaben H-Zeichen (h) und die deaktiven Sequenzen enden in einem Kleinbuchstaben L -Zeichen (l).
Cursor-Shape
Mit den folgenden Befehlen können Sie das Cursor-Shape anpassen.
| Reihenfolge | Programmcode | BESCHREIBUNG | Verhalten |
|---|---|---|---|
| ESC [ 0 SP q | DECSCUSR | Benutzer-Shape | Vom Benutzer konfiguriertes Standardcursor-Shape |
| ESC [ 1 SP q | DECSCUSR | Blinkender Block | Blinkende Blockcursorform |
| ESC [ 2 SP q | DECSCUSR | Stetiger Block | Ständiger Blockcursor-Shape |
| ESC [ 3 SP q | DECSCUSR | Blinkende Unterstreichung | Blinkende Unterstreichungscursorform |
| ESC [ 4 SP q | DECSCUSR | Konstante Unterstreichung | Beständiges Unterstreichungscursor-Shape |
| ESC [ 5 SP q | DECSCUSR | Blinkende Leiste | Blinkende Balkencursorform |
| ESC [ 6 SP q | DECSCUSR | Konstanter Balken | Balkencursor-Shape |
Hinweis
SP ist ein Literalzeichen (0x20) in der Zwischenposition und folgt q (0x71) an der letzten Position.
Viewportpositionierung
Alle Befehle in diesem Abschnitt entsprechen im Allgemeinen dem Aufrufen der ScrollConsoleScreenBuffer-Konsolen-API , um den Inhalt des Konsolenpuffers zu verschieben.
Vorsicht Die Befehlsnamen sind irreführend. Scroll bezieht sich auf die Richtung, in die der Text während des Vorgangs verschoben wird, nicht auf welche Weise der Viewport verschoben werden würde.
| Reihenfolge | Programmcode | BESCHREIBUNG | Verhalten |
|---|---|---|---|
| ESC [ <n> S | UU | Nach oben scrollen | Scrollen Sie nach oben um <n>. Auch als Schwenken nach unten bezeichnet, füllen sich neue Linien vom unteren Bildschirmrand aus |
| ESC [ <n> T | SD | Nach unten scrollen | Scrollen Sie um <n> nach unten. Auch als Schwenken bezeichnet, werden neue Linien vom oberen Bildschirmrand ausgefüllt. |
Der Text wird beginnend mit der Zeile verschoben, auf der sich der Cursor befindet. Wenn sich der Cursor in der mittleren Zeile des Viewports befindet, würde der Bildlauf nach oben die untere Hälfte des Viewports verschieben und leere Zeilen unten einfügen. Scrollen Sie nach unten, um die obere Hälfte der Viewportzeilen zu verschieben und neue Zeilen am oberen Rand einzufügen.
Beachten Sie auch, dass der Bildlauf nach oben und unten von den Bildlaufrändern beeinflusst wird. Der Bildlauf nach oben und unten wirkt sich nicht auf Linien außerhalb der Bildlaufränder aus.
Der Standardwert für <n> ist 1, und der Wert kann optional weggelassen werden.
Textänderung
Alle Befehle in diesem Abschnitt entsprechen im Allgemeinen dem Aufrufen von FillConsoleOutputCharacter, FillConsoleOutputAttribute und ScrollConsoleScreenBuffer-Konsolen-APIs zum Ändern des Textpufferinhalts.
| Reihenfolge | Programmcode | BESCHREIBUNG | Verhalten |
|---|---|---|---|
| ESC [ <n> @ | ICH | Zeichen einfügen | Fügen Sie <n> Leerzeichen an der aktuellen Cursorposition ein, und verschieben Sie den gesamten vorhandenen Text nach rechts. Text, der den Bildschirm nach rechts verlässt, wird entfernt. |
| ESC [ <n> P | DCH | Zeichen löschen | <n> Zeichen an der aktuellen Cursorposition löschen und leerzeichen vom rechten Rand des Bildschirms verschieben. |
| ESC [ <n> X | ECH | Zeichen löschen | Löschen Sie <n> Zeichen aus der aktuellen Cursorposition, indem Sie sie mit einem Leerzeichen überschreiben. |
| ESC [ <n> L | Illinois | Zeile einfügen | <Fügt n> Zeilen an der Cursorposition in den Puffer ein. Die Zeile, auf der sich der Cursor befindet, und die darunter liegenden Zeilen werden nach unten verschoben. |
| ESC [ <n> M | DL | Zeile löschen | <n> Zeilen aus dem Puffer werden gelöscht, beginnend mit der Zeile, auf der sich der Cursor befindet. |
Hinweis
Für IL und DL sind nur die Zeilen in den Bildlaufrändern betroffen (siehe Bildlaufränder). Wenn keine Seitenränder festgelegt sind, sind die Standardrandrahmen der aktuelle Viewport. Wenn Linien unter den Rändern verschoben werden, werden sie verworfen. Wenn Zeilen gelöscht werden, werden leere Zeilen am unteren Rand der Seitenränder eingefügt, linien von außerhalb des Viewports sind nie betroffen.
Für jede der Sequenzen ist der Standardwert für <n> , wenn er nicht angegeben wird, 0.
Für die folgenden Befehle weist der Parameter <n> drei gültige Werte auf:
- 0 löscht von der aktuellen Cursorposition (einschließlich) bis zum Ende der Zeile/Anzeige.
- 1 löscht vom Anfang der Zeile/Anzeige bis zur aktuellen Cursorposition
- 2 löscht die gesamte Zeile/Anzeige.
| Reihenfolge | Programmcode | BESCHREIBUNG | Verhalten |
|---|---|---|---|
| ESC [ <n> J | ED | Löschen in der Anzeige | Ersetzen Sie den gesamten Text im aktuellen Viewport/Bildschirm, der durch <n> durch Leerzeichen angegeben ist. |
| ESC [ <n> K | EL | Löschen in Zeile | Ersetzen Sie den gesamten Text in der Zeile durch den cursor, der durch <n> durch Leerzeichen angegeben wird. |
Textformatierung
Alle Befehle in diesem Abschnitt entsprechen im Allgemeinen dem Aufrufen von SetConsoleTextAttribute-Konsolen-APIs , um die Formatierung aller zukünftigen Schreibvorgänge in den Konsolenausgabetextpuffer anzupassen.
Dieser Befehl ist besonders darauf ausgerichtet, dass die <unten stehende n-Position> zwischen 0 und 16 Parametern akzeptieren kann, die durch Semikolons getrennt sind.
Wenn keine Parameter angegeben werden, wird sie genauso behandelt wie ein einzelner 0-Parameter.
| Reihenfolge | Programmcode | BESCHREIBUNG | Verhalten |
|---|---|---|---|
| ESC [ <n> m | SGR | Festlegen der Grafikdarstellung | Festlegen des Formats des Bildschirms und des Texts gemäß <n> |
Die folgende Tabelle mit Werten kann in <n> verwendet werden, um verschiedene Formatierungsmodi darzustellen.
Formatierungsmodi werden von links nach rechts angewendet. Das Anwenden konkurrierender Formatierungsoptionen führt dazu, dass die richtige Option Vorrang hat.
Bei Optionen, die Farben angeben, werden die Farben in der Konsolenfarbtabelle verwendet, die mithilfe der SetConsoleScreenBufferInfoEx-API geändert werden können. Wenn die Tabelle so geändert wird, dass die Position "blau" in der Tabelle einen RGB-Farbton von Rot anzeigt, werden alle Aufrufe von Vordergrundblau diese rote Farbe anzeigen, bis andernfalls geändert.
| Wert | BESCHREIBUNG | Verhalten |
|---|---|---|
| 0 | Standard | Gibt alle Attribute vor der Änderung an den Standardzustand zurück. |
| 1 | Fett/Hell | Wendet das Flag "Helligkeit/Intensität" auf Die Vordergrundfarbe an. |
| 22 | Kein Fett/Hell | Entfernt das Flag "Helligkeit/Intensität" aus der Vordergrundfarbe. |
| 4 | Unterstreichen | Fügt Unterstreichung hinzu |
| 24 | Keine Unterstreichung | Entfernt Unterstreichung |
| 7 | Negativ | Wechselt Vordergrund- und Hintergrundfarben |
| 27 | Positiv (Kein Negativ) | Gibt Vordergrund/Hintergrund auf normal zurück. |
| 30 | Vordergrund schwarz | Wendet nicht fett/hell schwarz im Vordergrund an |
| 31 | Vordergrundrot | Wendet nicht fett/hellrot im Vordergrund an |
| 32 | Vordergrundgrün | Wendet nicht fett/hellgrün im Vordergrund an |
| 33 | Vordergrundgelb | Wendet nicht fett/hellgelb im Vordergrund an |
| 34 | Vordergrundblau | Wendet nicht fett/hellblau im Vordergrund an |
| 35 | Vordergrund Magenta | Wendet nicht fett/hell magenta im Vordergrund an |
| 36 | Vordergrund Cyan | Wendet nicht fett/hell zyan im Vordergrund an |
| 37 | Vordergrund weiß | Wendet nicht fett/hellweiß im Vordergrund an |
| 38 | Vordergrund erweitert | Wendet den erweiterten Farbwert auf den Vordergrund an (siehe Details unten) |
| 39 | Vordergrundstandard | Wendet nur den Vordergrundteil der Standardwerte an (siehe 0) |
| 40 | Hintergrund Schwarz | Wendet nicht fett/hell schwarz auf Den Hintergrund an |
| 41 | Hintergrund rot | Wendet nicht fett/hellrot auf den Hintergrund an |
| 42 | Hintergrundgrün | Wendet nicht fett/hellgrün auf Den Hintergrund an |
| 43 | Hintergrund gelb | Wendet nicht fett/hellgelb auf den Hintergrund an |
| 44 | Hintergrundblau | Wendet nicht fett/hellblau auf Den Hintergrund an |
| 45 | Hintergrund Magenta | Wendet nicht fett/hell magenta auf Den Hintergrund an |
| 46 | Hintergrund Cyan | Wendet nicht fett/hell zyan auf Hintergrund an |
| 47 | Hintergrund weiß | Wendet nicht fett/hellweiß auf Den Hintergrund an |
| 48 | Erweiterter Hintergrund | Wendet den erweiterten Farbwert auf den Hintergrund an (siehe Details unten) |
| 49 | Hintergrundstandard | Wendet nur den Hintergrundteil der Standardwerte an (siehe 0) |
| 90 | Heller Vordergrund schwarz | Wendet fett/hell schwarz im Vordergrund an |
| 91 | Helles Vordergrundrot | Wendet fett/hellrot im Vordergrund an |
| 92 | Helles Vordergrundgrün | Wendet fett/hellgrün im Vordergrund an |
| 93 | Helles Vordergrundgelb | Wendet fett/hellgelb im Vordergrund an |
| 94 | Helles Vordergrundblau | Wendet fett/hellblau im Vordergrund an |
| 95 | Helles Vordergrund-Magenta | Wendet fett/hell magenta im Vordergrund an |
| 96 | Heller Vordergrund Zyan | Wendet fett/hell zyan im Vordergrund an |
| 97 | Helles Vordergrundweiß | Wendet fett/hellweiß im Vordergrund an |
| 100 | Heller Hintergrund Schwarz | Wendet fett/hell schwarz auf den Hintergrund an |
| 101 | Helles Hintergrundrot | Wendet fett/hellrot auf den Hintergrund an |
| 102 | Helles Hintergrundgrün | Wendet fett/hellgrün auf Den Hintergrund an |
| 103 | Helles Hintergrundgelb | Wendet fett/hellgelb auf den Hintergrund an |
| 104 | Helles Hintergrundblau | Wendet fett/hellblau auf Den Hintergrund an |
| 105 | Helles Hintergrund-Magenta | Wendet fett/hell magenta auf den Hintergrund an |
| 106 | Helles Hintergrund cyan | Wendet fett/hell zyan auf Den Hintergrund an |
| 107 | Helles Hintergrundweiß | Wendet fett/hellweiß auf Den Hintergrund an |
Erweiterte Farben
Einige virtuelle Terminalemulatoren unterstützen eine Palette von Farben, die größer als die von der Windows-Konsole bereitgestellten 16 Farben sind. Bei diesen erweiterten Farben wählt die Windows-Konsole die nächste geeignete Farbe aus der vorhandenen 16 Farbtabelle für die Anzeige aus. Im Gegensatz zu typischen SGR-Werten oben verbrauchen die erweiterten Werte zusätzliche Parameter nach dem anfänglichen Indikator gemäß der folgenden Tabelle.
| SGR-Untersequence | BESCHREIBUNG |
|---|---|
| 38 ; 2 ; <r> ; <g> ; <b> | Vordergrundfarbe auf RGB-Wert festlegen, der in <r>, <g>, <b> parameter* angegeben ist |
| 48 ; 2 ; <r> ; <g> ; <b> | Festlegen der Hintergrundfarbe auf RGB-Wert, der in <r>, <g>, <b> parameter* angegeben ist |
| 38 ; 5 ; <s> | Festlegen der Vordergrundfarbe auf <den> Index in der 88- oder 256-Farbtabelle* |
| 48 ; 5 ; <s> | Festlegen der Hintergrundfarbe auf <den> Index in der 88- oder 256-Farbtabelle* |
*Die 88- und 256 Farbpaletten, die intern für den Vergleich verwaltet werden, basieren auf dem xterm-Terminal-Emulator. Die Vergleichs-/Rundungstabellen können zurzeit nicht geändert werden.
Bildschirmfarben
Mit dem folgenden Befehl kann die Anwendung die Farbpalettenwerte des Bildschirms auf einen beliebigen RGB-Wert festlegen.
Die RGB-Werte sollten hexadezimale Werte zwischen 0 und ff, und durch das Schrägstrichzeichen (z. B. rgb:1/24/86) getrennt sein.
Beachten Sie, dass es sich bei dieser Sequenz um eine OSC-Sequenz "Betriebssystembefehl" und nicht um eine CSI handelt, wie viele der anderen aufgeführten Sequenzen, und als solche mit "\x1b]" beginnen, nicht "\x1b[". Als OSC-Sequenzen werden sie mit ESC \ einem Zeichenfolgenterminator beendet, der als <ST> (0x1B 0x5C) dargestellt und übertragen wird.
BEL (0x7) kann stattdessen als Terminator verwendet werden, aber das längere Formular wird bevorzugt.
| Reihenfolge | BESCHREIBUNG | Verhalten |
|---|---|---|
| ESC ] 4 ; <i> ; rgb : <r> / <g> / <b><ST> | Ändern von Bildschirmfarben | Legt den Index der Bildschirmfarbpalette <i> auf die RGB-Werte fest, die in <r>, <g>, <b angegeben sind.> |
Modusänderungen
Dies sind Sequenzen, die die Eingabemodi steuern. Es gibt zwei verschiedene Eingabemodi, den Cursortastenmodus und den Tastenkombinationsmodus. Der Cursortastenmodus steuert die Sequenzen, die von den Pfeiltasten sowie von start und ende ausgegeben werden, während der Tastensteuerungsmodus die Sequenzen steuert, die von den Tasten auf dem Numpad in erster Linie sowie den Funktionstasten ausgegeben werden.
Jeder dieser Modi ist einfache boolesche Einstellungen – der Cursortastenmodus ist entweder normal (Standard) oder Anwendung, und der Tastenkombinationsmodus ist entweder numerisch (Standard) oder Anwendung.
Weitere Informationen zu den in diesen Modi ausgegebenen Sequenzen finden Sie in den Abschnitten "Cursortasten" und "Numpad & Function Keys".
| Reihenfolge | Programmcode | BESCHREIBUNG | Verhalten |
|---|---|---|---|
| ESC = | DECKPAM | Aktivieren des Tastaturanwendungsmodus | Tastenkombinationen geben ihre Anwendungsmodussequenzen aus. |
| ESC > | DECKPNM | Aktivieren des Zehnertastaturmodus | Tastenkombinationen geben ihre Sequenzen für den numerischen Modus aus. |
| ESC [ ? 1 h | DECCKM | Aktivieren des Anwendungsmodus für Cursortasten | Tastenkombinationen geben ihre Anwendungsmodussequenzen aus. |
| ESC [ ? 1 l | DECCKM | Anwendungsmodus für Cursortasten deaktivieren (Normalmodus verwenden) | Tastenkombinationen geben ihre Sequenzen für den numerischen Modus aus. |
Abfragestatus
Alle Befehle in diesem Abschnitt entsprechen im Allgemeinen dem Aufrufen von Get*-Konsolen-APIs zum Abrufen von Statusinformationen zum aktuellen Konsolenpufferstatus.
Hinweis
Diese Abfragen geben ihre Antworten unmittelbar nach der Erkennung im Ausgabedatenstrom an den Konsoleneingabedatenstrom aus, während ENABLE_VIRTUAL_TERMINAL_PROCESSING festgelegt ist. Das flag ENABLE_VIRTUAL_TERMINAL_INPUT gilt nicht für Abfragebefehle, da davon ausgegangen wird, dass eine Anwendung, die die Abfrage stellt, immer die Antwort empfangen möchte.
| Reihenfolge | Programmcode | BESCHREIBUNG | Verhalten |
|---|---|---|---|
| ESC [ 6 n | DECXCPR | Berichtscursorposition | Emittieren Sie die Cursorposition wie: ESC [ <r> ; <c> R Where <r> = cursor row and <c> = cursor column |
| ESC [ 0 c | DA | Geräteattribute | Melden Sie die Terminalidentität. Wird "\x1b[?1; ausgegeben; 0c", der "VT101 ohne Optionen" angibt. |
Tabulatoren
Während die Windows-Konsole normalerweise erwartet, dass Registerkarten ausschließlich acht Zeichen breit sind, können *nix-Anwendungen, die bestimmte Sequenzen verwenden, bearbeiten, wo sich die Tabstopps in den Konsolenfenstern befinden, um die Cursorbewegung durch die Anwendung zu optimieren.
Mit den folgenden Sequenzen kann eine Anwendung die Tabstopppositionen innerhalb des Konsolenfensters festlegen, entfernen und zwischen diesen navigieren.
| Reihenfolge | Programmcode | BESCHREIBUNG | Verhalten |
|---|---|---|---|
| ESC H | HTS | Horizontaler Tabstoppsatz | Legt einen Tabstopp in der aktuellen Spalte fest, in der sich der Cursor befindet. |
| ESC [ <n> I | CHT | Cursor horizontal (Vorwärts) Tabstopp | Bewegen Sie den Cursor mit einem Tabstopp zur nächsten Spalte (in derselben Zeile). Wenn keine tabstopps mehr vorhanden sind, wechseln Sie zur letzten Spalte in der Zeile. Wenn sich der Cursor in der letzten Spalte befindet, wechseln Sie zur ersten Spalte der nächsten Zeile. |
| ESC [ <n> Z | CBT | Cursor Rückwärtsregisterkarte | Bewegen Sie den Cursor in die vorherige Spalte (in derselben Zeile) mit einem Tabstopp. Wenn keine tabstopps mehr vorhanden sind, wird der Cursor zur ersten Spalte verschoben. Wenn sich der Cursor in der ersten Spalte befindet, wird der Cursor nicht verschoben. |
| ESC [ 0 g | TBC | Tabstopp löschen (aktuelle Spalte) | Löscht den Tabstopp in der aktuellen Spalte, falls vorhanden. Andernfalls geschieht nichts. |
| ESC [ 3 g | TBC | Tabstopp löschen (alle Spalten) | Löscht alle aktuell festgelegten Tabstopps. |
- Für CHT und CBT <ist n> ein optionaler Parameter, der (default=1) angibt, wie oft der Cursor in der angegebenen Richtung vorangestellt werden soll.
- Wenn keine Tabstopps über HTS festgelegt sind, behandelt CHT und CBT die ersten und letzten Spalten des Fensters als die einzigen beiden Tabstopps.
- Die Verwendung von HTS zum Festlegen eines Tabstopps bewirkt auch, dass die Konsole zum nächsten Tabstopp auf der Ausgabe eines TAB-Zeichens (0x09, '\t') auf die gleiche Weise wie CHT navigiert.
Festlegen eines Zeichensatzes
Mit den folgenden Sequenzen kann ein Programm die Zuordnung des aktiven Zeichensatzes ändern. Dadurch kann ein Programm 7-Bit-ASCII-Zeichen ausgeben, aber sie werden als andere Glyphen auf dem Terminalbildschirm selbst angezeigt. Derzeit sind die einzigen beiden unterstützten Zeichensätze ASCII (Standard) und der DEC Special Graphics Character Set. Eine Auflistung aller Zeichen, die durch den DEC-Sonderzeichensatz dargestellt werden, finden Sie unter.See http://vt100.net/docs/vt220-rm/table2-4.html for a listing of all of the characters represented by the DEC Special Graphics Character Set.
| Reihenfolge | BESCHREIBUNG | Verhalten |
|---|---|---|
| ESC ( 0 | Zeichensatz festlegen – DEZ-Linienzeichnung | Aktiviert den DEZ-Linienzeichnungsmodus |
| ESC ( B | Festlegen eines Zeichensatzes – US ASCII | Aktiviert den ASCII-Modus (Standard) |
Insbesondere wird der DEC-Linienzeichnungsmodus für das Zeichnen von Rahmen in Konsolenanwendungen verwendet. In der folgenden Tabelle wird gezeigt, welches ASCII-Zeichen welchem Linienzeichnungszeichen zugeordnet ist.
| Hexe | ASCII | DEZ-Linienzeichnung |
|---|---|---|
| 0x6a | j | ┘ |
| 0x6b | k | ┐ |
| 0x6c | Liter | ┌ |
| 0x6d | m | └ |
| 0x6e | n | ┼ |
| 0x71 | q | ─ |
| 0x74 | t | ├ |
| 0x75 | u | ┤ |
| 0x76 | v | ┴ |
| 0x77 | w | ┬ |
| 0x78 | x | │ |
Bildlaufränder
Mit den folgenden Sequenzen kann ein Programm den "Bildlaufbereich" des Bildschirms konfigurieren, der von Bildlaufvorgängen betroffen ist. Dies ist eine Teilmenge der Zeilen, die angepasst werden, wenn der Bildschirm andernfalls scrollen würde, z. B. auf einem "\n" oder RI. Diese Seitenränder wirken sich auch auf die Zeilen aus, die durch Insert Line (IL) und Delete Line (DL), Scroll Up (SU) und Scroll Down (SD) geändert wurden.
Die Bildlaufränder können besonders nützlich sein, wenn ein Teil des Bildschirms nicht scrollt, wenn der rest des Bildschirms gefüllt ist, z. B. eine Titelleiste oben oder eine Statusleiste am unteren Rand der Anwendung.
Für DECSTBM gibt es zwei optionale Parameter, <t> und <b>, die verwendet werden, um die Zeilen anzugeben, die die oberen und unteren Zeilen des Bildlaufbereichs (einschließlich) darstellen. Wenn die Parameter nicht angegeben werden, <> wird standardmäßig "1" und <"b>" auf die aktuelle Viewporthöhe festgelegt.
Bildlaufränder sind pro Puffer, daher behalten der alternative Puffer und der Hauptpuffer separate Einstellungen für Bildlaufränder bei (daher vergiftet eine Vollbildanwendung im alternativen Puffer die Seitenränder des Hauptpuffers nicht).
| Reihenfolge | Programmcode | BESCHREIBUNG | Verhalten |
|---|---|---|---|
| ESC [ <t> ; <b> r | DECSTBM | Festlegen des Bildlaufbereichs | Legt die VT-Bildlaufränder des Viewports fest. |
Fenstertitel
Mit den folgenden Befehlen kann die Anwendung den Titel des Konsolenfensters auf den angegebenen <Zeichenfolgenparameter> festlegen. Die Zeichenfolge muss kleiner als 255 Zeichen sein, um akzeptiert zu werden. Dies entspricht dem Aufrufen von SetConsoleTitle mit der angegebenen Zeichenfolge.
Beachten Sie, dass es sich bei diesen Sequenzen um OSC-Sequenzen "Betriebssystembefehle" und nicht um eine CSI wie viele der anderen aufgeführten Sequenzen handelt und als solche mit "\x1b]" beginnt, nicht "\x1b[". Als OSC-Sequenzen werden sie mit ESC \ einem Zeichenfolgenterminator beendet, der als <ST> (0x1B 0x5C) dargestellt und übertragen wird.
BEL (0x7) kann stattdessen als Terminator verwendet werden, aber das längere Formular wird bevorzugt.
| Reihenfolge | BESCHREIBUNG | Verhalten |
|---|---|---|
| ESC ] 0 ; <Schnur><ST> | Fenstertitel festlegen | Legt den Titel des Konsolenfensters auf <Zeichenfolge> fest. |
| ESC ] 2 ; <Schnur><ST> | Fenstertitel festlegen | Legt den Titel des Konsolenfensters auf <Zeichenfolge> fest. |
Das endende Zeichen ist hier das Zeichen "Bell", "\x07".
Alternativer Bildschirmpuffer
*Nix-Stilanwendungen verwenden häufig einen alternativen Bildschirmpuffer, sodass sie den gesamten Inhalt des Puffers ändern können, ohne dass sich dies auf die Anwendung auswirkt, die sie gestartet hat. Der alternative Puffer ist genau die Abmessungen des Fensters, ohne einen Bildlaufbereich.
Für ein Beispiel für dieses Verhalten sollten Sie berücksichtigen, wann vim von bash gestartet wird. Vim verwendet die gesamte Bildschirmansicht, um die Datei zu bearbeiten, und dann wird der ursprüngliche Puffer unverändert beibehalten.
| Reihenfolge | BESCHREIBUNG | Verhalten |
|---|---|---|
| ESC [ ? 1 0 4 9 h | Alternativer Bildschirmpuffer verwenden | Wechselt zu einem neuen alternativen Bildschirmpuffer. |
| ESC [ ? 1 0 4 9 l | Hauptbildschirmpuffer verwenden | Wechselt zum Hauptpuffer. |
Fensterbreite
Die folgenden Sequenzen können verwendet werden, um die Breite des Konsolenfensters zu steuern. Sie entsprechen ungefähr dem Aufrufen der SetConsoleScreenBufferInfoEx-Konsolen-API, um die Fensterbreite festzulegen.
| Reihenfolge | Programmcode | BESCHREIBUNG | Verhalten |
|---|---|---|---|
| ESC [ ? 3 h | DECCOLM | Festlegen der Anzahl von Spalten auf 132 | Legt die Konsolenbreite auf 132 Spalten breit fest. |
| ESC [ ? 3 l | DECCOLM | Festlegen der Anzahl von Spalten auf 80 | Legt die Konsolenbreite auf 80 Spalten breit fest. |
Soft Reset
Die folgende Sequenz kann verwendet werden, um bestimmte Eigenschaften auf ihre Standardwerte zurückzusetzen. Die folgenden Eigenschaften werden auf die folgenden Standardwerte zurückgesetzt (auch aufgeführt sind die Sequenzen, die diese Eigenschaften steuern):
- Cursorsicht: sichtbar (DECTEM)
- Zehnertastatur: Numerischer Modus (DECNKM)
- Cursortastenmodus: Normalmodus (DECCKM)
- Obere und untere Seitenränder: Top=1, Bottom=Console height (DECSTBM)
- Zeichensatz: US ASCII
- Grafikdarstellung: Default/Off (SGR)
- Cursorzustand speichern: Startposition (0,0) (DECSC)
| Reihenfolge | Programmcode | BESCHREIBUNG | Verhalten |
|---|---|---|---|
| ESC [ ! p | DECSTR | Soft Reset | Setzen Sie bestimmte Terminaleinstellungen auf ihre Standardeinstellungen zurück. |
Eingabesequenzen
Die folgenden Terminalsequenzen werden vom Konsolenhost im Eingabedatenstrom ausgegeben, wenn das ENABLE_VIRTUAL_TERMINAL_INPUT Flag für den Eingabepufferhandle mithilfe des SetConsoleMode-Flags festgelegt ist.
Es gibt zwei interne Modi, die steuern, welche Sequenzen für die angegebenen Eingabetasten ausgegeben werden, der Cursortastenmodus und der Tastensteuerungsmodus. Diese werden im Abschnitt "Modusänderungen" beschrieben.
Cursortasten
| Schlüssel | Normaler Modus | Anwendungsmodus |
|---|---|---|
| NACH-OBEN-TASTE | ESC [ A | ESC O A |
| NACH-UNTEN-TASTE | ESC [ B | ESC O B |
| NACH-RECHTS-TASTE | ESC [ C | ESC O C |
| NACH-LINKS-TASTE | ESC [ D | ESC O D |
| Heim | ESC [ H | ESC O H |
| ENDE | ESC [ F | ESC O F |
Wenn STRG mit einer dieser Tasten gedrückt wird, werden stattdessen die folgenden Sequenzen unabhängig vom Cursortastenmodus ausgegeben:
| Schlüssel | Beliebiger Modus |
|---|---|
| STRG+NACH-OBEN | ESC [ 1 ; 5 A |
| STRG+NACH-UNTEN | ESC [ 1 ; 5 B |
| STRG+NACH-RECHTS | ESC [ 1 ; 5 C |
| STRG+NACH-LINKS | ESC [ 1 ; 5 D |
Numpad & Funktionstasten
| Schlüssel | Reihenfolge |
|---|---|
| Rücktaste | 0x7f (DEL) |
| Anhalten | 0x1a (SUB) |
| Flucht | 0x1b (ESC) |
| Einfügen | ESC [ 2 ~ |
| Löschen | ESC [ 3 ~ |
| Bild nach oben bewegen | ESC [ 5 ~ |
| Bild ab | ESC [ 6 ~ |
| F1 | ESC O P |
| F2 | ESC O Q |
| F3 | ESC O R |
| F4 | ESC O S |
| F5 | ESC [ 1 5 ~ |
| F6 | ESC [ 1 7 ~ |
| F7 | ESC [ 1 8 ~ |
| F8 | ESC [ 1 9 ~ |
| F9 | ESC [ 2 0 ~ |
| F10 | ESC [ 2 1 ~ |
| F11 | ESC [ 2 3 ~ |
| F12 | ESC [ 2 4 ~ |
Modifizierer
Alt wird behandelt, indem der Sequenz ein Escapezeichen vorangestellt wird: ESC <c> , wobei <c> das vom Betriebssystem übergebene Zeichen ist. ALT+STRG wird auf die gleiche Weise behandelt, mit der Ausnahme, dass das Betriebssystem die <C-TASTE> auf das entsprechende Steuerelementzeichen vorverlagern wird, das an die Anwendung weitergeleitet wird.
Strg wird im Allgemeinen genau wie vom System empfangen durchgestrichen. Dies ist in der Regel ein einzelnes Zeichen, das in das reservierte Leerzeichen des Steuerelementzeichens verschoben wird (0x0-0x1f). Beispielsweise wird STRG+@ (0x40) zu NUL (0x00), STRG+[ (0x5b) wird ESC (0x1b) usw. Einige Strg-Tastenkombinationen werden speziell gemäß der folgenden Tabelle behandelt:
| Schlüssel | Reihenfolge |
|---|---|
| STRG+LEERTASTE | 0x00 (NUL) |
| STRG+NACH-OBEN | ESC [ 1 ; 5 A |
| STRG+NACH-UNTEN | ESC [ 1 ; 5 B |
| STRG+NACH-RECHTS | ESC [ 1 ; 5 C |
| STRG+NACH-LINKS | ESC [ 1 ; 5 D |
Hinweis
STRG+NACH-RECHTS-ALT wird als AltGr behandelt. Wenn beide zusammen gesehen werden, werden sie entfernt, und der Unicode-Wert des vom System präsentierten Zeichens wird an das Ziel übergeben. Das System übersetzt AltGr-Werte entsprechend den aktuellen Systemeingabeeinstellungen vor.
Proben
Beispiel für SGR-Terminalsequenzen
Der folgende Code enthält mehrere Beispiele für die Textformatierung.
#include <stdio.h>
#include <wchar.h>
#include <windows.h>
int main()
{
// Set output mode to handle virtual terminal sequences
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE)
{
return GetLastError();
}
DWORD dwMode = 0;
if (!GetConsoleMode(hOut, &dwMode))
{
return GetLastError();
}
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(hOut, dwMode))
{
return GetLastError();
}
// Try some Set Graphics Rendition (SGR) terminal escape sequences
wprintf(L"\x1b[31mThis text has a red foreground using SGR.31.\r\n");
wprintf(L"\x1b[1mThis text has a bright (bold) red foreground using SGR.1 to affect the previous color setting.\r\n");
wprintf(L"\x1b[mThis text has returned to default colors using SGR.0 implicitly.\r\n");
wprintf(L"\x1b[34;46mThis text shows the foreground and background change at the same time.\r\n");
wprintf(L"\x1b[0mThis text has returned to default colors using SGR.0 explicitly.\r\n");
wprintf(L"\x1b[31;32;33;34;35;36;101;102;103;104;105;106;107mThis text attempts to apply many colors in the same command. Note the colors are applied from left to right so only the right-most option of foreground cyan (SGR.36) and background bright white (SGR.107) is effective.\r\n");
wprintf(L"\x1b[39mThis text has restored the foreground color only.\r\n");
wprintf(L"\x1b[49mThis text has restored the background color only.\r\n");
return 0;
}
Hinweis
Im vorherigen Beispiel ist die Zeichenfolge '\x1b[31m' die Implementierung von ESC [ <n> m , wobei <n> 31 ist.
Die folgende Grafik zeigt die Ausgabe des vorherigen Codebeispiels.
Beispiel für die Aktivierung der virtuellen Terminalverarbeitung
Der folgende Code enthält ein Beispiel für die empfohlene Methode zum Aktivieren der virtuellen Terminalverarbeitung für eine Anwendung. Die Absicht des Beispiels besteht darin, folgendes zu veranschaulichen:
Der vorhandene Modus sollte immer über GetConsoleMode abgerufen und analysiert werden, bevor er mit SetConsoleMode festgelegt wird.
Überprüfen, ob SetConsoleMode zurückgibt
0und GetLastError ERROR_INVALID_PARAMETER ist der aktuelle Mechanismus, der bestimmt, wann auf einem system down-Level ausgeführt wird. Eine Anwendung, die ERROR_INVALID_PARAMETER mit einer der neueren Konsolenmoduskennzeichnungen im Bitfeld empfängt, sollte das Verhalten ordnungsgemäß beeinträchtigen und es erneut versuchen.
#include <stdio.h>
#include <wchar.h>
#include <windows.h>
int main()
{
// Set output mode to handle virtual terminal sequences
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE)
{
return false;
}
HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
if (hIn == INVALID_HANDLE_VALUE)
{
return false;
}
DWORD dwOriginalOutMode = 0;
DWORD dwOriginalInMode = 0;
if (!GetConsoleMode(hOut, &dwOriginalOutMode))
{
return false;
}
if (!GetConsoleMode(hIn, &dwOriginalInMode))
{
return false;
}
DWORD dwRequestedOutModes = ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN;
DWORD dwRequestedInModes = ENABLE_VIRTUAL_TERMINAL_INPUT;
DWORD dwOutMode = dwOriginalOutMode | dwRequestedOutModes;
if (!SetConsoleMode(hOut, dwOutMode))
{
// we failed to set both modes, try to step down mode gracefully.
dwRequestedOutModes = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
dwOutMode = dwOriginalOutMode | dwRequestedOutModes;
if (!SetConsoleMode(hOut, dwOutMode))
{
// Failed to set any VT mode, can't do anything here.
return -1;
}
}
DWORD dwInMode = dwOriginalInMode | dwRequestedInModes;
if (!SetConsoleMode(hIn, dwInMode))
{
// Failed to set VT input mode, can't do anything here.
return -1;
}
return 0;
}
Beispiel für "Anniversary Update-Features auswählen"
Das folgende Beispiel soll ein robusteres Beispiel für Code sein, der eine Vielzahl von Escapesequenzen verwendet, um den Puffer zu bearbeiten, wobei die im Anniversary Update für Windows 10 hinzugefügten Features hervorgehoben werden.
In diesem Beispiel wird der alternative Bildschirmpuffer verwendet, Tabstopps geändert, Bildlaufränder festgelegt und der Zeichensatz geändert.
// System headers
#include <windows.h>
// Standard library C-style
#include <wchar.h>
#include <stdlib.h>
#include <stdio.h>
#define ESC "\x1b"
#define CSI "\x1b["
bool EnableVTMode()
{
// Set output mode to handle virtual terminal sequences
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE)
{
return false;
}
DWORD dwMode = 0;
if (!GetConsoleMode(hOut, &dwMode))
{
return false;
}
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(hOut, dwMode))
{
return false;
}
return true;
}
void PrintVerticalBorder()
{
printf(ESC "(0"); // Enter Line drawing mode
printf(CSI "104;93m"); // bright yellow on bright blue
printf("x"); // in line drawing mode, \x78 -> \u2502 "Vertical Bar"
printf(CSI "0m"); // restore color
printf(ESC "(B"); // exit line drawing mode
}
void PrintHorizontalBorder(COORD const Size, bool fIsTop)
{
printf(ESC "(0"); // Enter Line drawing mode
printf(CSI "104;93m"); // Make the border bright yellow on bright blue
printf(fIsTop ? "l" : "m"); // print left corner
for (int i = 1; i < Size.X - 1; i++)
printf("q"); // in line drawing mode, \x71 -> \u2500 "HORIZONTAL SCAN LINE-5"
printf(fIsTop ? "k" : "j"); // print right corner
printf(CSI "0m");
printf(ESC "(B"); // exit line drawing mode
}
void PrintStatusLine(const char* const pszMessage, COORD const Size)
{
printf(CSI "%d;1H", Size.Y);
printf(CSI "K"); // clear the line
printf(pszMessage);
}
int __cdecl wmain(int argc, WCHAR* argv[])
{
argc; // unused
argv; // unused
//First, enable VT mode
bool fSuccess = EnableVTMode();
if (!fSuccess)
{
printf("Unable to enter VT processing mode. Quitting.\n");
return -1;
}
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE)
{
printf("Couldn't get the console handle. Quitting.\n");
return -1;
}
CONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo;
GetConsoleScreenBufferInfo(hOut, &ScreenBufferInfo);
COORD Size;
Size.X = ScreenBufferInfo.srWindow.Right - ScreenBufferInfo.srWindow.Left + 1;
Size.Y = ScreenBufferInfo.srWindow.Bottom - ScreenBufferInfo.srWindow.Top + 1;
// Enter the alternate buffer
printf(CSI "?1049h");
// Clear screen, tab stops, set, stop at columns 16, 32
printf(CSI "1;1H");
printf(CSI "2J"); // Clear screen
int iNumTabStops = 4; // (0, 20, 40, width)
printf(CSI "3g"); // clear all tab stops
printf(CSI "1;20H"); // Move to column 20
printf(ESC "H"); // set a tab stop
printf(CSI "1;40H"); // Move to column 40
printf(ESC "H"); // set a tab stop
// Set scrolling margins to 3, h-2
printf(CSI "3;%dr", Size.Y - 2);
int iNumLines = Size.Y - 4;
printf(CSI "1;1H");
printf(CSI "102;30m");
printf("Windows 10 Anniversary Update - VT Example");
printf(CSI "0m");
// Print a top border - Yellow
printf(CSI "2;1H");
PrintHorizontalBorder(Size, true);
// // Print a bottom border
printf(CSI "%d;1H", Size.Y - 1);
PrintHorizontalBorder(Size, false);
wchar_t wch;
// draw columns
printf(CSI "3;1H");
int line = 0;
for (line = 0; line < iNumLines * iNumTabStops; line++)
{
PrintVerticalBorder();
if (line + 1 != iNumLines * iNumTabStops) // don't advance to next line if this is the last line
printf("\t"); // advance to next tab stop
}
PrintStatusLine("Press any key to see text printed between tab stops.", Size);
wch = _getwch();
// Fill columns with output
printf(CSI "3;1H");
for (line = 0; line < iNumLines; line++)
{
int tab = 0;
for (tab = 0; tab < iNumTabStops - 1; tab++)
{
PrintVerticalBorder();
printf("line=%d", line);
printf("\t"); // advance to next tab stop
}
PrintVerticalBorder();// print border at right side
if (line + 1 != iNumLines)
printf("\t"); // advance to next tab stop, (on the next line)
}
PrintStatusLine("Press any key to demonstrate scroll margins", Size);
wch = _getwch();
printf(CSI "3;1H");
for (line = 0; line < iNumLines * 2; line++)
{
printf(CSI "K"); // clear the line
int tab = 0;
for (tab = 0; tab < iNumTabStops - 1; tab++)
{
PrintVerticalBorder();
printf("line=%d", line);
printf("\t"); // advance to next tab stop
}
PrintVerticalBorder(); // print border at right side
if (line + 1 != iNumLines * 2)
{
printf("\n"); //Advance to next line. If we're at the bottom of the margins, the text will scroll.
printf("\r"); //return to first col in buffer
}
}
PrintStatusLine("Press any key to exit", Size);
wch = _getwch();
// Exit the alternate buffer
printf(CSI "?1049l");
}