C++ Win32 GUI 应用程序,程序退出后控制台提示会覆盖以前记录的文本

问题描述 投票:0回答:1

操作系统是 Windows 10

应用程序与 /SUBSYSTEM:WINDOWS 链接,并带有附加/分配的控制台,并且输入/输出流重定向如下:

void InitConsole()
{
    if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole()) {
        SetConsoleOutputCP(CP_UTF8);

        FILE* dummy;
        freopen_s(&dummy, "CONIN$", "r", stdin);
        freopen_s(&dummy, "CONOUT$", "w", stdout);
        freopen_s(&dummy, "CONOUT$", "w", stderr);

        DWORD consoleMode;
        GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &consoleMode);
        consoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
        SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), consoleMode);

        std::ios::sync_with_stdio(true);

        std::wcout.clear();
        std::cout.clear();
        std::wcerr.clear();
        std::cerr.clear();
        std::wcin.clear();
        std::cin.clear();
    }
}

这是可行的,文本以颜色等方式显示,但是在程序退出后,控制台提示符会覆盖记录的文本,而不是从结束的地方继续:

GIF of the Prompt overwriting the logged text

这种情况发生在 Windows TerminalPowerShellCommand Prompt,以及 VSCode 集成终端上。

使用 fmtlib 记录文本。然而

std::cout
printf()
的行为同样是错误的。

有没有办法将此行为纠正为更熟悉的控制台提示符,在使用 /SUBSYSTEM:WINDOWS 时从记录的文本结束处继续?像这样:

Image of the expected behavior

通过使用 /SUBSYSTEM:CONSOLE 实现预期行为,而不调用

InitConsole()
函数。

最小可重现示例:(与 /SUBSYSTEM:WINDOWS 链接)

#define UNICODE
#define _UNICODE
#include <iostream>
#include <windows.h>

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
    if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole()) {
        SetConsoleOutputCP(CP_UTF8);

        FILE* dummy;
        freopen_s(&dummy, "CONIN$", "r", stdin);
        freopen_s(&dummy, "CONOUT$", "w", stdout);
        freopen_s(&dummy, "CONOUT$", "w", stderr);

        DWORD consoleMode;
        GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &consoleMode);
        consoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
        SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), consoleMode);

        std::ios::sync_with_stdio(true);

        std::wcout.clear();
        std::cout.clear();
        std::wcerr.clear();
        std::cerr.clear();
        std::wcin.clear();
        std::cin.clear();
    }

    std::cout << "Test Text 1\n";
    std::cout << "Test Text 2\n";
    std::cout << "Test Text 3\n";

    FreeConsole();

    return 0;
}

c++ winapi console cout
1个回答
0
投票

当编译为 Windows 程序时,它会异步启动(可以说是在后台),并且命令提示符会立即出现。它不会等待程序完成。

如果您不希望在程序完成之前出现命令提示符,我建议将其编译为控制台程序。

© www.soinside.com 2019 - 2024. All rights reserved.