Question

I created an RC file which contains a string table, I would like to use some special

characters: ö ü ó ú ő ű á é. so I save the string with UTF-8 encoding.

But when I call in my cpp file, something like this:

LoadString("hu.dll", 12, nn, MAX_PATH);

I get a weird result:

Error message with unexpected characters

How do I solve this problem?

Était-ce utile?

La solution

As others have pointed out in the comments, the Windows APIs do not provide direct support for UTF-8 encoded text. You cannot pass the MessageBox function UTF-8 encoded strings and get the output that you expect. It will, instead, interpret them as characters in your local code page.

To get a UTF-8 string to pass to the Windows API functions (including MessageBox), you need to use the MultiByteToWideChar function to convert from UTF-8 to UTF-16 (what Windows calls Unicode, or wide strings). Passing the CP_UTF8 flag for the first parameter is the magic that enables this conversion. Example:

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;                    
}

Then, once you have a wide string, you will explicitly call the wide-string variant of the MessageBox function, MessageBoxW.

However, if you only need to support Windows and not other platforms that use UTF-8 everywhere, you will probably have a much easier time sticking exclusively with UTF-16 encoded strings. This is the native Unicode encoding that Windows uses, and you can pass these types of strings directly to any of the Windows API functions. See my answer here to learn more about the interaction between Windows API functions and strings. I recommend the same thing to you as I did to the other guy:

  • Stick with wchar_t and std::wstring for your characters and strings, respectively.
  • Always call the W variants of Windows API functions, including LoadStringW and MessageBoxW.
  • Ensure that the UNICODE and _UNICODE macros are defined either before you include any of the Windows headers or in your project's build settings.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top