如果我添加一个英文字符串表,制作法语和德语副本,并删除英语字符串,我可以编程方式在加载法语和德语字符串之间切换.
如果我保留英文副本,无论如何,当我尝试加载德语或法语时,英语字符串都会被加载.
我认为这是一个资源加载器错误,并且资源加载器忽略SetThreadLocale,如果它找到与windows ui语言相同语言的字符串表(例如,Windows资源管理器菜单的语言).
我试图更改控制面板 – >区域和语言选项 – >格式化为法语,但没有效果.资源编辑器显示没有附加语言的法语字符串表,但我的程序仍然总是加载英语字符串.将此更改复制到系统帐户也不起作用.
这是我尝试过的代码:
#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; }
Here是一个错误的,不完整的解释(在方法2的后半部分).在那里提出的第二种解决方法,只使用相对于中性的字符串表是没用的,因为我有单独的葡萄牙语 – 葡萄牙语和葡萄牙语 – 巴西字符串表.
提出的第一个解决方法不起作用.使用下面的代码,我得到错误1814.
HRSRC r = FindResource( GetModuleHandle(NULL),MAKEINTRESOURCE(IDS_STRING101),RT_STRING); DWORD e = GetLastError();
所以我该怎么做 ?这个奇怪的“虫子”有什么解释?
后期编辑:
经过一些测试,我发现:
> GetThreadLocale()返回的是什么
在控制面板中设置 – >区域和
语言选项 – >格式.
>资源加载器错误本质上是如果我的程序也有美国英语资源,那么无论在Formats中设置什么,都将加载这些资源.如果它没有美国英语资源,将使用在Formats中设置的语言.
>如果我有一个法语(中性)和一个德语(中性)字符串表,并且我将Formats设置为法语(法国),则会加载德语字符串.如果我添加一个英文(中性)字符串表,则加载英文字符串.因此,中立文化后备不适用于Formats所设定的内容.
>如果我添加一个中性字符串表,即使我有另一个英语(中性)或英语(美国)字符串表,也会使用该表.
解决方法
编辑:但是,根据我的经验(至少在Windows XP上),该页面上FindResource的详细搜索顺序并未描述实际行为.实际行为似乎是:
> LANG_NEUTRAL资源
> Lang和SubLang匹配UI语言Lang和SubLang的资源
> Lang匹配UI语言的资源Lang和资源Sublang是中立的
> Lang和SubLang匹配语言环境Lang和SubLang的资源
>资源,其中Lang匹配语言环境语言Lang和资源Sublang是中立的
>具有最低数值LANGID的资源
注意:我没有任何来源来验证该列表,因此如果有人可以更新或更正任何内容,请执行此操作.
编辑:要理解这种行为,重要的是要认识到’locale’和’UIlanguage’之间的区别,如下所述:NLS Terminology.FindResource函数语言选择主要基于UI语言,而不是’区域选项’设置“区域和语言选项”(即“语言环境”设置,与调用SetThreadLocale()相同).
据我所知,语言环境设置或’SetThreadLocale()’影响FindResource()的原因是@Kirill V. Lyadvinsky在其中一个答案中描述的异常情况,在Michael Kaplan’s blog中有更详细的解释.
只需在Vista中使用新功能“SetThreadUILanguage”,就可以干净利落地确定代码中FindResource的语言.相反使用SetThreadLocale,你看到的每个地方都会有hack使它工作和/或在UI语言改变时出现问题(即:外语窗口安装).