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 country-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:
Detailed description of how localized resources are selected (including the search order of FindResource) straight from MSDN: Multiple-Language Resources
Edit: However, from my experience (at least on Windows XP) the search order detailed for FindResource on that page does not describe the actual behaviour. The actual behaviour seems to be:
Note: I don't have any sources to validate that list, so if anybody can update or correct anything, please do so.
Edit: To understand this behaviour, it is important to recognize the difference between the 'locale' and 'UIlanguage' as explained here: NLS Terminology. The FindResource function language selection is based primarily off of the UI language which is NOT the 'Regional Options' setting in the 'Regional and Language Options' (that is the 'locale' setting, which is the same as calling SetThreadLocale()).
As far as I can tell, the reason the locale setting or 'SetThreadLocale()' affects FindResource() is because of the exception case described by @Kirill V. Lyadvinsky in one of the answers here, explained in more detail on Michael Kaplan's blog.
Setting the language for FindResource in code cleanly and deterministically was only made possible with the new function 'SetThreadUILanguage' in Vista onwards. Every place you see that instead uses SetThreadLocale will have hacks to make it work and/or have issues when the UI language changes (ie: Foreign language windows install).
Are you running Vista or Windows 7? If so then SetThreadLocale
doesn't work (even though it returns TRUE, sigh) and you have to use SetThreadUILanguage
.
I have just completed a WTL app that has been translated into 7 different languages and the user can switch languages without the problems you are describing. I am using SetThreadLocale
on XP and SetThreadUILanguage
on Vista/7.
More info:
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/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With