从Windows资源(RC)文件存储和检索UTF-8字符串

时间:2013-03-22 22:41:21

标签: c++ winapi unicode utf-8 rc

我创建了一个包含字符串表的RC文件,我想使用一些特殊的

字符:öüóúőűáé。所以我用UTF-8编码保存字符串。

但是当我调用我的cpp文件时,就像这样:

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

我得到了一个奇怪的结果:

Error message with unexpected characters

如何解决这个问题?

1 个答案:

答案 0 :(得分:8)

正如其他人在评论中指出的那样,Windows API不提供对UTF-8编码文本的直接支持。您无法传递MessageBox函数UTF-8编码的字符串并获得您期望的输出。相反,它会将它们解释为本地代码页中的字符。

要将UTF-8字符串传递给Windows API函数(包括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编码的字符串。这是Windows使用的本机Unicode编码,您可以将这些类型的字符串直接传递给任何Windows API函数。有关Windows API函数与字符串之间的交互的详细信息,请参阅my answer here。我和你对另一个人的推荐给你的东西一样:

  • 分别为您的字符和字符串添加wchar_tstd::wstring
  • 始终调用Windows API函数的W变体,包括LoadStringWMessageBoxW
  • 确保在包含任何Windows标头之前或在项目的构建设置中定义了UNICODE_UNICODE宏。