Вот что происходит:
- Вы вызываете SetWindowText с чем-то вроде
"\xC4\xEE\xE1\xF0\xEE\xE5 xF3\xF2\xF0\xEE"
. - Вы скомпилированы как приложение ANSI, а не Unicode, так что сопоставляется свызов SetWindowTextA.
- SetWindowTextA видит, что окно было создано в режиме ANSI, поэтому оно устанавливает строку напрямую.(Если бы это было окно Unicode, то оно преобразует входную строку ANSI в Unicode и передает ее в SetWindowTextW.)
- Окно ANSI преобразует строку ANSI в Unicode, чтобы оно могло ее отобразить.Но он не знает, что строка находится в другой кодовой странице, чем в системе по умолчанию.Именно это преобразование меняет все обратно на латинские символы.Предполагается, что входная строка находится в кодовой странице процесса по умолчанию (Windows 1252 в вашем случае).Так что теперь у вас есть куча латинских символов с ударениями вместо строки кириллицы.
- Элемент управления пытается отобразить эту строку Unicode, используя что-то вроде DrawTextW или TextOutW.
- Часть нижнего уровнясистема говорит: «О, дерьмо, эта строка представляет собой набор латинских символов, но пользователь выбрал кириллический шрифт».Чтобы решить проблему, он использует связывание шрифтов (или запасной вариант шрифта, я путаю эти термины), чтобы эффективно выбрать шрифт, совместимый с 1252.
- Вы видите латынь, вместо правильного русского.
Я пытался придумать минимальный способ сделать то, что вам нужно, но мне не удалось.Моей первой идеей было сделать преобразование самостоятельно и напрямую вызвать SetWindowTextW:
void SetWindowTextRussian(HWND hwnd, char *pszCyrillic) {
const int cchCyrillic = ::lstrlen(pszCyrillic);
const int cchUnicode = 4 * cchCyrillic; // worst case
WCHAR *pszUnicode = new WCHAR[cchUnicode];
// See: http://msdn.microsoft.com/en-us/library/dd317756(v=vs.85).aspx
const UINT CP_CYRILLIC = 1251;
if (::MultiByteToWideChar(CP_CYRILLIC, 0, pszCyrillic, -1,
pszUnicode, cchUnicode) > 0) {
::SetWindowTextW(hwnd, pszUnicode);
}
delete [] pszUnicode;
}
Но это не работает.Я подозреваю, что, так как окно было создано как окно ANSI, строка Unicode преобразуется обратно в ANSI (при условии, что снова используется неправильная кодовая страница), а затем вместо латинской ерунды вы получаете вопросительные знаки.
Я думаю, что выВам придется конвертировать в приложение Unicode или запускать только с кодовой страницей по умолчанию, равной 1251.
Обновление : если вы управляете созданием окна (например, вывызовите CreateWindow напрямую, вместо того, чтобы иметь диалоговое окно для создания элементов управления), тогда вы, вероятно, можете заставить вышеуказанную работу работать, вызвав CreateWindowW напрямую и создав окно Unicode для значимых элементов управления.