我希望在 Windows 桌面 (Win32/MFC) 应用程序中从 ASCII 迁移到 UTF-8。这与通常迁移到 UTF-16 不同。这个想法是,需要进行的更改更少,并且与以 UTF-8 通信的外部系统交互将需要更少的工作。
问题在于,资源文件中的对话框中的静态控件和按钮仅显示其汉字文本的第一个字符。资源文件使用 UTF-8 应该可以正常工作吗?
UTF-8 字符串似乎可以从资源文件中的字符串表中正确读取和显示,但不能直接在对话框本身上读取和显示文本。
我有:
在任何地方使用 UTF-8 意味着 std::string、CStringA 和 -A Win32 函数通过使用“高级/字符集”值“未设置”来隐式实现。此外,资源文件采用 UTF-8 格式,包括带有文本、字符串表等的对话框。如果我将其设置为“使用 Unicode 字符集”,我的理解是 UTF-16 和 -W 函数将成为默认值 -历史上支持 Unicode 的标准 Windows 方式。
该编译指示似乎有效,因为 Visual Studio 中的资源编辑器不会将 .rc 文件破坏为 UTF-16LE。此外,清单似乎可以正常工作,因为 MessageBox() (MessageBoxA) 函数可以正确显示字符串表中的文本。如果没有清单,MessageBox() 将显示问号。
TCHAR buffer[512];
LoadString(hInst, IDS_TESTKANJI, buffer, 512 - 1);
MessageBox(hWnd, buffer, _T("Caption"), MB_OK);
如果我将字符编码设置为“使用 Unicode 字符集”,一切似乎都按预期工作 - 所有字符都会显示。
我怀疑编码是UTF-8(.rc文件) - > UTF-16(内部表示) - > ASCII(对话框文本加载?),遇到UTF-16表示中的空字符,并在之后停止读取第一个字符。
如果我使用字符串表中的文本在静态控件上调用 SetDlgItemText(),静态控件将正确显示所有字符:
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
TCHAR buffer[512];
LoadString(hInst, IDS_TESTKANJI, buffer, 512 - 1);
SetDlgItemText(hDlg, IDC_STATIC, buffer);
...
在对话框上显示 UTF-8 文本的当前答案似乎是手动 - 在代码中 - 使用 SetDlgItemText() 等函数和 UTF-8 字符串设置文本,而不是依赖于对话框创建的资源加载代码本身。使用 UTF-8 清单,调用 -A 函数,它们将很好地设置 UTF-8 文本。
还可以显式调用-W函数,并在调用之前转换UTF-8 -> UTF-16。请参阅使用多字节字符集的 MFC 应用程序中的 UTF-8 文本。
另请参阅Microsoft CreateDialogIndirectA 宏 (winuser.h) 与此相关的异常明确:“对话框模板中的所有字符串,例如对话框和按钮的标题,必须是 Unicode 字符串。”