只有当我没有英文string表时,LoadString才起作用

我希望能够以编程方式修改应用程序的语言,或者至less使用控制面板 – >区域和语言选项 – >格式中指定的语言。

如果我添加一个英文string表,做一个法语和德语的副本,并删除英文的一个,我可以编程方式加载法语和德语string之间切换。 如果我保留英文版,无论如何,当我尝试加载德文或法文时,英文string会被加载。

我认为这是一个资源加载程序错误,如果资源加载器忽略SetThreadLocale,如果它find一个与windows ui语言(例如Windows资源pipe理器菜单的语言)相同语言的string表。

我试图将控制面板 – >区域和语言选项 – >格式更改为法语,但没有任何效果。 资源编辑器显示没有附加语言的法语string表,但我的程序仍然总是加载英文string。 将此更改复制到系统帐户也不起作用。

这是我试过的代码:

#include "stdafx.h" #include <iostream> #include "windows.h" // this should go to stdafx.h #include "resource.h" // this should not go to stdafx.h using namespace std; int _tmain(int argc, _TCHAR* argv[]) { // 1036 = french, 1031 = german SetThreadLocale(MAKELCID(1036, SORT_DEFAULT)); const int maxSize = 100; wchar_t c[maxSize]; LoadString(GetModuleHandle(NULL), IDS_STRING101, c, maxSize); std::cout << c; return 0; } 

这是一个错误的,不完整的解释(在方法2的后半部分)。 在那里提出的第二个解决方法是,只使用中立的string表是没有用的,因为我有单独的葡萄牙 – 葡萄牙和葡萄牙 – 巴西的string表。

提出的第一个解决方法不起作用。 用下面的代码,我得到错误1814。

 HRSRC r = FindResource( GetModuleHandle(NULL), MAKEINTRESOURCE(IDS_STRING101), RT_STRING); DWORD e = GetLastError(); 

所以我该怎么做 ? 什么是这个奇怪的“错误”的解释?

后期编辑:

经过一些testing后,我发现:

  1. GetThreadLocale()返回在“控制面板” – >“区域和语言选项” – >“格式”中设置的内容。
  2. 资源加载程序错误本质上是,如果我的程序也有美国英文资源,这些资源将被加载,无论在格式设置什么。 如果它没有美国英语资源,将使用格式设置的语言。
  3. 如果我有法语(中性)和德语(中性)string表格,并且将格式设置为法语(法国),则会加载德语string。 如果我添加一个英文(中性)string表,英文string被加载。 所以,中性文化回退不适用于格式设置。
  4. 如果我添加一个中性string表,即使我有另一个英文(中性)或英文(美国)string表,也会使用这个表。

Solutions Collecting From Web of "只有当我没有英文string表时,LoadString才起作用"

从MSDN直接选择本地化资源(包括FindResource的搜索顺序)的详细说明: 多语言资源

编辑:但是,从我的经验(至少在Windows XP)的FindResource该页面上详细搜索顺序没有描述实际的行为。 实际行为似乎是:

  1. LANG_NEUTRAL资源
  2. Lang和SubLang匹配UI语言Lang和SubLang的资源
  3. Lang匹配UI语言的资源Lang和资源Sublang是中立的
  4. Lang和SubLang匹配语言环境语言Lang和SubLang的资源
  5. Lang匹配locale语言的资源Lang和资源Sublang是中立的
  6. LANGID数值最低的资源

注意:我没有任何资料来验证这个列表,所以如果有人可以更新或更正任何内容,请这样做。

编辑:为了理解这种行为,重要的是要认识到“语言环境”和“UI语言”之间的区别,这里解释: NLS术语 。 FindResource函数语言选择主要基于UI语言,而不是“区域和语言选项”(即“语言环境”设置,与调用SetThreadLocale())相同的“区域选项”设置。

据我所知,区域设置或SetThreadLocale()影响FindResource()的原因是因为@Kirill V. Lyadvinsky在这里的一个答案中描述的异常情况,在Michael Kaplan的博客中有更详细的解释。

在代码中干净而确定地设置FindResource的语言只能在Vista中使用新的函数“SetThreadUILanguage”。 你看到的每一个地方,而是使用SetThreadLocale将有黑客使其工作和/或有问题时,UI语言改变(即:外语Windows安装)。

你正在运行Vista或Windows 7? 如果是这样的话SetThreadLocale不起作用(即使它返回TRUE,叹气),你必须使用SetThreadUILanguage

我刚刚完成了一个已翻译成7种不同语言的WTL应用程序,用户可以切换语言,而不会出现所描述的问题。 我在XP上使用SetThreadLocale ,在Vista / 7上使用SetThreadLocale

更多信息:

http://social.msdn.microsoft.com/forums/en-US/windowscompatibility/thread/d3a44b1c-900c-4c64-bdf8-fe94e46722e2/

http://www.curlybrace.com/words/2008/06/10/setthreadlocale-and-setthreaduilanguage-for-localization-on-windows-xp-and-vista/

这里的问题是,如果线程语言环境与当前选择的用户语言环境相同,则系统的资源加载器默认使用语言ID 0(中性)。 如果所需的资源被定义为中性语言,那么这个值将被返回。 否则,将枚举所有语言资源(按照语言ID顺序),并返回第一个匹配的资源ID – 不管其语言如何。

控制资源的唯一方法是为每种语言使用单独的资源DLL。