日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

让Windows控制台应用程序支持VT100---原理篇

發布時間:2025/3/19 windows 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 让Windows控制台应用程序支持VT100---原理篇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

微軟的操作系統在歷史上對VT的支持可追溯到 DOS 年代,那時候有一個設備驅動程序名字叫 ANSI.SYS(泄露的dos6.0代碼里面有,位于 ms_dos_6_0_source_code\dos-6.0\dev\ansi,是匯編語言實現的),加載后就可以讓終端支持VT控制符,后來進入桌面時代后就沒有類似的支持了。直到Windows 10的Anniversary Update(1607),微軟追加了對VT的支持,這可能是得益于微軟在內核層面支持Linux kernel的努力(WSL)。下面是詳細的介紹和示例內容

https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences

測試代碼

// // Copyright (C) Microsoft. All rights reserved. // //https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#define DEFINE_CONSOLEV2_PROPERTIES// System headers #include <windows.h>// Standard library C-style #include <wchar.h> #include <stdlib.h> #include <stdio.h>#define ESC "\x1b" #define CSI "\x1b["#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 #endifbool EnableVTMode() {// Set output mode to handle virtual terminal sequencesHANDLE 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 modeprintf(CSI "104;93m"); // bright yellow on bright blueprintf("x"); // in line drawing mode, \x78 -> \u2502 "Vertical Bar"printf(CSI "0m"); // restore colorprintf(ESC "(B"); // exit line drawing mode }void PrintHorizontalBorder(COORD const Size, bool fIsTop) {printf(ESC "(0"); // Enter Line drawing modeprintf(CSI "104;93m"); // Make the border bright yellow on bright blueprintf(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 cornerprintf(CSI "0m");printf(ESC "(B"); // exit line drawing mode }void PrintStatusLine(char* const pszMessage, COORD const Size) {printf(CSI "%d;1H", Size.Y);printf(CSI "K"); // clear the lineprintf(pszMessage); }int __cdecl wmain(int argc, WCHAR* argv[]) { argc; // unusedargv; // unused//First, enable VT modebool 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 bufferprintf(CSI "?1049h");// Clear screen, tab stops, set, stop at columns 16, 32printf(CSI "1;1H");printf(CSI "2J"); // Clear screenint iNumTabStops = 4; // (0, 20, 40, width)printf(CSI "3g"); // clear all tab stopsprintf(CSI "1;20H"); // Move to column 20printf(ESC "H"); // set a tab stopprintf(CSI "1;40H"); // Move to column 40printf(ESC "H"); // set a tab stop// Set scrolling margins to 3, h-2printf(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 - Yellowprintf(CSI "2;1H");PrintHorizontalBorder(Size, true);// // Print a bottom borderprintf(CSI "%d;1H", Size.Y-1);PrintHorizontalBorder(Size, false);wchar_t wch;// draw columnsprintf(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 lineprintf("\t"); // advance to next tab stop}PrintStatusLine("Press any key to see text printed between tab stops.", Size);wch = _getwch();// Fill columns with outputprintf(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 sideif (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 lineint 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 sideif (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 bufferprintf(CSI "?1049l");}

那如果windows版本低于win10 1607怎么辦呢?我感覺可以實現一個兼容層,例如微軟的telnet客戶端,他就是支持VT的,查看前一段時間nt5泄露代碼,確實找到相關的代碼。

位于?F:\nt5src\Source\Win2K3\NT\net\tcpip\services\telnet\client\trmio.c

代碼非常多,簡單摘一些里面代碼聲明吧。

static UCHAR pchNBBuffer[ READ_BUF_SZ ]; static void NewLineUp(WI *, TRM *); static void NewLine(WI *pwi, TRM *); static void SetBufferStart(TRM *); static BOOL FAddTabToBuffer( TRM *, DWORD ); static BOOL FAddCharToBuffer(TRM *, UCHAR); static void FlushBuffer(WI *pwi, TRM *); static void CursorUp(TRM *); static void CursorDown(TRM *); static void CursorRight(TRM *); static void CursorLeft(TRM *); static void ClearLine(WI *pwi, TRM *, DWORD); static void SetMargins(TRM *, DWORD, DWORD);

另外微軟win10 的cmd和conhost是開源的,在

https://github.com/microsoft/terminal

搜索?ENABLE_VIRTUAL_TERMINAL_PROCESSING 可找到相關的代碼

總結

以上是生活随笔為你收集整理的让Windows控制台应用程序支持VT100---原理篇的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。