2

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

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

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

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

我得到一个奇怪的结果:

包含意外字符的错误消息

我该如何解决这个问题?

4

1 回答 1

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 函数和字符串之间交互的更多信息。我向您推荐与向其他人所做的相同的事情:

  • 分别为你的字符和字符串坚持wchar_t和。std::wstring
  • 始终调用WWindows API 函数的变体,包括LoadStringWMessageBoxW.
  • 确保在包含任何 Windows 标头之前或在项目的构建设置中定义了UNICODE和宏。_UNICODE
于 2013-03-22T23:24:59.113 回答