Использование шрифта Unicode в консольном приложении C++
Как изменить шрифт в моем консольном приложении 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);
это работает с правильным шрифтом. Но в моем реальном приложении я использую 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);
Могу ли я установить кодовую страницу только для стандартного вывода или что-то?
3 ответа
Для Vista и выше есть SetCurrentConsoleFontEx, как уже было сказано.
Для 2К и ХР есть недокументированная функция 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);
Сейчас, console_font_index
является индексом в таблице шрифтов консоли, определение которой неизвестно. Тем не мение, console_font_index == 10
известно, что идентифицирует Lucida Console (шрифт Unicode). Я не уверен, насколько стабильно это значение в разных версиях ОС.
ОБНОВИТЬ
После комментария Датта я провел эксперимент по чистой установке XP SP2.
Изначально GetNumberOfConsoleFonts() действительно возвращает 10, а индексы шрифтов 0..9 указывают различные растровые шрифты.
После того, как я открываю консоль с выбранным в ее свойствах шрифтом Lucida (только один раз; я могу закрыть его сразу после открытия, но эффект тот же), внезапно GetNumberOfConsoleFonts() начинает возвращать 12, а индексы 10 и 11 выбирают Lucida разных размеров,
Так что, похоже, этот трюк работал для меня, когда я играл с ним, потому что у меня всегда было запущено хотя бы одно консольное приложение с выбранным шрифтом Lucida.
Таким образом, для практических целей ответ Джона Хансона кажется лучше. Помимо предоставления лучшего контроля, это на самом деле работает.:)
Windows сохраняет настройки cmd (включая шрифт) в реестре, используя путь exe в качестве ключа. Корневым ключом является "HKEY_CURRENT_USER\Console", поэтому, если вы загляните туда с помощью regedit, вы должны увидеть несколько подразделов, названных в честь varous exe.
Чтобы скопировать настройки существующего exe-файла, вы можете экспортировать ключ в текстовый файл, затем отредактировать файл, чтобы изменить имя ключа на имя вашего exe-файла, а затем снова импортировать его.
Вы также можете программно изменять реестр, хотя я сомневаюсь, что это немедленно отразится на вашем окне консоли.