[英]Inconsistent behavior with Win32 Console API between console emulator
有人可以告诉我以下代码片段中我做错了什么吗?
问题是这个片段,它应该打印“Hello, World!” with colors 在cmder中以 cmd.exe 作为 shell 运行时完全符合预期,但在本机 cmd.exe 终端模拟器或本机 PowerShell 模拟器中使用时完全损坏。 具体来说就是背景颜色变了,reset也不管用。
#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 官方文档来编写整个代码的,所以我有点困惑。
我建议您可以尝试使用Multi-Byte Character Set
而不是Unicode Character Set
。
或者您可以尝试使用宽字符文字,例如:
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,
.
WriteConsole(term.h, L"Hello, ", 8, NULL, NULL);
.
WriteConsole(term.h, L"World !\n\r", 9, NULL, NULL);
编辑:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.