【问题标题】:Storing and retrieving UTF-8 strings from Windows resource (RC) files从 Windows 资源 (RC) 文件存储和检索 UTF-8 字符串
【发布时间】:2013-03-12 22:31:07
【问题描述】:

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

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

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

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

我得到一个奇怪的结果:

我该如何解决这个问题?

【问题讨论】:

  • 哦,还有其他匈牙利人。你好。为您固定英语(达到一定水平)。
  • 从我对 Windows 的记忆中,它本身不支持 UTF8。它要么是一些特定的代码页,要么是 UTF16。希望这会有所帮助。
  • 它可能在 UTF-8 中读取就好了。当您尝试在窗口中显示它时,问题就来了。 Windows 代码期望它采用不同的编码。
  • @user1601401 您不会更改对话编码,但您必须为其提供以本地代码页(“A”API)或 UTF16(“W”)API 编码的字符串.无论哪种情况,您都必须将 UTF8 字符串转换为 Windows 可以理解的内容。
  • rc.exe 的现代版本理解 UTF-8。您需要在(顶级).rc 文件中使用#pragma code_page(65001)。字符串资源将存储为 UTF-16,因此您需要确保使用 LoadStringWMessageBoxW(或使用 UNICODE 编译)。

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


【解决方案1】:

正如其他人在 cmets 中指出的那样,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 函数。请参阅my answer here 以了解有关 Windows API 函数和字符串之间交互的更多信息。我向您推荐与向其他人所做的相同的事情:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-18
    • 1970-01-01
    • 2020-10-08
    • 2014-07-26
    • 1970-01-01
    • 2011-11-10
    • 2016-03-17
    • 2018-09-30
    相关资源
    最近更新 更多