我可以从语言偏好中获取代码页吗
Can I get a code page from a language preference?
Windows似乎至少跟踪了"当前区域设置"的四个维度:http://www.siao2.com/2005/02/01/364707.aspx
- 默认用户区域设置
- 默认系统区域设置
- 默认用户界面语言
- 默认输入区域设置
我的大脑很痛,只是想知道四个不同的地方对什么有用。。。
然而,我不了解代码页和区域设置(或LCID
,或Language ID)之间的关系,所有这些似乎都是不同的(例如,日语(Japan)是LANGID=0x411位置代码1,但日本的代码页是932)。
在Unicode和窄字符串之间转换时,我如何配置我们的应用程序以使用用户所需的语言作为默认MBCS目标
也就是说,我们曾经是一个MBCS应用程序。然后我们切换到Unicode。在英语中运行良好,但在亚洲语言中失败了,这显然是因为Windows转换函数WideCharToMultiByte
和MultiByteToWideChar
采用了一个明确的代码页(而不是区域设置ID或语言ID),可以设置为CP_ACP
(默认为ANSI代码页),但似乎没有"默认为用户默认界面语言的代码页"的值。
我的意思是,这是一些非常复杂的废话。"当前语言"的四个独立维度,三种不同的标识符类型,以及C库和C++标准库的(不同的)字符串标识符。
在我们以前的MBCS构建中,磁盘I/O和用户I/O工作正常:所有内容都保留在DEFAULT SYSTEM LOCALE(Windows XP术语:"非Unicode程序的语言")中。但现在,在我们的UNICODE构建中,所有东西都试图使用"C"作为区域设置,而文件I/O无法将UNICODE正确地转换为用户的区域设置,反之亦然。
我们希望使用当前用户语言的代码页写出文本文件(当缩小时)。当读入时,当前用户语言的代码页应该转换回UNICODE。
救命!!!
澄清:理想情况下,我希望使用MUI语言代码页,而不是操作系统默认代码页。GetACP()返回系统默认代码页,但我不知道有一个函数会返回用户选择的MUI语言(如果没有指定/安装MUI,它会自动恢复为系统默认语言)
我同意Jon Trauntvein的评论,GetACP
函数确实反映了控制面板中用户的语言设置。此外,根据您提供的"整理一切"博客链接,DEFAULT USER INTERFACE LANGUAGE是Windows用户界面将使用的语言,与程序使用的语言不同。
但是,如果您真的想使用DEFAULT USER INTERFACE LANGUAGE,那么您可以通过调用GetUserDefaultUILanguage
来获得它,然后您可以使用下表将语言id映射到代码页。语言标识符和区域
您也可以使用GetLocaleInfo
函数来进行映射,但首先您必须将从GetUserDefaultUILanguage
获得的语言id转换为区域设置id,我认为您将获得代码页的名称,而不是数值,但您可以尝试并查看。
如果您只想配置一个区域设置对象以使用当前选择的区域设置,那么您应该能够执行以下操作:
std::locale loc = std::locale("");
您还可以使用Win32::GetACP()函数访问窗口中的当前代码页。以下是我在字符串类中实现的一个示例,用于将多字节字符附加到unicode字符串:
void StrUni::append_mb(char const *buff, size_t buff_len)
{
UINT current_code_page = ::GetACP();
int space_needed;
if(buff_len == 0)
return;
space_needed = ::MultiByteToWideChar(
current_code_page,
MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
buff,
buff_len,
0,
0);
if(space_needed > 0)
{
reserve(this->buff_len + space_needed + 1);
MultiByteToWideChar(
current_code_page,
MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
buff,
buff_len,
storage + this->buff_len,
space_needed);
this->buff_len += space_needed;
terminate();
}
}
只需使用CW2A()或CA2W(),它将为您使用当前系统区域设置(或用于非Unicode应用程序的语言)进行转换。
FWIW,这就是我最终要做的:
#define _CONVERSION_DONT_USE_THREAD_LOCALE // force CP_ACP *not* CP_THREAD_ACP for MFC CString auto-conveters!!!
- 在应用程序启动中,构造所需的区域设置:
m_locale(FStringA(".%u", GetACP()).GetString(), LC_CTYPE)
- 强制其同意GetACP():
// force C++ and C libraries based on setlocale() to use system locale for narrow strings
m_locale = ::std::locale::global(m_locale); // we store the previous global so we can restore before termination to avoid memory loss
这使我能够相对理想地使用MFC的内置窄<->CString中的宽转换,以便在转换到当前语言环境的MBCS字符串或从当前语言环境转换MBCS字符串时自动使用用户的默认语言。
注:m_locale
是类型::std::locale
- 我无法获取以下代码的输出
- 如何在 WSL 上获取 VS 代码以调试我的C++代码?
- 从两个 4x64 位整数数组中获取取模
- 如何在 Linux 中获取本地代码页?
- 在 JS 中通过 Emscripten 获取 SDL 代码C++时遇到问题
- 在 for 循环和变量值中获取此代码的多个错误;
- TCL文件无法获取通过代码设置的环境变量
- 获取X509代码签名证书的序列号,以不受管理的C/C 签名
- 节点 js 我可以从用 C++ 编写的 windows 命令行应用程序中获取退出代码
- 获取 QT 代码的普通C++实现
- 如何从 UTF-8 字符串的每个字符中获取 UNICODE 代码
- 从WM_char消息获取扫描代码
- 获取以下 c++ 代码的链接器错误
- 从std::thread获取返回代码
- 如何使用MsiGetProductInfo和MsiOpenDatabase获取升级代码
- 获取错误代码 998 尝试从命名管道读取时对内存位置的访问无效
- 我无法使用 libcurl 获取 http 代码 404
- C++获取编译代码中使用的代码部分的大小
- 自动获取某些代码段的浮点运算计数的方法
- 获取 html 代码时出错