将三个字母的语言代码转换为语言标识符(LANGID)

时间:2009-10-13 12:23:25

标签: c++ winapi internationalization

在Win32 API中是否有某种方法可以将指定GetLocaleInfo()的{​​{1}}返回的三字母语言代码转换为相应的LOCALE_SABBREVLANGNAMELANGID?也就是说,与LCID通常做的“反向”?

我要做的是解析资源DLL使用的语言类型,到目前为止,没有触及任何关于DLL的内容,使用格式为GetLocaleInfo()的dll名称,其中{ {1}}是一个三字母语言代码,似乎是最简单的方法,假设存在这样的函数。

如果这不容易做到,我想计划B是给我们的语言DLL一个版本信息资源,在那里指定他们各自的文化,然后在应用程序中,阅读他们使用的文化。

3 个答案:

答案 0 :(得分:2)

不幸的是,没有直接的Win32 API为您提供了一个给出3个字母缩写的LANGID。

看起来CLanguageSupport是您的朋友today :-)它已经实现了您的计划B,以根据版本信息资源的内容查找LANGID。

您正在寻找的代码是函数

LANGID CLanguageSupport::GetLangIdFromFile(LPCTSTR pszFilename)

当然,缺点是您可能在版本信息和DLL名称之间不匹配。但是你会在测试中很快发现它。如果你让像appTranslator这样的工具为你创建DLL,那么你肯定是安全的。

答案 1 :(得分:1)

您可以使用EnumSystemLocales()枚举已安装的区域设置并自行构建地图。我在应用程序初始化期间在我之前写过的一个服务中执行此操作,到目前为止它已经运行良好。

在这种情况下,我建议使用 Plan B 。我通常避免将编码内容编入文件名。如果没有其他原因,使用3个字符ISO-639变体并不完美,除非您严格指定所使用的变体 - ISO-639-2/B, ISO-639-2/TISO-639-3

如果您需要提供特定于语言环境的变体,那么您应该仔细查看RFC3066。基本上,您需要指定语言和国家/地区代码,在某些情况下,还需要指定区域代码。在任何情况下,LCID都包含了所有这些优点。

我不完全确定的一件事是资源信息中的langID是否是完整的LCID。 VERSIONINFO引用中列出的代码是LCID,因此我会尝试在VERSIONINFO标头中使用LCID。如果没有,您始终可以将信息作为字符串包含在字符串块中。

答案 2 :(得分:0)

您可以通过GetLocaleInfo()为{em> LCType 参数调用LOCAL_RETURN_NUMBER|LOCALE_ILANGUAGE来获取LangID,就像您通过LOCALE_SABBREVLANGNAME获取三个字母的ISO代码一样。通过将相同的 lcid 传递给此函数,您可以使用ISO代码存储相应的LangID。

请注意,MSDN表示不应在Vista及更高版本上使用LOCALE_ILANGUAGE LOCALE_SLANG,但我认为该评论不适用于LOCALE_ILANGUAGELOCALE_RETURN_NUMBER的使用

随着项目的发展,您可能会为每种语言生成多个本地化文件。因此,我建议您将本地化文件存储在以该语言命名的子目录中。 Microsoft使用以LangID命名的目录,例如“1033”作为英语资源目录。我认为使用三个字母的代码会比较友好,比如“ENU \ name.dll”。在任何情况下,子目录都是一个简单的解决方案,并且希望不会像更改目标文件名那样使构建过程复杂化。