Визуализация uft-8 (польский) не работает должным образом

Мое программное обеспечение поддерживает несколько языков (английский, немецкий, польский, русский, ...).
По этой причине у меня есть несколько языковых файлов с текстами диалогов на определенном языке (в кодировке UTF-8). В моем приложении mfc я открываю и читаю эти файлы и вставляю текст в свои AfxMessageBoxes и другие окна пользовательского интерфейса.

// Get the codepage number. 65001 = UTF-8
// In the real code this is a parameter in the function I call (just for clarification)
LANGID languageID = 65001;
TCHAR szCodepage[10];
GetLocaleInfo (MAKELCID (languageID, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, szCodepage, 10);
int nAnsiCodePage = _ttoi (szCodepage);

// Open the file
CFile file;
CString filename = getName();

if (!file.Open(FileName, CFile::modeRead, NULL))
{
    //Check if everything is fine, else break
}

// Read the file
CString inString;
int len = file.GetLength ();
UINT n = file.Read (inString.GetBuffer(len), len);
inString.ReleaseBuffer ();
int size = MultiByteToWideChar (CP_ACP, 0, strAllItems, -1, NULL, 0);

WCHAR *ubuf = new WCHAR[size + 1]; 
MultiByteToWideChar ((UINT) nAnsiCodePage, (nAnsiCodePage == CP_UTF8 ?
                                     0 : MB_PRECOMPOSED), inString, -1, ubuf, (int) size);

outString = ubuf;
file.Close ();


Результат:

Результат

Этот механизм отлично работает для специальных букв русского и немецкого языков, но не для польских. Я уже проверил сайт utf-8 (http://www.utf8-chartable.de/unicode-utf8-table.pl?number=1024), и польские символы являются его частью.
Я также проверил шестнадцатеричные значения моей CString, и все вроде бы в порядке, но это не визуализируется должным образом. Просто для проверки я изменил используемую кодовую страницу с utf-8 на 1250 (Восточная Европа, включая польский язык), и это также не сработало. Что я делаю не так?

РЕДАКТИРОВАТЬ:
Когда я использую:

MultiByteToWideChar (CP_UTF8 , 0, inString, -1, ubuf, (int) size);

Шестнадцатеричные значения сокращены до букв «наилучшего совпадения». Значение моего результата: mezczyzna

Я использую Windows 7 с выбранным английским языком.


person xMutzelx    schedule 17.04.2018    source источник
comment
Используемый вами шрифт поддерживает польские символы?   -  person Alan Birtles    schedule 17.04.2018
comment
@AlanBirtles Если я все сделал правильно, я использовал шрифт Segoe UI. Я не знаю, поддерживает ли это полировку. Я проверю.   -  person xMutzelx    schedule 17.04.2018
comment
CString уже содержит широкие символы (если только вы не компилируете приложение без поддержки Unicode, чего делать не следует), поэтому чтение utf8 в него не сработает. Если вы собираетесь скрыть utf8, вам следует указать CP_UTF8 в качестве кодовой страницы. Но решением было бы удалить весь этот код и переключиться на ресурсы MUI (многоязычный пользовательский интерфейс), которые будут автоматически загружать соответствующий язык.   -  person user7860670    schedule 17.04.2018
comment
Пользовательский интерфейс Segoe поддерживает польские символы. Ваша проблема заключается в том, что вы используете CP_ACP. Вы знаете, что вводите кодировку UTF-8, так зачем лгать API? Кроме того, передача (потенциально) другой кодовой страницы в вызов, который выполняет фактическое преобразование, является еще одной ошибкой. Если вы используете общую тему для первого вызова API для получения размера буфера результатов, а затем вызываете его во второй раз для выполнения операции, вам необходимо передать одинаковые параметры в обоих вызовах.   -  person IInspectable    schedule 17.04.2018
comment
@VTT К сожалению, этот проект не использует Unicode ... Если я изменю его, проект не скомпилируется. Мне не разрешено изменять настройки проекта.   -  person xMutzelx    schedule 17.04.2018
comment
Что ж, вы должны переключить его на Unicode и исправить ошибки компиляции. Прошло около 20 лет с тех пор, как написание не-Unicode-приложений для Windows перестало быть приемлемым. Обратите внимание, что большинство новых API-интерфейсов поддерживают только Unicode, а использование API-интерфейсов, отличных от Unicode, часто влечет за собой снижение производительности.   -  person user7860670    schedule 17.04.2018
comment
@IInspectable Спасибо за этот совет, я сразу же изменил его. К сожалению, это не решает мою проблему.   -  person xMutzelx    schedule 17.04.2018
comment
@xMutzelx: переход на Unicode - это не волшебное быстрое решение. Однако это единственное решение, которое Microsoft активно поддерживает.   -  person MSalters    schedule 17.04.2018


Ответы (1)


Ну, у вас есть два варианта:

A. Сделайте ваше приложение Unicode. Вы не говорите нам, так ли это на самом деле, но я делаю вывод, что это не так. Технически это «лучшее» решение, но оно может потребовать больших усилий, а может быть и вообще неосуществимым (например, использование библиотек, отличных от Unicode).

Б. Если ваше приложение не поддерживает Unicode, у вас есть некоторые ограничения:
– ваше приложение сможет корректно отображать только одну кодовую страницу с использованием API и сообщений, отличных от Unicode, что, к сожалению, невозможно. может быть установлен для каждого приложения, он глобально устанавливается в Windows с помощью параметра "Язык для программ, отличных от Unicode" и требует перезагрузки.
— Чтобы правильно отображать строки, содержащие символы, не входящие в кодовую страницу по умолчанию, вам нужно преобразовать их в Unicode и явно использовать «широкие» версии API и сообщений для их отображения (например, MessageBoxW()). Немного громоздко, но выполнимо, если операция касается лишь небольшого количества элементов управления.

Машина, над которой вы работаете, имеет какой-то западноевропейский язык как «Язык для программ, не поддерживающих Unicode», и я прихожу к такому выводу, потому что «Этот механизм отлично работает для специальных букв русского и немецкого языков» и «Используя MessageBoxA (0 , "mężczyzna", 0, 0) не работает", как вы сказали (хотя я совсем не уверен насчет русского, так как это другая кодировка).

Кроме того, как сказал IInspectable, int size = MultiByteToWideChar (CP_ACP, 0, strAllItems, -1, NULL, 0); вообще не имеет смысла, поскольку известно, что строка является UTF-8, а не кодовой страницей по умолчанию. Вам также может понадобиться удалить заголовок спецификации UTF-8, если он содержится в вашем файле.

person Constantine Georgiou    schedule 17.04.2018