コンソールの仮想ターミナル シーケンス

仮想ターミナル シーケンスは、出力ストリームに書き込まれることでカーソルの移動、コンソールの色、その他の操作を制御できる制御文字シーケンスです。 出力ストリームのクエリ情報シーケンスへの応答で、または適切なモードが設定されているときのユーザー入力のエンコードとして、入力ストリームでシーケンスを受け取ることもできます。

GetConsoleMode および SetConsoleMode 関数を使用して、この動作を構成できます。 仮想ターミナルの動作を有効にするための推奨される方法のサンプルは、このドキュメントの最後に記載されています。

以下のシーケンスの動作は、VT100 および派生ターミナル エミュレーター テクノロジ (具体的には xterm ターミナル エミュレーター) に基づいています。 ターミナル シーケンスの詳細については、http://vt100.net および http://invisible-island.net/xterm/ctlseqs/ctlseqs.html を参照してください。

出力シーケンス

SetConsoleMode 関数を使用してスクリーン バッファー ハンドルで ENABLE_VIRTUAL_TERMINAL_PROCESSING フラグが設定されている場合、次のターミナル シーケンスは、出力ストリームに書き込まれるとコンソール ホストによってインターセプトされます。 行の最後の列に書き込まれた文字に関連して、他のターミナル エミュレーターのカーソルの配置とスクロールの動作をエミュレートする場合に、DISABLE_NEWLINE_AUTO_RETURN フラグも役に立つ場合があることに注意してください。

カーソルの簡単な配置

以下のすべての説明において、ESC は常に 16 進数値 0x1B です。 ターミナル シーケンスにスペースを含めることはできません。 個々のターミナル シーケンスは、WriteFile または WriteConsole への複数のシーケンシャル呼び出しで任意の文字またはバイト位置で切り離せますが、シーケンス全体を 1 回の呼び出しに含めるのがベストプラクティスです。 これらのシーケンスを実際に使用する方法の例については、このトピックの最後にあるを参照してください。

次の表では、ESC 文字の直後に単一のアクション コマンドがある簡単なエスケープ シーケンスについて説明します。 これらのシーケンスにはパラメーターはなく、すぐに有効になります。

このテーブルのすべてのコマンドは、一般に、SetConsoleCursorPosition コンソール API を呼び出してカーソルを配置することと同じです。

カーソルの移動は、バッファーに対する現在のビューポートによって制限されます。 スクロール (可能な場合) は発生しません。

シークエンス 短縮形 Behavior
ESC M 予約インスタンス インデックスの反転 \n の逆の操作を実行して、カーソルを 1 行上に移動し、水平位置を維持し、必要に応じてバッファーをスクロールします*
ESC 7 DECSC カーソル位置をメモリに保存します**
ESC 8 DECSR カーソル位置をメモリから復元します**

Note

* スクロール マージンが設定されている場合、マージン内の RI ではマージンの内容のみがスクロールされ、ビューポートは変更されません。 (「スクロール マージン」を参照)

** 保存コマンドが初めて使用されるまで、値はメモリに保存されません。 保存されている値にアクセスする唯一の方法は、復元コマンドを使用することです。

カーソルの配置

次の表では、Control Sequence Introducer (CSI) タイプのシーケンスを示します。 すべての CSI シーケンスは、ESC (0x1B) の後の [ (左角かっこ、0x5B) で開始し、各操作の詳細を指定するために可変長のパラメーターを含むことができます。 これは、短縮形 <n> によって表されます。 以下の各表は機能でグループ化されており、各表の下のメモでグループ化の方法が説明されています。

すべてのパラメーターについて、特に断りのない限り、次の規則が適用されます。

  • <n> は、移動する量を表し、省略可能なパラメーターです
  • <n> がない場合、または 0 に等しい場合は、1 として扱われます
  • <n> は、32767 (最大の short 値) より大きくすることはできません
  • <n> を負の値にすることはできません

このセクションのすべてのコマンドは、一般に、SetConsoleCursorPosition コンソール API を呼び出すことと同じです。

カーソルの移動は、バッファーに対する現在のビューポートによって制限されます。 スクロール (可能な場合) は発生しません。

シークエンス コード 説明 Behavior
ESC [ <n> A CUU カーソルを上に移動 カーソルを <n> だけ上に移動します
ESC [ <n> B CUD カーソルを下に移動 カーソルを <n> だけ下に移動します
ESC [ <n> C CUF カーソルを前方に移動 カーソルを <n> だけ前方 (右) に移動します
ESC [ <n> D CUB カーソルを後方に移動 カーソルを <n> だけ後方 (左) に移動します
ESC [ <n> E CNL カーソルの次の行に移動 カーソルを現在位置から <n> 行だけ下に移動します
ESC [ <n> F CPL カーソルを前の行に移動 カーソルを現在位置から <n> 行だけ上に移動します
ESC [ <n> G CHA カーソルを水平方向の絶対位置に移動 カーソルを現在の行の <n> 番目の位置に横に移動します
ESC [ <n> d VPA 垂直方向の絶対的な行位置に移動 カーソルを現在の列の <n> 番目の位置に縦に移動します
ESC [ <y> ; <x> H CUP カーソル位置 * カーソルをビューポート内の座標 <x>; <y> に移動します。<x> は <y> 行目の列です
ESC [ <y> ; <x> f HVP 水平方向の垂直位置 * カーソルをビューポート内の座標 <x>; <y> に移動します。<x> は <y> 行目の列です
ESC [ s ANSISYSSC カーソルの保存 – Ansi.sys のエミュレーション ** パラメーターがないと、DECSC のようなカーソル保存操作が実行されます
ESC [ u ANSISYSRC カーソルの復元 – Ansi.sys のエミュレーション ** パラメーターが省略されると、DECRC のようなカーソル復元操作が実行されます

Note

*<x> and <y> パラメーターには、上記の <n> と同様の制限があります。 <x> と <y> が省略された場合は、1;1 に設定されます。

** ANSI.sys の過去のドキュメントは https://msdn.microsoft.com/library/cc722862.aspx にあり、便宜と互換性のために実装されています。

カーソルの可視性

次のコマンドでは、カーソルの可視性と点滅状態が制御されます。 通常、DECTCEM シーケンスは、SetConsoleCursorInfo コンソール API を呼び出してカーソルの可視性を切り替えることと同じです。

シークエンス コード 説明 Behavior
ESC [ ? 12 時間 ATT160 テキスト カーソルの点滅の有効化 カーソルの点滅を開始します
ESC [ ? 12 l ATT160 テキスト カーソルの点滅の無効化 カーソルの点滅を停止します
ESC [ ? 25 h DECTCEM テキスト カーソル有効化モード表示 カーソルを表示します
ESC [ ? 25 l DECTCEM テキスト カーソル有効化モード非表示 カーソルを非表示にします

ヒント

有効化シーケンスは小文字の H (h) で終了し、無効化シーケンスは小文字の L (l) で終了します。

カーソル図形

次のコマンドは、カーソルの図形を制御し、カスタマイズできるようにします。

シークエンス コード 説明 Behavior
ESC [ 0 SP q DECSCUSR ユーザー図形 ユーザーによって構成されたデフォルトのカーソル図形
ESC [ 1 SP q DECSCUSR 点滅ブロック 点滅ブロック カーソル図形
ESC [ 2 SP q DECSCUSR 安定ブロック 安定したブロック カーソル図形
ESC [ 3 SP q DECSCUSR 点滅下線 点滅下線カーソル図形
ESC [ 4 SP q DECSCUSR 安定した下線 固定下線カーソル図形
ESC [ 5 SP q DECSCUSR 点滅バー 点滅バー カーソル図形
ESC [ 6 SP q DECSCUSR 安定バー 固定バー カーソル図形

Note

SP は中間位置のリテラル空白文字 (0x20) であり、その後に最後の位置に q (0x71) が続きます 。

ビューポートの配置

このセクションのすべてのコマンドは、一般に、ScrollConsoleScreenBuffer コンソール API を呼び出してコンソール バッファーの内容を移動することと同じです。

注意 コマンド名は誤解を招きます。 スクロールは、操作の間にテキストが移動する方向を指すもので、ビューポートが移動するように見える向きではありません。

シークエンス コード 説明 Behavior
ESC [ <n> S SU 上にスクロール テキストを <n> だけ上にスクロールします。 パン ダウンとも呼ばれ、新しい行が画面の下部から入ってきます
ESC [ <n> T SD 下にスクロール <n> だけ下にスクロールします。 パン アップとも呼ばれ、新しい行が画面の上部から入ってきます

テキストの移動は、カーソルがある行から開始します。 カーソルがビューポートの中央の行にある場合、上にスクロールすると、ビューポートの下半分が移動し、一番下に空白行が挿入されます。 下にスクロールすると、ビューポートの上半分の行が移動し、一番上に新しい行が挿入されます。

また、上下へのスクロールはスクロール マージンの影響を受けることにも注意することが重要。 上下にスクロールしても、スクロール マージンの外側の行には影響しません。

<n> の既定値は 1 であり、必要に応じて値を省略できます。

テキストの変更

このセクションのすべてのコマンドは、一般に、FillConsoleOutputCharacterFillconsoleoutputcharacterScrollConsoleScreenBuffer コンソール API を呼び出して、テキスト バッファーの内容を変更することと同じです。

シークエンス コード 説明 Behavior
ESC [ <n> @ ICH 文字の挿入 現在のカーソル位置に <n> 個の空白文字を挿入し、既存のすべてのテキストを右にシフトします。 画面から右に出て行ったテキストは削除されます。
ESC [ <n> P DCH 文字の削除 現在のカーソル位置で <n> 個の文字を削除し、画面の右端から空白文字をシフトします。
ESC [ <n> X ECH 文字の消去 現在のカーソル位置から <n> 個の文字を消去し、空白文字で上書きします。
ESC [ <n> L IL 線の挿入 カーソル位置のバッファーに <n> 行を挿入します。 カーソルがある行とそれより下の行が、下方にシフトされます。
ESC [ <n> M DL [行の削除] カーソルがある行を開始位置として、バッファーから <n> 行を削除します。

Note

IL と DL の場合、スクロール マージン内の行 (「スクロール マージン」を参照) だけが影響を受けます。 マージンが設定されていない場合、既定のマージン境界は現在のビューポートになります。 マージンより下にシフトされた行は破棄されます。 行が削除されると、マージンの下部に空白行が挿入され、ビューポートの外側の行は影響を受けません。

どのシーケンスでも、<n> を省略した場合の既定値は 0 です。

次のコマンドについては、パラメーター <n> に有効な値が 3 つあります。

  • 0 は、現在のカーソル位置 (その位置を含む) から、行または表示の最後までを消去します
  • 1 は、行または表示の先頭から、現在のカーソル位置 (その位置を含む) までを消去します
  • 2 は、行または表示全体を消去します
シークエンス コード 説明 Behavior
ESC [ <n> J ED 表示で消去 <n> で指定されている現在のビューポートまたは画面のすべてのテキストを、空白文字に置き換えます
ESC [ <n> K EL 行で消去 <n> によって指定されているカーソル行のすべてのテキストを、空白文字に置き換えます

テキストの書式設定

このセクションのすべてのコマンドは、一般に、SetConsoleTextAttribute コンソール API を呼び出して、コンソール出力テキスト バッファーに対するそれ以降のすべての書き込みの書式設定を調整することと同じです。

このコマンドは、以下の <n> の位置で、セミコロンで区切った 0 から 16 個のパラメーターを指定できる点が特別です。

パラメーターが指定されていない場合は、1 つの 0 パラメーターとして扱われます。

シークエンス コード 説明 Behavior
ESC [ <n> m SGR グラフィックス表示の設定 画面とテキストの書式を、<n> で指定されているように設定します

次の表の値を <n> で使用して、さまざまな書式設定モードを表すことができます。

書式設定モードは左から右に適用されます。 競合する書式設定オプションを適用すると、右端のオプションが優先されます。

色を指定するオプションの場合、コンソールのカラー テーブルで定義されている色が使用されます。これは、SetConsoleScreenBufferInfoEx API を使用して変更できます。 テーブル内の "青" の位置で赤の RGB 網掛けを表示するようにテーブルが変更された場合は、他の設定に変更されるまで、前景青のすべての呼び出しで赤い色が表示されます。

Value 説明 Behavior
0 既定値 すべての属性を変更前の既定の状態に戻します
1 ボールド/明 明度と彩度のフラグを前景色に適用します
22 ボールドなし/明 明度と彩度のフラグを前景色から削除します
4 下線 下線を追加します
24 下線なし 下線を削除します
7 否定的 前景色と背景色を入れ替えます
27 正 (非負) 前景色と背景値を標準に戻します
30 前景黒 非ボールドの明るい黒を前景に適用します
31 前景赤 非ボールドの明るい赤を前景に適用します
32 前景緑 非ボールドの明るい緑を前景に適用します
33 前景黄 非ボールドの明るい黄を前景に適用します
34 前景青 非ボールドの明るい青を前景に適用します
35 前景マゼンタ 非ボールドの明るいマゼンタを前景に適用します
36 前景シアン 非ボールドの明るいシアンを前景に適用します
37 前景白 非ボールドの明るい白を前景に適用します
38 前景拡張 前景に拡張色の値を適用します (後の詳細を参照)
39 前景既定値 既定値の前景部分のみを適用します (0 を参照)
40 背景黒 非ボールドの明るい黒を背景に適用します
41 背景赤 非ボールドの明るい赤を背景に適用します
42 背景緑 非ボールドの明るい緑を背景に適用します
43 背景黄 非ボールドの明るい黄を背景に適用します
44 背景青 非ボールドの明るい青を背景に適用します
45 背景マゼンタ 非ボールドの明るいマゼンタを背景に適用します
46 背景シアン 非ボールドの明るいシアンを背景に適用します
47 背景白 非ボールドの明るい白を背景に適用します
48 背景拡張 背景に拡張色の値を適用します (後の詳細を参照)
49 背景既定値 既定値の背景部分のみを適用します (0 を参照)
90 明るい前景黒 ボールドの明るい黒を前景に適用します
91 明るい前景赤 ボールドの明るい赤を前景に適用します
92 明るい前景緑 ボールドの明るい緑を前景に適用します
93 明るい前景黄 ボールドの明るい黄を前景に適用します
94 明るい前景青 ボールドの明るい青を前景に適用します
95 明るい前景マゼンタ ボールドの明るいマゼンタを前景に適用します
96 明るい前景シアン ボールドの明るいシアンを前景に適用します
97 明るい前景白 ボールドの明るい白を前景に適用します
100 明るい背景黒 ボールドの明るい黒を背景に適用します
101 明るい背景赤 ボールドの明るい赤を背景に適用します
102 明るい背景緑 ボールドの明るい緑を背景に適用します
103 明るい背景黄 ボールドの明るい黄を背景に適用します
104 明るい背景青 ボールドの明るい青を背景に適用します
105 明るい背景マゼンタ ボールドの明るいマゼンタを背景に適用します
106 明るい背景シアン ボールドの明るいシアンを背景に適用します
107 明るい背景白 ボールドの明るい白を背景に適用します

拡張色

一部の仮想ターミナル エミュレーターでは、Windows コンソールによって提供される 16 色を超えるカラー パレットがサポートされています。 これらの拡張色を表示するため、Windows コンソールにより、既存の 16 色のテーブルから最も近い適切な色が選択されます。 上記の一般的な SGR 値とは異なり、拡張値の場合は、初期インジケーターの後に次の表に従って追加パラメーターが使用されます。

SGR サブシーケンス 説明
38 ; 2 ; <r> ; <g> ; <b> 前景色を <r>、<g>、<b> パラメーターで指定された RGB 値に設定します*
48 ; 2 ; <r> ; <g> ; <b> 背景色を <r>、<g>、<b> パラメーターで指定された RGB 値に設定します*
38 ; 5 ; <s> 前景色を 88 または 256 カラー テーブルのインデックス <s> に設定します*
48 ; 5 ; <s> 背景色を 88 または 256 カラー テーブルのインデックス <s> に設定します*

*比較のために内部的に保持されている 88 および 256 カラー パレットは、xterm ターミナル エミュレーターに基づいています。 現在、比較および丸めテーブルを変更することはできません。

画面の色

次のコマンドを使用すると、画面カラー パレットの値をアプリケーションで任意の RGB 値に設定できます。

RGB 値は、0 から ff の間の 16 進数値でなければならず、スラッシュ文字で区切る必要があります (例: rgb:1/24/86)。

このシーケンスは、OSC (オペレーティング システム コマンド) シーケンスであり、一覧で示した他の多くのシーケンスのような CSI ではないため、"\x1b[" ではなく "\x1b]" で始まることに注意してください。 OSC シーケンスとして、<ST> として表される "文字列ターミネータ" で終わり、ESC \ (0x1B 0x5C) で送信されます。 BEL (0x7) をターミネータとして代わりに使用できますが、長い形式の方が推奨されます。

シークエンス 説明 Behavior
ESC ] 4 ; <i> ; rgb : <r> / <g> / <b><ST> 画面の色を変更する 画面カラー パレットのインデックス <i> を、<r>, <g>, <b> で指定されている RGB 値に設定します

モードの変更

これらは、入力モードを制御するシーケンスです。 入力モードには、カーソル キー モードとキーパッド キー モードの 2 つの異なるセットがあります。 カーソル キー モードを使用すると、方向キーおよび Home と End によって出力されるシーケンスが制御されますが、キーパッド キー モードを使用すると、主にテンキーのキーおよびファンクション キーによって出力されるシーケンスが制御されます。

これらの各モードは単純なブール値の設定です。カーソル キー モードは、標準 (既定値) またはアプリケーションのいずれかであり、キーパッド キー モードは数値 (既定) またはアプリケーションのいずれかです。

これらのモードで出力されるシーケンスについては、「カーソル キー」および「テンキーとファンクション キー」のセクションを参照してください。

シークエンス コード 説明 Behavior
ESC = DECKPAM キーパッド アプリケーション モードを有効にする キーパッドのキーによって、アプリケーション モードのシーケンスが出力されます。
ESC > DECKPNM キーパッド数値モードを有効にする キーパッドのキーによって、数値モードのシーケンスが出力されます。
ESC [ ? 1 時間 DECCKM カーソル キー アプリケーション モードを有効にする キーパッドのキーによって、アプリケーション モードのシーケンスが出力されます。
ESC [ ? 1 l DECCKM カーソル キー アプリケーション モードを無効にする (標準モードを使用する) キーパッドのキーによって、数値モードのシーケンスが出力されます。

クエリの状態

このセクションのすべてのコマンドは、一般に、Get* コンソール API を呼び出して、現在のコンソール バッファーの状態に関する状態情報を取得することと同じです。

Note

ENABLE_VIRTUAL_TERMINAL_PROCESSING が設定されている間は、これらのクエリにより、出力ストリームで認識された直後に、応答がコンソール入力ストリームに出力されます。 ENABLE_VIRTUAL_TERMINAL_INPUT フラグは、クエリを行っているアプリケーションでは常に応答の受信が要求されていると想定されるため、クエリ コマンドには適用されません。

シークエンス コード 説明 Behavior
ESC [ 6 n DECXCPR カーソルの位置を報告する カーソルの位置を「ESC [ <r> ; <c> R (<r> = カーソルの行、<c> = カーソルの列)」のように出力します
ESC [ 0 c DA デバイスの属性 ターミナル ID を報告します。 "\x1b[?1;0c" を出力し、"VT101 でオプションなし" を示します。

タブ

従来の Windows コンソールではタブは 8 文字幅だけと想定されていますが、特定のシーケンスを使用する *nix アプリケーションの場合は、コンソール ウィンドウ内でタブ ストップの場所を操作し、アプリケーションでカーソルの動きを最適化できます。

次のシーケンスを使用すると、アプリケーションで、コンソールウィンドウ内でのタブ ストップ位置の設定、それらの削除、それらの間の移動を行うことができます。

シークエンス コード 説明 Behavior
ESC H HTS 水平タブ設定 カーソルが現在ある列のタブ ストップを設定します。
ESC [ <n> I CHT カーソル水平 (前方) タブ タブ ストップを使用して、カーソルを (同じ行の) 次の列に進めます。 タブ ストップがそれ以上ない場合は、行の最後の列に移動します。 カーソルが最後の列にある場合は、次の行の最初の列に移動します。
ESC [ <n> Z CBT カーソル後方タブ タブ ストップを使用して、カーソルを (同じ行の) 前の列に移動します。 タブ ストップがそれ以上ない場合は、カーソルを最初の列に移動します。 カーソルが最初の列にある場合、カーソルを移動しません。
ESC [ 0 g 未定 タブ クリア (現在の列) 現在の列にタブ ストップがある場合は、それをクリアします。 それ以外の場合は、何も行いません。
ESC [ 3 g 未定 タブ クリア (すべての列) 現在設定されているすべてのタブ ストップをクリアします。
  • CHT と CBT のどちらでも、<n> は省略可能なパラメーターであり、指定した方向にカーソルを進める回数を示します(既定値 = 1)。
  • HTS によって設定されたタブ ストップが存在しない場合は、CHT と CBT により、ウィンドウの最初と最後の列が、ただ 2 つのタブ ストップとして扱われます。
  • HTS を使用してタブ ストップを設定しても、CHT と同じように、コンソールは、TAB (0x09, "\t") 文字の出力で、次のタブ位置に移動します。

文字セットの指定

次のシーケンスを使用すると、アクティブな文字セットのマッピングをプログラムで変更できます。 これにより、プログラムでは 7 ビットの ASCII 文字を出力しながら、ターミナル画面自体には他のグリフとして表示することができます。 現在は、ASCII (既定値) と DEC 特殊グラフィックス文字セットの 2 つの文字セットのみがサポートされています。 DEC 特殊グラフィックス文字セットによって表されるすべての文字の一覧については、http://vt100.net/docs/vt220-rm/table2-4.html を参照してください。

シークエンス 説明 Behavior
ESC ( 0 文字セットの指定 - DEC 線描画 DEC の線描画モードを有効にします
ESC ( B 文字セットの指定 – US ASCII ASCII モードを有効にします (既定)

特に、DEC 線描画モードは、コンソール アプリケーションで境界線を描画するために使用されます。 次の表では、ASCII 文字と線描画文字の対応を示します。

Hex ASCII DEC の線描画
0x6a j
0x6b k
0x6c l
0x6d m
0x6e n
0x71 q
0x74 t
0x75 u
0x76 v
0x77 w
0x78 x

スクロール マージン

次のシーケンスを使用すると、スクロール操作の影響を受ける画面の "スクロール領域" をプログラムで構成できます。 これは、たとえば "\n" や RI などでスクリーンがスクロールするときに調整される行のサブセットです。 これらのマージンは、行の挿入 (IL)、行の削除 (DL)、スクロール アップ (SU)、スクロール ダウン (SD) によって変更される行にも影響します。

スクロール マージンは、画面の残りの部分がいっぱいになったときでもスクロールしない部分を画面に作成する場合に特に便利です。たとえば、アプリケーションの上部のタイトル バーや、下部のステータス バーなどです。

DECSTBM には、2 つの省略可能なパラメーター <t> と <b> があります。これらは、スクロール領域の上端と下端が含まれる行を指定するために使用されます (その行を含みます)。 パラメーターを省略した場合、<t> の既定値は 1、<b> の既定値は現在のビューポートの高さになります。

スクロール マージンはバッファー単位です。したがって、重要なこととして、代替バッファーとメイン バッファーは個別にスクロール マージンの設定を保持します (したがって、代替バッファーの全画面アプリケーションが、メイン バッファーのマージンに悪影響を及ぼすことはありません)。

シークエンス コード 説明 Behavior
ESC [ <t> ; <b> r DECSTBM スクロール領域の設定 ビューポートの VT スクロール マージンを設定します。

ウィンドウ タイトル

次のコマンドを使用すると、アプリケーションでコンソール ウィンドウのタイトルを指定した <string> パラメーターに設定できます。 文字列が許容されるには、255 文字未満にする必要があります。 これは、文字列を指定して SetConsoleTitle を呼び出すことと同じです。

これらのシーケンスは、OSC (オペレーティング システム コマンド) シーケンスであり、一覧で示した他の多くのシーケンスのような CSI ではないため、"\x1b]" ではなく "\x1b[" で始まることに注意してください。 OSC シーケンスとして、<ST> として表される "文字列ターミネータ" で終わり、ESC \ (0x1B 0x5C) で送信されます。 BEL (0x7) をターミネータとして代わりに使用できますが、長い形式の方が推奨されます。

シークエンス 説明 Behavior
ESC ] 0 ; <string><ST> ウィンドウ タイトルの設定 コンソール ウィンドウのタイトルを <string> に設定します。
ESC ] 2 ; <string><ST> ウィンドウ タイトルの設定 コンソール ウィンドウのタイトルを <string> に設定します。

ここでの終端文字は、"Bell" 文字 "\x07" です

代替画面バッファー

*Nix スタイルのアプリケーションでは、多くの場合、代替スクリーン バッファーを使用して、それらを開始したアプリケーションに影響を与えずに、バッファーの内容全体を変更することができます。 代替バッファーはウィンドウとまったく同じ大きさであり、スクロール可能領域はありません。

この動作の例として、bash から vim を起動する場合を考えます。 vim により画面全体を使用してファイルの編集が行われた後、bash に戻ったとき、元のバッファーは変更されずに残っています。

シークエンス 説明 Behavior
ESC [ ? 1 0 4 9 h 代替画面バッファーを使用する 新しい代替画面バッファーに切り替えます。
ESC [ ? 1 0 4 9 l メイン画面バッファーを使用する メイン バッファーに切り替えます。

ウィンドウの幅

次のシーケンスを使用して、コンソール ウィンドウの幅を制御できます。 これらは、SetConsoleScreenBufferInfoEx コンソール API を呼び出してウィンドウの幅を設定することとほぼ同じです。

シークエンス コード 説明 Behavior
ESC [ ? 3 h DECCOLM 列数を 132 に設定する コンソールの幅を 132 列幅に設定します。
ESC [ ? 3 l DECCOLM 列数を 80 に設定する コンソールの幅を 80 列幅に設定します。

ソフト リセット

次のシーケンスを使用すると、特定のプロパティを既定値にリセットできます。次のプロパティが、次の既定値にリセットされます (それらのプロパティを制御するシーケンスも記載されています)。

  • カーソルの可視性: 表示 (DECTEM)
  • テンキー: 数値モード (DECNKM)
  • カーソル キー モード: 標準モード (DECCKM)
  • 上余白と下余白: 上 = 1、下 = コンソールの高さ (DECSTBM)
  • 文字セット: US ASCII
  • グラフィックス表示: デフォルト/オフ (SGR)
  • カーソルの状態を保存する: ホーム位置 (0,0) (DECSC)
シークエンス コード 説明 Behavior
ESC [ ! P DECSTR ソフト リセット 特定のターミナル設定を既定値にリセットします。

入力シーケンス

SetConsoleMode フラグを使用して入力バッファー ハンドルで ENABLE_VIRTUAL_TERMINAL_INPUT フラグが設定されている場合、入力ストリーム上のコンソール ホストによって、次のターミナル シーケンスが出力されます。

特定の入力キーに対して出力されるシーケンスを制御する内部モードには、カーソル キー モードとキーパッド キー モードの 2 つがあります。 これらについては、「モードの変更」セクションで説明されています。

カーソル キー

キー 標準モード アプリケーション モード
↑ キー ESC [ A ESC O A
↓ キー ESC [ B ESC O B
ESC [ C ESC O C
ESC [ D ESC O D
ホーム ESC [ H ESC O H
末尾 ESC [ F ESC O F

また、これらのキーのいずれかと共に Ctrl キーが押された場合は、カーソル キー モードに関係なく、次のシーケンスが代わりに出力されます。

キー 任意のモード
Ctrl + ↑ ESC [ 1 ; 5 A
Ctrl + ↓ ESC [ 1 ; 5 B
Ctrl + → ESC [ 1 ; 5 C
Ctrl + ← ESC [ 1 ; 5 D

テンキーとファンクション キー

キー シークエンス
バックスペース 0x7f (DEL)
一時停止 0x1a (SUB)
エスケープ特殊文字 0x1b (ESC)
Insert ESC [ 2 ~
削除 ESC [ 3 ~
Page Up ESC [ 5 ~
Page Down 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 ~

修飾子

Alt は、シーケンスの前にエスケープ ESC <c> を付けることで処理されます。ここで、<c> はオペレーティング システムによって渡される文字です。 Alt + Ctrl も同じように処理されますが、オペレーティング システムによって <c> キーが適切な制御文字に事前にシフトされ、それがアプリケーションに中継される点が異なります。

一般に、Ctrl はシステムから受け取られたとおりに渡されます。 これは、通常、制御文字の予約領域 (0x0 - 0x1f) にシフトされた単一の文字です。 たとえば、Ctrl+@ (0x40) は NUL (0x00)、Ctrl+[ (0x5b) は ESC (0x1b) になります。いくつかの Ctrl キーの組み合わせは、次の表に従って特別に扱われます。

キー シークエンス
Ctrl + Space 0x00 (NUL)
Ctrl + ↑ ESC [ 1 ; 5 A
Ctrl + ↓ ESC [ 1 ; 5 B
Ctrl + → ESC [ 1 ; 5 C
Ctrl + ← ESC [ 1 ; 5 D

Note

Ctrl + 右 Alt は、AltGr として扱われます。 両方が同時に示される場合、それらは除去され、システムによって示された文字の Unicode 値がターゲットに渡されます。 AltGr 値は、システムにより、現在のシステム入力設定に従って事前に変換されます。

サンプル

SGR ターミナル シーケンスの例

次のコードでは、テキストの書式設定の例をいくつか示します。

#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;
}

Note

前の例では、文字列 "\x1b[31m" は ESC <n> m の実装であり、<n> は 31 です。

次の図は、前のコード例の出力を示したものです。

output of the console using the sgr command

仮想ターミナル処理を有効にする例

次のコードは、アプリケーションの仮想ターミナル処理を有効にするための推奨される方法の例を示したものです。 サンプルの目的は、次のことを示すことです。

  1. SetConsoleMode で設定を行う前に、常に、GetConsoleMode を使用して既存のモードを取得し、分析する必要があります。

  2. SetConsoleMode によって 0 が返されるかどうか、および GetLastError によって ERROR_INVALID_PARAMETER が返されるかどうかのチェックは、ダウンレベル システムで実行されている場合を判断するための現在のメカニズムです。 ERROR_INVALID_PARAMETER と共に、ビット フィールドで新しいコンソール モード フラグのいずれか 1 つを受け取ったアプリケーションは、動作が正常に低下し、再試行される必要があります。

#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;
}

Anniversary Update の機能の選択の例

次に示すのは、Windows 10 の Anniversary Update で追加された機能に重点を置いて、バッファーを操作するためのさまざまなエスケープ シーケンスを使用する、より堅牢なコードの例です。

この例では、代替画面バッファー、タブ ストップの操作、スクロール マージンの設定、文字セットの変更を利用しています。

// 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");

}