Как отмечали другие в комментариях, API-интерфейсы Windows не обеспечивают прямую поддержку текста в кодировке UTF-8. Вы не можете передать функции MessageBox
строки в кодировке UTF-8 и получить ожидаемый результат. Вместо этого он будет интерпретировать их как символы вашей локальной кодовой страницы.
Чтобы получить строку UTF-8 для передачи функциям API Windows (включая MessageBox
), необходимо использовать MultiByteToWideChar
для преобразования из UTF-8 в UTF-16 (то, что Windows называет Unicode или широкими строками). Передача флага CP_UTF8
для первого параметра — это волшебство, которое включает это преобразование. Пример:
std::wstring ConvertUTF8ToUTF16String(const char* pszUtf8String)
{
// Determine the size required for the destination buffer.
const int length = MultiByteToWideChar(CP_UTF8,
0, // no flags required
pszUtf8String,
-1, // automatically determine length
nullptr,
0);
// Allocate a buffer of the appropriate length.
std::wstring utf16String(length, L'\0');
// Call the function again to do the conversion.
if (!MultiByteToWideChar(CP_UTF8,
0,
pszUtf8String,
-1,
&utf16String[0],
length))
{
// Uh-oh! Something went wrong.
// Handle the failure condition, perhaps by throwing an exception.
// Call the GetLastError() function for additional error information.
throw std::runtime_error("The MultiByteToWideChar function failed");
}
// Return the converted UTF-16 string.
return utf16String;
}
Затем, когда у вас будет широкая строка, вы явно вызовете вариант широкой строки функции MessageBox
, MessageBoxW
.
Однако, если вам нужно поддерживать только Windows, а не другие платформы, которые повсеместно используют UTF-8, вам, вероятно, будет намного проще придерживаться исключительно строк в кодировке UTF-16. Это собственная кодировка Unicode, которую использует Windows, и вы можете передавать эти типы строк напрямую в любую из функций Windows API. См. мой ответ здесь, чтобы узнать больше о взаимодействии между функциями Windows API и строками. Я рекомендую вам то же самое, что и другому парню:
- Используйте
wchar_t
и std::wstring
для символов и строк соответственно.
- Всегда вызывайте
W
вариантов функций Windows API, включая LoadStringW
и MessageBoxW
.
- Убедитесь, что макросы
UNICODE
и _UNICODE
определены либо до включения каких-либо заголовков Windows, либо в настройках сборки вашего проекта.
person
Cody Gray
schedule
22.03.2013
rc.exe
понимают UTF-8. Вам нужно использовать#pragma code_page(65001)
в файле .rc (верхнего уровня). Строковый ресурс будет храниться как UTF-16, поэтому вам нужно убедиться, что вы используетеLoadStringW
иMessageBoxW
(или компилируете сUNICODE
). - person jamesdlin   schedule 23.03.2013