c++ - LoadString 仅在我没有英文字符串表时才有效

标签 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;
}

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

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

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

那么,我该怎么办?这个奇怪的“错误”的解释是什么?

后期编辑:

经过更多的测试,我发现:

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

最佳答案

有关如何选择本地化资源的详细说明(包括 FindResource 的搜索顺序)直接来自 MSDN:Multiple-Language Resources

编辑:但是,根据我的经验(至少在 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 数值最低的资源

注意:我没有任何来源来验证该列表,因此如果有人可以更新或更正任何内容,请这样做。

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

据我所知,语言环境设置或“SetThreadLocale()”影响 FindResource() 的原因是@Kirill V. Lyadvinsky 在此处的一个答案中描述的异常情况,更详细地解释了Michael Kaplan's blog .

只有在 Vista 之后的新函数“SetThreadUILanguage”中,才能在代码中清晰、确定地设置 FindResource 的语言。你看到的每一个使用 SetThreadLocale 的地方都会有黑客让它工作和/或在 UI 语言更改时出现问题(即:外语窗口安装)。

关于c++ - LoadString 仅在我没有英文字符串表时才有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1213510/

相关文章:

c++ - “正则表达式”类型无法识别

c++ - 堆栈限制和线程之间的关系

c++ - 如何在 Visual Studio 调试器中显示动态分配的数组?

c++ - 在 C++ 中隐藏实现细节

node.js - 重击 : npm: command not found?

c# - 如何获得已安装软件产品的列表?

python - conda 在激活环境之外寻找库

swift - 如何在 Swift 中翻译/本地化变量

ios - 使用附加字符串本地化 Info.plist 变量

java - 如何将Spotlight for Help插入Java中的本地化macOS应用程序中?