我希望能够以编程方式修改应用程序的语言,或者至少使用控制面板中指定的语言 - >区域和语言选项 - >格式。
如果我添加一个英文字符串表,制作法文和德文副本,并删除英文字符串,我可以以编程方式切换加载法语和德语字符串。 如果我保留英文副本,无论如何,当我尝试加载德语或法语时,英语字符串都会被加载。
我认为这是一个资源加载器错误,如果资源加载器找到与windows ui语言相同语言的字符串表(例如Windows资源管理器菜单的语言),则忽略SetThreadLocale。
我尝试更改控制面板 - >区域和语言选项 - >格式化为法语,但没有效果。资源编辑器显示没有附加语言的法语字符串表,但我的程序仍然总是加载英语字符串。将此更改复制到系统帐户也不起作用。
以下是我尝试过的代码:
#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();
那么,我该怎么办?这个奇怪的“虫子”有什么解释?
LATER EDIT:
经过一些测试后我发现:
答案 0 :(得分:6)
直接从MSDN选择本地化资源(包括FindResource的搜索顺序)的详细说明:Multiple-Language Resources
编辑:但是,根据我的经验(至少在Windows XP上),该页面上FindResource的详细搜索顺序并未描述实际行为。实际行为似乎是:
注意:我没有任何资源来验证该列表,因此如果有人可以更新或更正任何内容,请执行此操作。
编辑:要理解这种行为,重要的是要认识到'locale'和'UIlanguage'之间的区别,如下所述:NLS Terminology。 FindResource函数语言选择主要基于UI语言,而不是“区域和语言选项”中的“区域选项”设置(即“语言环境”设置,与调用SetThreadLocale()相同)。
据我所知,语言环境设置或'SetThreadLocale()'影响FindResource()的原因是由于@Kirill V. Lyadvinsky在其中一个答案中描述的异常情况,更详细地解释了Michael Kaplan's blog。
只有在Vista中使用新功能“SetThreadUILanguage”才能干净利落地确定代码中FindResource的语言。相反使用SetThreadLocale而你看到的每个地方都会有黑客使其工作和/或在UI语言发生变化时出现问题(即:外语窗口安装)。
答案 1 :(得分:5)
您运行的是Vista还是Windows 7?如果是这样,那么SetThreadLocale
不起作用(即使它返回TRUE,叹气),你必须使用SetThreadUILanguage
。
我刚刚完成了一个已翻译成7种不同语言的WTL应用程序,用户可以在没有您描述的问题的情况下切换语言。我在XP上使用SetThreadLocale
,在Vista / 7上使用SetThreadUILanguage
。
更多信息:
答案 2 :(得分:4)
这里的问题是,如果线程区域设置与当前选定的用户区域设置相同,则系统的资源加载器将默认使用语言ID 0(中性)。如果将所需资源定义为中性语言,则将返回此值。否则,将枚举所有语言资源(按语言ID顺序),并返回第一个匹配的资源ID - 无论其语言如何 -
控制资源的唯一方法是为每种语言使用单独的资源DLL。