次の方法で共有


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

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

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

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

出力シーケンス

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

単純なカーソルの配置

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

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

このテーブル内のすべてのコマンドは、通常、 SetConsoleCursorPosition コンソール API を呼び出してカーソルを置くのと同じです。

カーソルの移動は、現在のビューポートによってバッファーにバインドされます。 スクロール (使用可能な場合) は行われません。

順序 速記 行動
ESC M RI 逆インデックス - \nの逆操作を実行し、カーソルを 1 行上に移動し、水平位置を維持し、必要に応じてバッファーをスクロールします*
ESC 7 DECSC メモリ内のカーソル位置を保存**
ESC 8 DECSR メモリからのカーソル位置の復元**

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

**save コマンドを最初に使用するまで、メモリに保存された値はありません。 保存された値にアクセスする唯一の方法は、restore コマンドを使用することです。

カーソルの配置

次の表は、制御シーケンス 導入子 (CSI) 型シーケンスを含みます。 すべての CSI シーケンスは、ESC (0x1B) の後に [ (左角かっこ、0x5B) で始まり、各操作の詳細情報を指定するための可変長パラメーターを含む場合があります。 これは短縮形の <n>で表されます。 次の各テーブルは、各テーブルの下にグループのしくみを説明するメモを含む機能別にグループ化されています。

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

  • <n> は移動する距離を表し、省略可能なパラメーターです。
  • <n>を省略するか、0 と等しい場合は、1 として扱われます。
  • <n> 32,767 (最大短い値) より大きくすることはできません
  • <n> を負にすることはできません

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

カーソルの移動は、現在のビューポートによってバッファーにバインドされます。 スクロール (使用可能な場合) は行われません。

順序 Code 説明 行動
ESC [ <n> A CUU カーソルを上へ <n でカーソルを上げる>
ESC [ <n> B CUD カーソルダウン カーソルを <n で下へ移動する>
ESC [ <n> C CUF カーソルを前方に移動 カーソル順 (右) ( <n)>
ESC [ <n> D カブ カーソルを後方に移動 <n のカーソルを後方 (左) に移動する>
ESC [ <n> E CNL カーソルの次の行 カーソルを現在位置から下 <n> 行
ESC [ <n> F CPL カーソルの前の行 現在の位置から <行> 上にカーソルを置く
ESC [ <n> G チャ カーソル水平絶対 カーソルが現在 <行>水平方向に移動します。
ESC [ <n> d VPA 垂直線位置絶対 カーソルが現在の列の <n>垂直方向の位置に移動します
ESC [ <y> ; <x> H カップ カーソル位置 *カーソルが <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 などの復元カーソル操作を実行します。

*<x> および <y> パラメーターには、上記の <n> と同じ制限があります。 <x>および<y>を省略すると、1;1 に設定されます。

**ANSI.sys 履歴ドキュメントは、 https://msdn.microsoft.com/library/cc722862.aspx で確認でき、利便性と互換性のために実装されています。

カーソルの表示

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

順序 Code 説明 行動
ESC [ ? 12 時間 ATT160 テキスト カーソルの点滅を有効にする カーソルの点滅を開始する
ESC [ ? 12 l ATT160 テキスト カーソル 点滅を無効にする カーソルの点滅を停止する
ESC [ ? 25 時間 DECTCEM テキスト カーソル有効化モードの表示 カーソルを表示する
ESC [ ? 25 l DECTCEM テキスト カーソル有効化モード 非表示 カーソルを非表示にする

ヒント

有効シーケンスは小文字の H 文字 (h) で終わり、無効シーケンスは小文字の L 文字 (l) で終わる。

カーソルの図形

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

順序 Code 説明 行動
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 安定したバー 固定バー カーソルの図形

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

ビューポートの配置

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

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

順序 Code 説明 行動
ESC [ <n> S SU 上へスクロール <n>でテキストを上にスクロールします。 パンダウンとも呼ばれ、画面の下部から改行が入力されます。
ESC [ <n> T SDカード 下へスクロール <n>で下にスクロールします。 パンアップとも呼ばれ、画面の上部から改行が入力されます。

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

また、上下にスクロールすることは、スクロール余白の影響を受ける点にも注意してください。 上下にスクロールしても、スクロール余白の外側の行には影響しません。

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

テキストの変更

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

順序 Code 説明 行動
ESC [ <n> @ ICH 文字の挿入 現在のカーソル位置に <n> スペースを挿入し、既存のすべてのテキストを右にシフトします。 右側の画面から出たテキストが削除されます。
ESC [ <n> P DCH 文字の削除 現在のカーソル位置 <n> 文字を削除し、画面の右端から空白文字をシフトします。
ESC [ <n> X ECH 文字の消去 <n>文字をスペース文字で上書きして、現在のカーソル位置から消去します。
ESC [ <n> L IL 線の挿入 <n>行をカーソル位置のバッファーに挿入します。 カーソルが置いている行と、その下の行が下方向にシフトします。
ESC [ <n> M DL [行の削除] カーソル <行から始まる> 行をバッファーから削除します。

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

各シーケンスについて、省略した場合の <n> の既定値は 0 です。

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

  • 0 は、現在のカーソル位置 (両端を含む) から行/表示の末尾まで消去します。
  • 1 は、行/表示の先頭から現在のカーソル位置まで消去します。
  • 2 行/表示全体を消去します。
順序 Code 説明 行動
ESC [ <n> J 拘束形態素 ディスプレイで消去 <n で指定された現在のビューポート/画面のすべてのテキストをスペース文字に置き換えます>
ESC [ <n> K EL 行内の消去 行のすべてのテキストを、 <n で指定されたカーソルに置き換えます> スペース文字

テキストの書式設定

このセクションのすべてのコマンドは、通常、 SetConsoleTextAttribute コンソール API を呼び出して、コンソール出力テキスト バッファーへの今後のすべての書き込みの書式設定を調整することと同じです。

このコマンドは、次の <n> 位置がセミコロンで区切られた 0 ~ 16 個のパラメーターを受け取ることができるという点で特殊です。

パラメーターが指定されていない場合は、単一の 0 パラメーターと同じように扱われます。

順序 Code 説明 行動
ESC [ <n> m SGR グラフィックス表示の設定 <n で指定された画面とテキストの形式を設定する>

次の値の表は、さまざまな書式設定モードを表すために <n> で使用できます。

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

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

価値 説明 行動
0 既定値 変更前のすべての属性を既定の状態に戻します。
1 太字/明るい 前景色に明るさ/強度フラグを適用します
22 太字/明るい色なし 前景色から明るさ/強度フラグを削除します
4 アンダーライン 下線を追加します
二十四 下線なし 下線を削除します
7 否定的 前景色と背景色を入れ替えます
二十七 正 (負の値なし) 前景/背景を通常の状態に戻します。
30 前景黒 非太字/明るい黒を前景に適用します
31 前景色 (赤) 非太字/明るい赤を前景に適用します
32 前景緑 非太字/明るい緑を前景に適用します
33 前景 黄色 非太字/明るい黄色を前景に適用します
34 前景 (青) 非太字/明るい青を前景に適用します
35 前景マゼンタ 非太字/明るいマゼンタを前景に適用します
36 前景シアン 非太字/明るいシアンを前景に適用します
37 前景白 非太字/明るい白を前景に適用します
三十八 前景拡張 前景に拡張カラー値を適用します (以下の詳細を参照)
39 前景の既定値 既定値の前景部分のみを適用します (0 を参照)
40 背景 黒 非太字/明るい黒を背景に適用します
41 背景 赤 非太字/明るい赤を背景に適用します
42 背景 緑 非太字/明るい緑を背景に適用します
43 背景 (黄色) 非太字/明るい黄色を背景に適用します
44 背景 (青) 非太字/明るい青を背景に適用します
45 背景マゼンタ 非太字/明るいマゼンタを背景に適用します
46 背景 シアン 非太字/明るいシアンを背景に適用します
47 背景 (白) 非太字/明るい白を背景に適用します
48 拡張された背景 拡張された色の値を背景に適用します (下記の詳細を参照してください)
49 背景の既定値 既定値の背景部分のみを適用します (0 を参照)
90 明るい前景黒 前景に太字/明るい黒を適用します
91 明るい前景赤 前景に太字/明るい赤を適用します
92 明るい前景緑 前景に太字/明るい緑を適用します
93 明るい前景黄色 前景に太字/明るい黄色を適用します
94 明るい前景の青 前景に太字/明るい青を適用します
95 Bright Foreground Magenta 前景に太字/明るいマゼンタを適用します
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 ;<> 前景色を 88 または 256 色の表で<>インデックスに設定します*
48 ;5 ;<> 背景色を 88 または 256 色テーブルの<>インデックスに設定します*

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

画面の色

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

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

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

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

モードの変更

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

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

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

順序 Code 説明 行動
ESC = DECKPAM キーパッド アプリケーション モードを有効にする キーパッド キーは、アプリケーション モード シーケンスを出力します。
Esc キー > DECKPNM キーパッド数値モードを有効にする キーパッド キーは、数値モード シーケンスを出力します。
ESC [ ? 1 時間 DECCKM カーソル キー アプリケーション モードを有効にする キーパッド キーは、アプリケーション モード シーケンスを出力します。
ESC [ ? 1 l DECCKM カーソル キー アプリケーション モードを無効にする (通常モードを使用) キーパッド キーは、数値モード シーケンスを出力します。

クエリの状態

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

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

順序 Code 説明 行動
ESC [ 6 n DECXCPR レポート カーソル位置 カーソル位置を ESC [ <r> ; として出力 <c> R Where <r> = cursor row and <c> = cursor column
ESC [ 0 c DA デバイス属性 ターミナル ID を報告します。 "\x1b[?1; を出力します。0c"。"VT101 とオプションなし" を示します。

タブ

Windows コンソールでは従来、タブの幅は 8 文字のみを想定していますが、特定のシーケンスを利用する *nix アプリケーションでは、コンソール ウィンドウ内のタブ位置を操作して、アプリケーションによるカーソルの移動を最適化できます。

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

順序 Code 説明 行動
ESC H HTS 水平タブ セット カーソルの現在の列にタブ位置を設定します。
ESC [ <n> I CHT [カーソルの水平 (前方)] タブ タブ位置を使用して、カーソルを (同じ行内の) 次の列に進めます。 これ以上タブ位置がない場合は、行の最後の列に移動します。 カーソルが最後の列にある場合は、次の行の最初の列に移動します。
ESC [ <n> Z CBT [カーソルの後方] タブ タブ位置を使用して、(同じ行内の) 前の列にカーソルを移動します。 これ以上タブ位置がない場合は、カーソルを最初の列に移動します。 カーソルが最初の列にある場合、カーソルは移動しません。
ESC [ 0 g TBC タブクリア (現在の列) 現在の列にタブ位置がある場合は、そのタブ位置をクリアします。 それ以外の場合は何も行いません。
ESC [ 3 g TBC タブクリア (すべての列) 現在設定されているすべてのタブ位置をクリアします。
  • CHT と CBT の両方の場合、 <n> は省略可能なパラメーターです。これは、指定した方向にカーソルを進める回数を示す省略可能なパラメーターです (default=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 を参照してください。

順序 説明 行動
ESC ( 0 文字セットの指定 – DEC 線描画 DEC 線描画モードを有効にします
ESC ( B 文字セットの指定 – US ASCII ASCII モードを有効にする (既定)

特に、DEC 線描画モードは、コンソール アプリケーションで罫線を描画するために使用されます。 次の表は、どの ASCII 文字がどの線描画文字にマップするかを示しています。

ヘックス 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 には、 <t> と <b> の 2 つの省略可能なパラメーターがあります。これは、スクロール領域の上と下の行を表す行を指定するために使用されます。 パラメーターを省略すると、 <t> の既定値は 1、 <b> は現在のビューポートの高さになります。

スクロール余白はバッファー単位であるため、重要なことに、代替バッファーとメイン バッファーは個別のスクロール余白の設定を維持します (そのため、代替バッファーの全画面表示アプリケーションはメイン バッファーの余白を有害にしません)。

順序 Code 説明 行動
ESC [ <t> ; <b> r DECSTBM スクロール領域の設定 ビューポートの VT スクロール余白を設定します。

ウィンドウ のタイトル

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

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

順序 説明 行動
ESC ] 0 ; <string><聖> ウィンドウタイトルの設定 コンソール ウィンドウのタイトルを <string> に設定します。
ESC ] 2 ; <string><聖> ウィンドウタイトルの設定 コンソール ウィンドウのタイトルを <string> に設定します。

ここで終了する文字は、"Bell" 文字 '\x07' です。

代替画面バッファー

*Nixスタイルのアプリケーションは、多くの場合、代替画面バッファーを使用して、それらを開始したアプリケーションに影響を与えることなく、バッファーの内容全体を変更することができます。 代替バッファーは、スクロールバック領域を含まないウィンドウのサイズです。

この動作の例として、bash から vim を起動するタイミングを検討してください。 Vimは画面全体を使用してファイルを編集し、bashに戻って元のバッファを変更せずに残します。

順序 説明 行動
ESC [ ? 1 0 4 9 時間 代替画面バッファーを使用する 新しい代替画面バッファーに切り替えます。
ESC [ ? 1 0 4 9 l メイン画面バッファーを使用する メイン バッファーに切り替えます。

ウィンドウの幅

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

順序 Code 説明 行動
ESC [ ? 3 時間 DECCOLM 列数を 132 に設定する 本体の幅を幅 132 列に設定します。
ESC [ ? 3 l DECCOLM 列数を 80 に設定する 本体の幅を幅 80 列に設定します。

ソフト リセット

次のシーケンスを使用して、特定のプロパティを既定値にリセットできます。次のプロパティは、次の既定値にリセットされます (これらのプロパティを制御するシーケンスも一覧表示されます)。

  • カーソルの可視性: 表示 (DECTEM)
  • テンキー: 数値モード (DECNKM)
  • カーソル キー モード: 標準モード (DECCKM)
  • 上余白と下余白: 上 = 1、下 = 本体の高さ (DECSTBM)
  • 文字セット: US ASCII
  • グラフィックス表示: 既定値/オフ (SGR)
  • カーソルの状態を保存する: ホーム位置 (0,0) (DECSC)
順序 Code 説明 行動
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
End 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

Numpad とファンクション キー

順序
バックスペース 0x7f (DEL)
一時停止 0x1a (SUB)
逃げる 0x1b (ESC)
[挿入] ESC [ 2 ~
削除 ESC [ 3 ~
ページアップ ESC [ 5 ~
ページダウン ESC [ 6 ~
フォーミュラ1 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) にシフトダウンされた 1 文字です。 たとえば、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

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

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

次の図は、前のコード例の出力を示しています。

sgr コマンドを使用したコンソールの出力

仮想ターミナル処理の有効化の例

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

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

  2. SetConsoleMode が 0 を返し、GetLastError がERROR_INVALID_PARAMETERを返すかどうかを確認することは、ダウンレベルのシステムでいつ実行されるかを判断するための現在のメカニズムです。 ビット フィールドに新しいコンソール モード フラグのいずれかを持つERROR_INVALID_PARAMETERを受け取るアプリケーションは、動作を適切に低下させ、もう一度やり直す必要があります。

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

記念日の更新機能の選択の例

次の例は、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");

}