ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

colored ENABLE_VIRTUAL_TERMINAL_PROCESSING

2021-12-10 12:33:00  阅读:230  来源: 互联网

标签:ENABLE HANDLE PROCESSING TERMINAL BOOL result rovi mode


ENABLE_VIRTUAL_TERMINAL_PROCESSING

当用WriteFile或WriteConsole写入时,字符被解析为VT100和类似的控制字符序列,这些字符控制光标移动、颜色/字体模式和其他操作,也可以通过现有的Console APIs执行。欲了解更多信息,请参见控制台虚拟终端序列。

see: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#example-of-sgr-terminal-sequences

检测、测试cmd.exe颜色支持

#define _WIN32_WINNT 0x0600

#include <stdio.h>
#include <windows.h>
#include <fileapi.h>

#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif

typedef NTSTATUS (WINAPI*RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);

/**
 * Check if STD_OUTPUT_HANDLE or STD_ERROR_HANDLE is redirected to a file.
 */
BOOL IsRedirectedToFile(DWORD stdHandle) {
	BOOL result = FALSE;

	HANDLE hStd = GetStdHandle(stdHandle);
	if (hStd != INVALID_HANDLE_VALUE) {
		if (GetFinalPathNameByHandle(hStd, NULL, 0, 0) != 0 || GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
			result = TRUE;
		}
	}

	return result;
}

/**
 * Check if the current console supports ANSI colors.
 */
BOOL HaveColorSupport() {
	static BOOL result = 2;
	if (result == 2) {
		const DWORD MINV_MAJOR = 10, MINV_MINOR = 0, MINV_BUILD = 10586;
		result = FALSE;
		HMODULE hMod = GetModuleHandle(TEXT("ntdll.dll"));
		if (hMod) {
			RtlGetVersionPtr fn = (RtlGetVersionPtr) GetProcAddress(hMod, "RtlGetVersion");
			if (fn != NULL) {
				RTL_OSVERSIONINFOW rovi = { 0 };
				rovi.dwOSVersionInfoSize = sizeof(rovi);
				if (fn(&rovi) == 0) {
					if (
						rovi.dwMajorVersion > MINV_MAJOR
						||
						(
							rovi.dwMajorVersion == MINV_MAJOR
							&&
							(
								rovi.dwMinorVersion > MINV_MINOR
								||
								(
									rovi.dwMinorVersion == MINV_MINOR
									&& rovi.dwBuildNumber >= MINV_BUILD
								)
							)
						)
					) {
						result = TRUE;
					}
				}
			}
		}
	}
	return result;
}

/**
 * Check if the current console has ANSI colors enabled.
 */
BOOL ColorSupportEnabled() {
	BOOL result = FALSE;
	if (HaveColorSupport()) {
		HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
		if (hStdOut != INVALID_HANDLE_VALUE) {
			DWORD mode;
			if (GetConsoleMode(hStdOut, &mode)) {
				if (mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) {
					result = TRUE;
				}
			}
		}
	}

	return result;
}

/**
 * Enable/disable ANSI colors support for the current console.
 *
 * Returns TRUE if operation succeeded, FALSE otherwise.
 */
BOOL EnableColorSupport(BOOL enabled)
{
	BOOL result = FALSE;
	if (HaveColorSupport()) {
		HANDLE hStdOut;
		hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
		if (hStdOut != INVALID_HANDLE_VALUE) {
			DWORD mode;
			if (GetConsoleMode(hStdOut, &mode)) {
				if (((mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) ? 1 : 0) == (enabled ? 1 : 0)) {
					result = TRUE;
				} else {
					if (enabled) {
						mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
					} else {
						mode &= ~ENABLE_VIRTUAL_TERMINAL_PROCESSING;
					}
					if (SetConsoleMode(hStdOut, mode)) {
						result = TRUE;
					}
				}
			}
		}
	}

	return result;
}

LPSTR formatOkKo(LPSTR buffer, BOOL cond, LPCSTR ok, LPCSTR ko) {
	BOOL color = ColorSupportEnabled();
	buffer[0] = '\0';
	if (color) {
		strcat(buffer, cond ? "\x1b[92m" : "\x1b[91m");
	}
	strcat(buffer, cond ? ok : ko);
	if (color) {
		strcat(buffer, "\x1b[0m");
	}
	return buffer;
}

int main(void) {
	printf("stdOut redirected? %s\n", IsRedirectedToFile(STD_OUTPUT_HANDLE) ? "yes" : "no");
	printf("stdErr redirected? %s\n", IsRedirectedToFile(STD_ERROR_HANDLE) ? "yes" : "no");
	printf("Can have color? %s\n", HaveColorSupport() ? "yes" : "no");
	printf("Color is enabled? %s\n", ColorSupportEnabled() ? "yes" : "no");
	printf("Enabling color: %s\n", EnableColorSupport(TRUE) ? "success" : "failed");
	printf("Color is enabled? %s\n", ColorSupportEnabled() ? "yes" : "no");
	printf("Sample colored text: %s\n", (ColorSupportEnabled() && !IsRedirectedToFile(STD_OUTPUT_HANDLE)) ? "\x1b[92mTEST\x1b[0m" : "<skipped>");
	printf("Disabling color: %s\n", EnableColorSupport(FALSE) ? "success" : "failed");
	return EXIT_SUCCESS;
}

Rust库:colored

https://github.com/mackwic/colored/blob/master/src/control.rs

标签:ENABLE,HANDLE,PROCESSING,TERMINAL,BOOL,result,rovi,mode
来源: https://www.cnblogs.com/develon/p/15671168.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有