在某些Windows 10版本中(从2018年4月开始,内部使用,也称为“正常” 1903年),有一个名为“ Beta:使用Unicode UTF-8进行全球语言支持”的新选项。
您可以通过转到“设置”,然后查看以下选项: 所有设置->时间和语言->语言->“管理语言设置”
这是它的样子:
选中此复选框后,我观察到一些异常情况(如下所示),我想知道此复选框的作用以及为什么发生以下情况。
在Visual Studio 2019中创建一个全新的Windows Froms应用程序。在主窗体上,指定Paint
偶数处理程序,如下所示:
private void Form1_Paint(object sender, PaintEventArgs e)
{
Font buttonFont = new Font("Webdings", 9.25f);
TextRenderer.DrawText(e.Graphics, "0r", buttonFont, new Point(), Color.Black);
}
运行程序,如果未选中此复选框,将显示以下内容:
但是,如果您选中复选框(并按要求重新启动),则更改为:
您可以在Wikipedia上查找Webdings字体。根据给定的字符表,这两个字符的代码为"\U0001F5D5\U0001F5D9"
。如果我使用它们而不是"0r"
,则 with 复选框已选中,但 without 复选框已选中,现在看起来像这样:
我想找到一个始终有效的解决方案,无论该复选框处于选中状态还是未选中状态,该解决方案都是无偿的。
可以做到吗?
答案 0 :(得分:2)
您可以在ProcMon中看到它。
似乎在REG_SZ
中设置了ACP
,MACCP
和OEMCP
的值HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage
到65001
。
我不确定,但是可能与gAnsiCodePage
读取的KernelBase.dll
中的变量GetACP
有关。如果您真的想,则可以 动态地为您的程序更改它,而无需考虑系统设置如何通过动态反汇编GetACP
来查找指令序列读取gAnsiCodePage
并获取指向它的指针,然后直接更新该变量。
(实际上,我see references to an undocumented function named SetCPGlobal
可以完成这项工作,但是在我的系统上找不到该功能。不确定它是否仍然存在。)
答案 1 :(得分:2)
大多数Windows C API有两种不同的变体:
Microsoft官方建议不要使用“ A”版本,而是要确保您的代码始终使用“ W”变体。这样一来,无论用户的国家/语言配置为什么,您都应该获得一致的行为。
但是,看起来该复选框所做的不只是一件事情。很明显,应该将“ ANSI代码页”更改为65001,这表示UTF-8。看起来它也在改变字体渲染,使其更像Unicody。
我建议您检测是否GetACP() == 65001,然后绘制字符串的Unicode版本,否则绘制旧的“ 0r”版本。我不确定您是如何从.NET做到这一点的...
答案 2 :(得分:1)
请看这个问题,看看它在启用时解决了什么问题:How to save to file non-ascii output of program in Powershell?
我还发现 Ghisler 写的解释很有帮助 (source):
<块引用>如果选中此选项,Windows 将使用代码页 65001 (Unicode UTF-8) 而不是像 1252 (Western Latin1) 这样的本地代码页 所有纯文本文件。优点是在例如创建的文本文件 俄语语言环境也可以在其他语言环境中阅读,例如西方或 欧洲中部。缺点是只有 ANSI 的程序(大多数较旧的 程序)将显示垃圾而不是重音字符。
我在这里留下了两种启用它的方法,我认为它们对很多用户都有帮助:
intl.cpl
Administrative
标签Change system locale
按钮。Beta: Use Unicode UTF-8 for worldwide language support
或者通过 reg
文件:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage]
"ACP"="65001"
"OEMCP"="65001"
"MACCP"="65001"