【问题标题】:ENABLE_VIRTUAL_TERMINAL_PROCESSING and DISABLE_NEWLINE_AUTO_RETURN failingENABLE_VIRTUAL_TERMINAL_PROCESSING 和 DISABLE_NEWLINE_AUTO_RETURN 失败
【发布时间】:2018-02-12 07:04:56
【问题描述】:

重点是在终端中制作这款小型多人游戏,应用一些基本的图形概念来掌握它的工作原理和背后的数学原理。

请注意,我希望这样做是为了好玩,并且我完全清楚使用终端有更好的选择。

我需要一个可以写入的控制台,所以重点是移除滚动条并将整个缓冲区打印到屏幕上。

但是由于字符被写入上一行末尾时的回车:

这看起来整体很难看:

在通过 SetConsoleMode 尝试了大约 3 小时后,我不和谐地询问了它。

我得到的答案是这样的:

void main( )
{
    auto h = GetStdHandle( STD_OUTPUT_HANDLE );

    DWORD mode = 0;
    GetConsoleMode( h, &mode );

    mode |= DISABLE_NEWLINE_AUTO_RETURN | ENABLE_VIRTUAL_TERMINAL_PROCESSING;

    puts( SetConsoleMode( h, mode ) ? "Win" : "Loss" );

    char * buf = new char[ 200*2 ];
    memset( buf, 0, 200*2 );
    memset( buf, 'A', 120*2 );
    std::cout << ( buf );

    getchar( );
}

结果如下:

起初我尝试将其调整到我的项目中,但失败了。 然后我很沮丧,最终创建了一个新项目,我只是将工作代码复制粘贴到其中。

你猜对了,它不起作用。

现在我已经尝试了很多东西,我已经将我的程序从 unicode 更改为 ansi 并返回,并完成了mode = DISABLE_NEWLINE_AUTO_RETURN | ENABLE_VIRTUAL_TERMINAL_PROCESSINGmode |= DISABLE_NEWLINE_AUTO_RETURN | ENABLE_VIRTUAL_TERMINAL_PROCESSING,以及每个单独使用和不使用 | 都没有成功。

鉴于错误 87 表示参数错误,我什至尝试从 GetConsoleMode 中输入确切值以查看它是否是句柄,但由于它有效,我们可以假设这不是句柄的问题。

基本上可以在另一台机器上运行的代码在我的机器上不起作用。 另一台机器是windows 10 mine的8.1,都是64。

在两台机器上,第一次从 GetConsoleMode 得到的值都是 3,这意味着 ENABLE_PROCESSED_OUTPUT 和 ENABLE_WRAP_AT_EOL_OUTPUT。

我项目上的 windows SDK 版本是 10.0.15063.0,带有 Visual Studio 2017 (v141) 的平台工具集。

我一整天都没有成功。现在这不是我第一次阅读一些重要的细节,但我一直在阅读文档,没有提到使用 ENABLE_VIRTUAL_TERMINAL_PROCESSING 的 SetConsoleMode 失败。

据我所知,我根据Docs 做得正确

我不应该做什么?

对于可能引起注意的任何拼写/语法错误,我们深表歉意,感谢您抽出宝贵时间。

【问题讨论】:

  • 不是你的错,请注意。 MSDN 通常非常擅长指定最低版本要求,但微软在这方面确实放弃了。
  • 感谢@eryksun 和 Harry Johnston (不能在一条评论中提及 2 次)。您介意将其作为答案,以便我将其标记为已解决吗?

标签: c++ windows winapi terminal console


【解决方案1】:

从 Windows 10.0.10586 开始,控制台中提供了虚拟终端模式。如果设置模式失败并出现ERROR_INVALID_PARAMETER (87),则操作系统不支持。此外,它仅在新控制台中实现。在 Windows 10 中选择旧版控制台后,启用 VT 模式可能会成功,但实际上不会启用 VT 支持。

Enabling Virtual Terminal Processing 示例中,失败案例被错误地记录为“SetConsoleMode 返回 STATUS_INVALID_PARAMETER”(0xC000000D)。作者似乎忽略了 NtDeviceIoControlFile 系统调用(在 Windows 8+ 中)返回的内核状态代码被转换为 SetConsoleMode 调用失败并将状态代码转换为 Windows API错误代码。

【讨论】:

  • 有没有办法修补 Win 版本
  • @not2qubi,控制台主机内置在操作系统中。在 Windows 7 之前,每个控制台都托管在 csrss.exe 会话服务器进程中的专用线程上。从 Windows 7 开始,每个控制台都托管在一个单独的 conhost.exe 实例中。有一些替代方案可以在不同程度上侵入控制台 API,例如 ANSICON(只是通过 DLL 注入侵入 API)和 ConEmu(一个强大的替代控制台/终端,它也依赖于 DLL 注入)。
猜你喜欢
  • 2016-12-10
  • 1970-01-01
  • 2011-12-28
  • 2015-06-17
  • 2017-01-04
  • 2017-01-16
  • 2015-04-13
  • 2011-05-08
  • 2012-09-24
相关资源
最近更新 更多