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



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

好吧,主要是:如何使用多字节打印西里尔文?

谢谢大家!

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上。

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

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

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

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

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

// From Unicode UTF-16 to Cyrillic code page
std::string cyrillic_text = cyrillic_encode(wch);
// Show Cyrillic-encoded "MBCS" text
m_wndOutputBuild.AddString(cyrillic_text.c_str());

此外,正如@IInspectable在注释中正确指出的那样,请考虑在转换函数中添加适当的错误检查代码。事实上,一般来说,可能存在无法用西里尔文正确编码的 UTF-16 文本,因为后者是前者的适当子集。

最新更新