在C ++控制台应用程序中使用Unicode字体 [英] Using Unicode font in C++ console app

查看:165
本文介绍了在C ++控制台应用程序中使用Unicode字体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



似乎没有使用cmd.exe默认使用的字体(Lucida控制台)。当我通过现有的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);

它使用正确的字体。但在我的实际应用中,我使用 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);
}

,然后使用错误的字体。我使用两个不同的窗口,创建如下:

  mHandleA = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,0,
NULL, CONSOLE_TEXTMODE_BUFFER,NULL);

可以设置标准输出的代码页吗?

解决方案

对于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);
//添加错误检查
..........

SetConsoleFont(GetStdHandle(STD_OUTPUT_HANDLE),console_font_index);

现在, console_font_index 字体表,其定义未知。但是,已知 console_font_index == 10 可以识别Lucida控制台(Unicode字体)。我不知道不同操作系统版本的此值有多稳定。



UPDATE



在dutt的评论之后,我对一个干净的XP SP2设置进行了实验。




  • 最初,GetNumberOfConsoleFonts


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




所以看起来这个技巧对我来说,当我玩它,因为我总是运行至少一个控制台应用程序选择Lucida字体。



因此,出于实际目的, jon hanson的回答似乎更好。除了提供更好的控制,它实际上工作。 :)


How do I change the font in my C++ Windows console app?

It doesn't seem to use the font cmd.exe uses by default (Lucida Console). When I run my app through an existing cmd.exe (typing name.exe) it looks like this: http://dathui.mine.nu/konsol3.png which is entierly correct. But when I run my app seperatly (double-click the .exe) it looks like this: http://dathui.mine.nu/konsol2.png. Same code, two different looks.

So now I wonder how I can change the font so it always looks correctly regardless of how it's run.


EDIT:

Ok, some more information. When I just use this little snippet:

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);

it works with the correct font. But in my real application I use WriteConsoleOutput() to print strings instead:

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);
}

and then it uses the wrong font. I use two different windows, created like this:

mHandleA = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0,
                                     NULL, CONSOLE_TEXTMODE_BUFFER, NULL);

Might I be setting the codepage for just the standard output or something?

解决方案

For Vista and above, there is SetCurrentConsoleFontEx, as already has been said.

For 2K and XP, there is an undocumented function SetConsoleFont; e.g. read here.

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);

Now, console_font_index is an index into console font table, definition of which is unknown. However, console_font_index == 10 is known to identify Lucida Console (a Unicode font). I'm not sure how stable is this value across different OS versions.

UPDATE

After dutt's comment, I've run an experiment on a clean XP SP2 setup.

  • Initially, GetNumberOfConsoleFonts(), indeed, returns 10, and font indices 0..9 specify various raster fonts.

  • After I open a console with Lucida font selected in its properties (just once; I can close it immediately after opening but the effect is the same), suddenly GetNumberOfConsoleFonts() starts to return 12, and indices 10 and 11 select Lucida of different sizes.

So it seems this trick worked for me when I played with it because I always had running at least one console app with Lucida font selected.

Thus, for practical purposes, jon hanson's answer seems better. Besides offering better control, it actually works. :)

这篇关于在C ++控制台应用程序中使用Unicode字体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆