Использование шрифта Unicode в консольном приложении C ++ - PullRequest
8 голосов
/ 17 декабря 2009

Как изменить шрифт в моем консольном приложении C ++ для Windows?

Похоже, он не использует шрифт cmd.exe, используемый по умолчанию (Lucida Console). Когда я запускаю свое приложение через существующий cmd.exe (набрав name.exe), оно выглядит так: http://dathui.mine.nu/konsol3.png, что совершенно верно. Но когда я запускаю свое приложение отдельно (дважды щелкнув по .exe), оно выглядит так: http://dathui.mine.nu/konsol2.png. Один и тот же код, два разных вида.

Теперь мне интересно, как я могу изменить шрифт, чтобы он всегда выглядел правильно, независимо от того, как он работает.


EDIT:

Хорошо, еще немного информации. Когда я просто использую этот маленький фрагмент:

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 ]

4 голосов
/ 17 декабря 2009

Windows сохраняет настройки cmd (включая шрифт) в реестре, используя путь exe в качестве ключа. Корневой ключ - «HKEY_CURRENT_USER \ Console», поэтому, если вы загляните туда с помощью regedit, вы увидите несколько подразделов, названных в честь varous exe.

Чтобы скопировать настройки существующего exe-файла, вы можете экспортировать ключ в текстовый файл, затем отредактировать файл, чтобы изменить имя ключа на имя вашего exe-файла, а затем снова импортировать его.

Вы также можете программно изменять реестр, хотя я сомневаюсь, что это немедленно вступит в силу с w.r.t. к окну вашей консоли.

3 голосов
/ 17 декабря 2009

Вы можете попробовать функцию SetCurrentConsoleFontEx () .

2 голосов
/ 17 декабря 2009

Для 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);

Теперь console_font_index - это индекс в таблице шрифтов консоли, определение которой неизвестно. Однако, console_font_index == 10, как известно, идентифицирует Lucida Console (шрифт Unicode). Я не уверен, насколько стабильно это значение в разных версиях ОС.

UPDATE

После комментария Датта я провел эксперимент с чистой установкой XP SP2.

  • Изначально GetNumberOfConsoleFonts () действительно возвращает 10, а индексы шрифтов 0..9 указывают различные растровые шрифты.

  • После того, как я открыл консоль с выбранным в ее свойствах шрифтом Lucida (только один раз; я могу закрыть его сразу после открытия, но эффект тот же), внезапно GetNumberOfConsoleFonts () начинает возвращать 12, а индексы 10 и 11 выберите Lucida разных размеров.

Так что, похоже, этот прием сработал для меня, когда я играл с ним, потому что у меня всегда было запущено хотя бы одно консольное приложение с выбранным шрифтом Lucida.

Таким образом, для практических целей ответ Джона Хансона кажется лучше. Помимо предоставления лучшего контроля, это на самом деле работает. :)

...