如何在MFC多字节应用程序中显示西里尔文本?

时间:2018-03-09 11:08:23

标签: c++ mfc cyrillic multibyte

我是C ++和MFC的新手。主要问题是我有一个需要翻译成俄语的MFC项目。我看到最好的选择是将项目更改为Unicode,但我不能,因为它是一个巨大的项目,当我改变时,我收到超过4000个错误。稍后我们将所有代码传递给Unicode,但是现在我只需要在按钮和CListBox上显示Cyrillic。

嗯,主要的是:如何用Multibyte打印Cyrillic?

谢谢你们!

PD:对不起,我会更加明确我的尝试:

使用俄语语言环境:

setlocale(LC_ALL, "russian_russia.1251");
setlocale(LC_CTYPE, "rus");

但没有工作。显示问号。

此外,我尝试使用功能WideCharToMultiByte进行转换。但是显示似乎编码错误的字符。

std::string utf8_encode(const std::wstring &wstr)
{
    if (wstr.empty()) return std::string();
    int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
    std::string strTo(size_needed, 0);
    WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
    return strTo;
}

    wchar_t* wch = L"Привет";

    std::string ch = utf8_encode(wch);

    m_wndOutputBuild.AddString(ch.c_str()); //OUTPUT Привет

PD2:现在我打电话给这个

setlocale(LC_ALL, "russian_russia.1251");

std::wstring wch = L"Привет";

std::string ch = encode_1251(wch);

m_wndOutputBuild.AddString(ch.c_str()); //OUTPUT Ïðèâåò

和功能:

std::string encode_1251(const std::wstring &wstr)
{
    if (wstr.empty()) return std::string();
    int size_needed = WideCharToMultiByte(1251, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
    std::string strTo(size_needed, 0);
    WideCharToMultiByte(1251, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
    return strTo;
}

我发现Windows-1251将这样的CP放在WideCharToMultiByte here上。

1 个答案:

答案 0 :(得分:2)

profiler函数中,将Unicode UTF-16字符串转换为utf8_encode时,您将std::string传递给CP_UTF8。然后,您获取返回的UTF-8 WideCharToMultiByte,并通过std::string将其传递给.c_str()方法。

但是,如果您的应用程序位于MBCS Cyrillic中,则应将UTF-16转换为西里尔语代码页,而不是UTF-8,并将您在西里尔语代码页中编码的字符串传递给您的MFC类方法,如CListBox::AddString

换句话说,您可能希望将CListBox::AddString函数替换为utf8_encode函数,该函数将UTF-16文本作为输入,并将其转换为您的西里尔语代码页:

cyrillic_encode

然后将返回的字符串传递给感兴趣的MFC类方法,例如:

// Convert from Unicode UTF-16 to Cyrillic code page
std::string cyrillic_encode(const std::wstring &utf16)

此外,正如@IInspectable在评论中正确指出的那样,请考虑在转换函数中添加适当的错误检查代码。实际上,一般情况下,可能存在不能在西里尔语中正确编码的UTF-16文本,因为后者是前者的适当子集。