2009-12-17 50 views
8

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

它似乎没有使用默认使用的字体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); 

我可能是设置语言编码的只是标准输出什么?

+0

嗯......奇怪的是,有一种方法来检测控制台与双击与几个例外情况。这篇文章是一个好的开始,但它不够远:http://www.codeguru.com/cpp/misc/misc/consoleapps/article.php/c15893/ – 2009-12-17 15:03:24

+0

您使用哪种编译器? – SjB 2009-12-17 15:09:21

+0

也许跟踪启动代码 - 从pre main() - 查看实际构建控制台窗口本身的代码是什么?我假设编译器/控制台项目提供的.exe文件必须有一些代码,用于检测您的应用程序是否已经在控制台中启动,或者是否需要控制台,以便在这种情况下为您创建控制台窗口。这是我的直觉,不是研究的事实,但可能只有几分钟的调试才能验证。在这一点上,你可以看到它的源代码,看看你可能需要做什么才能访问该控制台HWND,以不同的方式设置它的字体...... – Mordachai 2009-12-17 15:11:04

回答

2

对于Vista及更高版本,有SetCurrentConsoleFontEx,因为已经有said

对于2K和XP,有一个无证函数SetConsoleFont;例如阅读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); 

console_font_index是一个指数到控制台字体表中,定义其是未知的。但是,console_font_index == 10已知识别Lucida控制台(Unicode字体)。我不确定在不同的操作系统版本中这个值有多稳定。

UPDATE

杜特的评论后,我已经运行在一个干净的XP SP2安装程序的实验。

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

  • 后,我打开,在其属性中选择Lucida的字体的控制台(只有一次;打开后马上我可以关闭它,但效果是一样的),突然GetNumberOfConsoleFonts()开始返回12,和指数10和11选择不同大小的Lucida。

如此看来这一招工作对我来说,当我打它,因为我一直运行与Lucida的字体至少一个控制台应用程序中选择。

因此,出于实用目的,jon hanson's answer似乎更好。除了提供更好的控制之外,它实际上也是可行:)

+0

它确实会改变字体,但GetNumberOfConsoleFonts()为我返回10,我试过0-9(和10,11,.. )但没有一个是Lucida Console。 所以现在的问题是,我该如何使用它来改变Lucida控制台? :) – dutt 2009-12-17 19:48:05

4

Windows将cmd设置(包括字体)存储在注册表中,使用exe路径作为关键字。根键是'HKEY_CURRENT_USER \ Console',所以如果你看看那里的注册表,你会看到几个以varous exe命名的子键。

要复制现有exe的设置,可以将密钥导出到文本文件,然后编辑文件以将密钥名称更改为exe的密钥名称,然后重新导入它。

您也可以逐步修改注册表,但我怀疑这会立即生效w.r.t.到您的控制台窗口。

3

您可以尝试SetCurrentConsoleFontEx()函数。

+1

你可能想提及GetStdHandle太 - http://msdn.microsoft.com/en-us/library/ms683231(VS.85).aspx – 2009-12-17 15:41:10

+0

iirc只存在于Vista和更高版本,更喜欢这是可行的XP上以及许多人仍然运行它。 – dutt 2009-12-17 16:05:39

+0

奇怪,他们声称你需要Vista,但也声称你应该将_WIN32_WINNT定义为0x0500(Windows 2000)或更高版本。似乎矛盾。 – 2009-12-17 16:32:28

相关问题