utf-8(波兰语)无法正常工作的可视化
Visualisation of uft-8 (Polish) not working properly
我的软件支持多种语言(英语、德语、波兰语、俄语……)。
出于这个原因,我有一些特定语言的文件,其中包含特定语言的对话框文本(编码为 UTF-8)。
在我的 mfc 应用程序中,我打开并读取这些文件并将文本插入到我的 AfxMessageBoxes 和其他 UI-Windows 中。
// Get the codepage number. 65001 = UTF-8
// In the real code this is a parameter in the function I call (just for clarification)
LANGID languageID = 65001;
TCHAR szCodepage[10];
GetLocaleInfo (MAKELCID (languageID, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, szCodepage, 10);
int nAnsiCodePage = _ttoi (szCodepage);
// Open the file
CFile file;
CString filename = getName();
if (!file.Open(FileName, CFile::modeRead, NULL))
{
//Check if everything is fine, else break
}
// Read the file
CString inString;
int len = file.GetLength ();
UINT n = file.Read (inString.GetBuffer(len), len);
inString.ReleaseBuffer ();
int size = MultiByteToWideChar (CP_ACP, 0, strAllItems, -1, NULL, 0);
WCHAR *ubuf = new WCHAR[size + 1];
MultiByteToWideChar ((UINT) nAnsiCodePage, (nAnsiCodePage == CP_UTF8 ?
0 : MB_PRECOMPOSED), inString, -1, ubuf, (int) size);
outString = ubuf;
file.Close ();
结果:
此机制适用于俄语和德语的特殊字母,但不适用于波兰语。我已经查看了 utf-8 站点 (http://www.utf8-chartable.de/unicode-utf8-table.pl?number=1024),波兰字符是其中的一部分。
我还检查了我的 CString 的十六进制值,一切似乎都没有问题,但它没有以正确的方式可视化。只是为了测试,我将使用的代码页从 utf-8 更改为 1250(东欧,包括波兰语),但它也没有用。
我究竟做错了什么?
编辑:
当我使用:
MultiByteToWideChar (CP_UTF8 , 0, inString, -1, ubuf, (int) size);
十六进制值缩短为 "best match" 个字母。这意味着我的结果是:mezczyzna
我正在使用 windows 7 并选择了英语。
嗯,你有两个选择:
一个。使您的应用程序成为 Unicode。你不告诉我们它是否真的是,但我断定它不是。从技术上讲,这是“最佳”解决方案,但可能需要付出很多努力,甚至可能根本不可行(例如使用 non-Unicode 库)。
乙。如果您的应用是 non-Unicode,则有一些限制:
- 您的应用程序只能使用 non-unicode API 和消息正确显示 one 代码页,不幸的是,这不能针对每个应用程序进行设置,它在 [=36= 中全局设置] 与 "Language for non-Unicode programs" 选项,并且需要重新启动。
- 要正确显示包含不在默认代码页中的字符的字符串,您需要将它们转换为 Unicode 并明确使用 "wide" 版本的 API 和消息,以显示它们(例如 MessageBoxW()
)。有点繁琐,但是可以,如果操作只涉及少量控件。
您正在使用的机器有一些西欧语言,如 "Language for non-Unicode programs",我得出这个结论是因为 "This mechanism is working fine for special letters of russian and german" 和 "Using MessageBoxA(0, "mężczyzna", 0, 0)不起作用”,如您所说(尽管我对俄语完全不确定,因为它是不同的代码页)。
除此之外,正如 IInspectable 所说,int size = MultiByteToWideChar (CP_ACP, 0, strAllItems, -1, NULL, 0);
根本没有意义,因为已知该字符串是 UTF-8,而不是默认代码页。如果您的文件包含 UTF-8 BOM header,您可能还需要删除它。
我的软件支持多种语言(英语、德语、波兰语、俄语……)。
出于这个原因,我有一些特定语言的文件,其中包含特定语言的对话框文本(编码为 UTF-8)。
在我的 mfc 应用程序中,我打开并读取这些文件并将文本插入到我的 AfxMessageBoxes 和其他 UI-Windows 中。
// Get the codepage number. 65001 = UTF-8
// In the real code this is a parameter in the function I call (just for clarification)
LANGID languageID = 65001;
TCHAR szCodepage[10];
GetLocaleInfo (MAKELCID (languageID, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, szCodepage, 10);
int nAnsiCodePage = _ttoi (szCodepage);
// Open the file
CFile file;
CString filename = getName();
if (!file.Open(FileName, CFile::modeRead, NULL))
{
//Check if everything is fine, else break
}
// Read the file
CString inString;
int len = file.GetLength ();
UINT n = file.Read (inString.GetBuffer(len), len);
inString.ReleaseBuffer ();
int size = MultiByteToWideChar (CP_ACP, 0, strAllItems, -1, NULL, 0);
WCHAR *ubuf = new WCHAR[size + 1];
MultiByteToWideChar ((UINT) nAnsiCodePage, (nAnsiCodePage == CP_UTF8 ?
0 : MB_PRECOMPOSED), inString, -1, ubuf, (int) size);
outString = ubuf;
file.Close ();
结果:
此机制适用于俄语和德语的特殊字母,但不适用于波兰语。我已经查看了 utf-8 站点 (http://www.utf8-chartable.de/unicode-utf8-table.pl?number=1024),波兰字符是其中的一部分。
我还检查了我的 CString 的十六进制值,一切似乎都没有问题,但它没有以正确的方式可视化。只是为了测试,我将使用的代码页从 utf-8 更改为 1250(东欧,包括波兰语),但它也没有用。
我究竟做错了什么?
编辑:
当我使用:
MultiByteToWideChar (CP_UTF8 , 0, inString, -1, ubuf, (int) size);
十六进制值缩短为 "best match" 个字母。这意味着我的结果是:mezczyzna
我正在使用 windows 7 并选择了英语。
嗯,你有两个选择:
一个。使您的应用程序成为 Unicode。你不告诉我们它是否真的是,但我断定它不是。从技术上讲,这是“最佳”解决方案,但可能需要付出很多努力,甚至可能根本不可行(例如使用 non-Unicode 库)。
乙。如果您的应用是 non-Unicode,则有一些限制:
- 您的应用程序只能使用 non-unicode API 和消息正确显示 one 代码页,不幸的是,这不能针对每个应用程序进行设置,它在 [=36= 中全局设置] 与 "Language for non-Unicode programs" 选项,并且需要重新启动。
- 要正确显示包含不在默认代码页中的字符的字符串,您需要将它们转换为 Unicode 并明确使用 "wide" 版本的 API 和消息,以显示它们(例如 MessageBoxW()
)。有点繁琐,但是可以,如果操作只涉及少量控件。
您正在使用的机器有一些西欧语言,如 "Language for non-Unicode programs",我得出这个结论是因为 "This mechanism is working fine for special letters of russian and german" 和 "Using MessageBoxA(0, "mężczyzna", 0, 0)不起作用”,如您所说(尽管我对俄语完全不确定,因为它是不同的代码页)。
除此之外,正如 IInspectable 所说,int size = MultiByteToWideChar (CP_ACP, 0, strAllItems, -1, NULL, 0);
根本没有意义,因为已知该字符串是 UTF-8,而不是默认代码页。如果您的文件包含 UTF-8 BOM header,您可能还需要删除它。