简体   繁体   English

我该如何ENABLE_VIRTUAL_TERMINAL_PROCESSING?

[英]How can I ENABLE_VIRTUAL_TERMINAL_PROCESSING?

Some time ago I noticed that there's a new console mode ENABLE_VIRTUAL_TERMINAL_PROCESSING and I decided to try it out. 不久前,我注意到有一个新的控制台模式ENABLE_VIRTUAL_TERMINAL_PROCESSING ,因此我决定尝试一下。 Here's my sample code: 这是我的示例代码:

// File: test1.c
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char * const TEST_STRING = "\x1B[31;1mRed\x1B[0m \x1B[32;1mGreen\x1B[0m \x1B[34;1mBlue\x1B[0m";

void ErrorExit(const char* errorMessage) {
    puts(errorMessage);
    exit(1);
}

int main(int argc, char** argv) {
    if (argc != 2) {
        ErrorExit("Usage: program (enable|disable|test|sample)");
    }

    HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE), hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD dwMode;

    char *cmd = argv[1];
    if (!strcmp(cmd, "enable")) {
        /*
        GetConsoleMode(hInput, &dwMode);
        dwMode |= ENABLE_VIRTUAL_TERMINAL_INPUT;
        SetConsoleMode(hInput, dwMode);
        */

        GetConsoleMode(hOutput, &dwMode);
        dwMode |= ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
        if (!SetConsoleMode(hOutput, dwMode)) {
            ErrorExit("SetConsoleMode failed.");
        }
    }
    else if (!strcmp(cmd, "disable")) {
        /*
        GetConsoleMode(hInput, &dwMode);
        dwMode &= ~ENABLE_VIRTUAL_TERMINAL_INPUT;
        SetConsoleMode(hInput, dwMode);
        */

        GetConsoleMode(hOutput, &dwMode);
        dwMode &= ~ENABLE_VIRTUAL_TERMINAL_PROCESSING;
        if (!SetConsoleMode(hOutput, dwMode)) {
            ErrorExit("SetConsoleMode failed.");
        }
    }
    else if (!strcmp(cmd, "test")) {
        puts(TEST_STRING);
    }
    else if (!strcmp(cmd, "sample")) {
        SetConsoleTextAttribute(hOutput, 0x0C);
        printf("Red");
        SetConsoleTextAttribute(hOutput, 0x07);
        printf(" ");
        SetConsoleTextAttribute(hOutput, 0x0A);
        printf("Green");
        SetConsoleTextAttribute(hOutput, 0x07);
        printf(" ");
        SetConsoleTextAttribute(hOutput, 0x09);
        printf("Blue");
        SetConsoleTextAttribute(hOutput, 0x07);
        printf("\n");
    }
    else {
        ErrorExit("Invalid command!");
    }
    return 0;
}

The code compiled successfully into test1.exe , but it didn't work as expected: 该代码已成功编译到test1.exe ,但未按预期工作:

屏幕截图

I am fairly sure I've got everything else correct. 我相当确定我所做的所有其他事情都是正确的。 I'm running latest Windows 10 Enterprise 64-bit, version 10.0.17763.1 . 我正在运行最新的Windows 10 Enterprise 64位版本10.0.17763.1

I have also tried this but it made no difference: 我也尝试过,但这没什么区别:

else if (!strcmp(cmd, "test")) {
    DWORD dwNumber = strlen(TEST_STRING), dwWritten;
    WriteConsole(hOutput, TEST_STRING, dwNumber, &dwWritten, NULL);
    puts("");
}

So why isn't my code working (still generating garbage when invoked as test1 test , after running test1 enable )? 那么,为什么我的代码无法正常工作(在运行test1 enable之后,当作为test1 test调用时仍然生成垃圾)?

The problem is, that the settings you do with SetConsoleMode() affect only the running process (and potential subprocesses). 问题在于,使用SetConsoleMode()的设置仅影响正在运行的进程(和潜在的子进程)。 This means, it is not really a setting of the command line window and not "passed back" to the parent shell process. 这意味着,它实际上不是命令行窗口的设置,并且不会“传递”给父shell进程。 You have to set it directly before you do your output, ie: 您必须在进行输出之前直接设置它,即:

else if (!strcmp(cmd, "test")) {
    GetConsoleMode(hOutput, &dwMode);
    dwMode |= ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
    if (!SetConsoleMode(hOutput, dwMode)) {
        ErrorExit("SetConsoleMode failed.");
    }
    puts(TEST_STRING);
}

This should work as you expect. 这应该可以按预期工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM