仅当我没有英文字符串表时,LoadString才有效

Csu*_*enő 7 c++ windows localization visual-c++

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

如果我添加一个英语字符串表,制作一个法语和德语副本,并删除英语字符串,我可以编程方式在加载法语和德语字符串之间切换.如果我保留英文副本,无论如何,当我尝试加载德语或法语时,英语字符串都会被加载.

我认为这是一个资源加载器错误,如果资源加载器找到与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;
}
Run Code Online (Sandbox Code Playgroud)

是一个错误的,不完整的解释(在方法2的后半部分).在那里提出的第二种解决方法,只使用相对于中性的字符串表是没用的,因为我有单独的葡萄牙语 - 葡萄牙语和葡萄牙语 - 巴西字符串表.

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

HRSRC r = FindResource(
    GetModuleHandle(NULL),
    MAKEINTRESOURCE(IDS_STRING101),
    RT_STRING);
DWORD e = GetLastError();
Run Code Online (Sandbox Code Playgroud)

所以我该怎么做 ?这个奇怪的"虫子"有什么解释?

后期编辑:

经过一些测试后我发现:

  1. GetThreadLocale()返回控制面板 - >区域和语言选项 - >格式中设置的内容.
  2. 资源加载器错误本质上是如果我的程序也有美国英语资源,那么无论在Formats中设置什么,这些资源都将被加载.如果它没有美国英语资源,将使用在Formats中设置的语言.
  3. 如果我有一个法语(中性)和一个德语(中性)字符串表,并且我将Formats设置为法语(法国),则会加载德语字符串.如果我添加一个英文(中性)字符串表,则加载英文字符串.因此,中立文化后备不适用于Formats所设定的内容.
  4. 如果我添加一个中性字符串表,即使我有另一个英语(中性)或英语(美国)字符串表,也会使用该表.

Sog*_*ger 6

直接从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匹配语言环境语言Lang和资源Sublang是中立的
  6. 数值LANGID最小的资源

注意:我没有任何来源来验证该列表,因此如果有人可以更新或更正任何内容,请执行此操作.

编辑:要理解这种行为,重要的是要认识到'locale'和'UIlanguage'之间的区别,如下所述:NLS术语.FindResource函数语言选择主要基于UI语言,而不是"区域和语言选项"中的"区域选项"设置(即"语言环境"设置,与调用SetThreadLocale()相同).

据我所知,语言环境设置或'SetThreadLocale()'影响FindResource()的原因是由于@Kirill V. Lyadvinsky在其中一个答案中描述的异常情况,在Michael Kaplan的博客中有更详细的解释.

只需在Vista中使用新功能"SetThreadUILanguage",就可以干净利落地确定代码中FindResource的语言.相反使用SetThreadLocale,你看到的每个地方都会有黑客使其工作和/或在UI语言改变时出现问题(即:外语窗口安装).


Rob*_*Rob 5

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

我刚刚完成了一个已翻译成7种不同语言的WTL应用程序,用户可以在没有您描述的问题的情况下切换语言.我SetThreadLocale在XP和SetThreadUILanguageVista/7上使用.

更多信息:

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/


Kir*_*sky 4

\n

这里的问题是,如果线程区域设置与当前选择的用户区域设置相同,则 system\xe2\x80\x99s 资源加载器将默认使用语言 ID 0(中性)。如果所需资源被定义为中性语言,则将返回该值。否则,将枚举所有语言资源(按语言 ID 顺序),并返回第一个匹配的资源 ID \xe2\x80\x93,无论其语言 \xe2\x80\x93 是什么。

\n
\n\n

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

\n