在C++控制台应用程序中使用Unicode字体

dut*_*utt 8 c++ unicode winapi fonts console-application

如何更改C++ Windows控制台应用程序中的字体?

它似乎没有使用默认情况下cmd.exe使用的字体(Lucida Console).当我通过现有的cmd.exe(输入name.exe)运行我的应用程序时,它看起来像这样:http://dathui.mine.nu/konsol3.png这是非常正确的.但是,当我单独运行我的应用程序(双击.exe)时,它看起来像这样:http://dathui.mine.nu/konsol2.png.相同的代码,两个不同的外观.

所以现在我想知道如何更改字体,使其无论运行方式如何都始终正确.


编辑:

好的,还有一些信息.当我只使用这个小片段时:

SetConsoleOutputCP(CP_UTF8);
wchar_t s[] = L"èéøÞ????æ?a";
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
char* m = new char[bufferSize]; 
WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL);
wprintf(L"%S", m);
Run Code Online (Sandbox Code Playgroud)

它使用正确的字体.但在我的实际应用程序中,我WriteConsoleOutput()用来打印字符串:

CHAR_INFO* info = new CHAR_INFO[mWidth * mHeight];
for(unsigned int a = 0; a < mWidth*mHeight; ++a) {
    info[a].Char.UnicodeChar = mWorld.getSymbol(mWorldX + (a % mWidth), mWorldY + (a / mWidth));
    info[a].Attributes = mWorld.getColour(mWorldX + (a % mWidth), mWorldY + (a / mWidth));
}
COORD zero;
zero.X = zero.Y = 0;
COORD buffSize;
buffSize.X = mWidth;
buffSize.Y = mHeight;
if(!WriteConsoleOutputW(window, info, buffSize, zero, &rect)) {
    exit(-1);
}
Run Code Online (Sandbox Code Playgroud)

然后它使用错误的字体.我使用两个不同的窗口,像这样创建:

mHandleA = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0,
                                     NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
Run Code Online (Sandbox Code Playgroud)

我可能只为标准输出设置代码页吗?

atz*_*tzz 2

对于 Vista 及以上版本,有SetCurrentConsoleFontEx,正如已经说过的

对于2K和XP,有一个未记录的功能SetConsoleFont;例如,阅读此处

typedef BOOL (WINAPI *FN_SETCONSOLEFONT)(HANDLE, DWORD);
FN_SETCONSOLEFONT SetConsoleFont;
..........
HMODULE hm = GetModuleHandle(_T("KERNEL32.DLL"));
SetConsoleFont = (FN_SETCONSOLEFONT) GetProcAddress(hm, "SetConsoleFont");
// add error checking
..........

SetConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE), console_font_index);
Run Code Online (Sandbox Code Playgroud)

现在,console_font_index是控制台字体表的索引,其定义未知。然而,console_font_index == 10已知可识别 Lucida Console(一种 Unicode 字体)。我不确定这个值在不同操作系统版本中的稳定性如何。

更新

在 dutt 发表评论后,我在干净的 XP SP2 设置上运行了一个实验。

  • 最初,GetNumberOfConsoleFonts() 实际上返回 10,字体索引 0..9 指定各种光栅字体。

  • 当我打开一个在其属性中选择了 Lucida 字体的控制台后(仅一次;我可以在打开后立即关闭它,但效果是相同的),突然 GetNumberOfConsoleFonts() 开始返回 12,索引 10 和 11 选择不同大小的 Lucida 。

所以当我使用它时,这个技巧似乎对我有用,因为我总是运行至少一个选择 Lucida 字体的控制台应用程序。

因此,出于实际目的,乔恩·汉森的答案似乎更好。除了提供更好的控制之外,它确实有效。:)