I want to be able to modify the application's language programatically, or at least use the language specified in Control Panel -> Regional and Language Options -> Formats.
If I add an english string table, make a french and a german copy of it, and delete the english one, I can programatically switch between loading the french and the german strings. If I keep the english copy, the english strings get loaded, no matter what, when I try to load the german or the french ones.
I think that this is a resource loader bug, and that the resource loader ignores SetThreadLocale, if it finds a string table in the same language as the windows ui language (the language of the windows explorer menus for example).
I tried to change Control Panel -> Regional and Language Options -> Formats to French, but that has no effect. The resource editor shows the french string table without the language appended, but my program still always loads the english strings. Copying this change to the system account has no effect either.
Here is the code I tried this with:
#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 is a half wrong, incomplete explanation (in the second half of Method 2). The second workaround proposed there, using only coutry-neutral string tables is useless, because I have separate portuguese-Portugal and portuguese-Brazil string tables.
The first workaround proposed there does not work. With the code below, I get error 1814.
HRSRC r = FindResource(
GetModuleHandle(NULL),
MAKEINTRESOURCE(IDS_STRING101),
RT_STRING);
DWORD e = GetLastError();
So, what should I do ? What's the explanation of this strange "bug" ?
LATER EDIT:
After some more tests I found out that:
- GetThreadLocale() returns what is set in Control Panel -> Regional and Language Options -> Formats.
- The resource loader bug is essentially that if my program has US English resources too, those resources will be loaded, no matter what is set at Formats. If it does not have US English resources, the language set at Formats will be used.
- If I have a French (Neutral) and a German (Neutral) string table, and I set Formats to French (France), the german strings are loaded. If I add an English (Neutral) string table, the english strings are loaded. So, the neutral culture fallback does not work for what is set at Formats.
- If I add a Neutral string table, that one will be used, even if I have another English (Neutral) or an English (United States) string table.