首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >控制台模拟器与Win32控制台API的不一致行为

控制台模拟器与Win32控制台API的不一致行为
EN

Stack Overflow用户
提问于 2022-11-28 16:46:13
回答 1查看 52关注 0票数 0

有人能告诉我在下面的片段中我做错了什么吗?

问题是这个片段,它应该打印“你好,世界!”在cmder中以cmd.exe作为外壳运行时,颜色的工作原理与预期完全相同,但在本机cmd.exe终端模拟器或本机PowerShell模拟器中使用时,颜色会被完全破坏。具体来说,背景色被改变了,而重置不起作用。

代码语言:javascript
运行
复制
#include <windows.h>
#include <io.h>
#include <conio.h>
#include <fileapi.h>

#include <assert.h>
#include <stdio.h>

typedef struct {
  HANDLE h;
  HANDLE hin;
  WORD savedAttr;
} Terminal;

#define FOREGROUND_RGB (FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN)
#define BACKGROUND_RGB (BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN)
#define TRY_OS(expr) if ((expr) == 0) { osError(); }
#define TRY_OR(expr) if ((expr) == 0)

static WORD get_text_attributes(Terminal term)
{
  CONSOLE_SCREEN_BUFFER_INFO c;

  TRY_OR(GetConsoleScreenBufferInfo(term.h, &c)) {
    return 0x70;
  }

  return c.wAttributes;
}

Terminal getHandle(FILE* in, FILE* out)
{
  Terminal term;

  if ((in == stdin) && (out == stdout)) {
    // grab the current console even if stdin/stdout have been redirected
    term.h =
        CreateFile("CON", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
                   0, 0);
    term.hin =
        CreateFile("CON", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0,
                   0);
    // term.h = GetStdHandle(STD_OUTPUT_HANDLE);
    // term.hin = GetStdHandle(STD_INPUT_HANDLE);
  } else {
    term.h = (HANDLE) _get_osfhandle(_fileno(out));
    term.hin = (HANDLE) _get_osfhandle(_fileno(in));
  }

  term.savedAttr = get_text_attributes(term);
  return term;
}

void setFG(Terminal term, int color)
{
  WORD attr = get_text_attributes(term);
  attr &= ~FOREGROUND_RGB;  // clear FG color
  attr &= ~FOREGROUND_INTENSITY;  // clear FG intensity
  attr |= color;

  SetConsoleTextAttribute(term.h, attr);
}

void setBG(Terminal term, int color)
{
  WORD attr = get_text_attributes(term);
  attr &= ~BACKGROUND_RGB;  // clear BG color
  attr &= ~BACKGROUND_INTENSITY;  // clear BG intensity
  attr |= color;

  SetConsoleTextAttribute(term.h, attr);
}

int main()
{
  Terminal term = getHandle(stdin, stdout);

  setFG(term, FOREGROUND_RED);
  WriteConsole(term.h, "Hello, ", 7, NULL, NULL);

  setFG(term, FOREGROUND_BLUE);
  WriteConsole(term.h, "World !\r\n", 9, NULL, NULL);

  // reset style
  SetConsoleTextAttribute(term.h, term.savedAttr);

  return 0;
}

我想我在使用API时做错了什么,cmder对它的使用比较宽松,但是我是通过阅读官方的Microsoft来编写这整个代码的,所以我有点困惑。

EN

回答 1

Stack Overflow用户

发布于 2022-11-29 02:16:30

我建议您尝试使用Multi-Byte Character Set而不是Unicode Character Set

或者您可以尝试使用宽字符文字,例如:

代码语言:javascript
运行
复制
    term.h =
        CreateFile(L"CON", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
            0, 0);
    term.hin =
        CreateFile(L"CON", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0,

代码语言:javascript
运行
复制
WriteConsole(term.h, L"Hello, ", 8, NULL, NULL);

代码语言:javascript
运行
复制
WriteConsole(term.h, L"World !\n\r", 9, NULL, NULL);

编辑:

使用cmd运行的结果:

使用visual studio运行的结果:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74603868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档