There has been an unexpected problem localizing application resources when STRING resources failed to load while there were no problems with other resource types. The source of the problem appears to be within ATL core. As long as CP_THREAD_ACP is involved in ATL’s conversion the loaded string is screwed.
The problem is illustrated by the sample. The same string resource is loaded with LoadString API and CString::LoadString ATL function. The difference is emphasized with bold below. As soon as Russian string is loaded from a thread with non-Russian thread locale, the string is screwed but only when loaded through ATL class (warning: Russian characters seems to be forged by WordPress in quoted text below):
C:\>ThreadLocaleSample01.exe
Default Thread Locale: 1033 (0x409), Primary Language 9 (0x9), SubLanguage 1 (0x1), Sort 0 (0x0)
String 101: ABCDEFGHIJKLMNOPQRSTUVWXYZ
String 102: ????????????????????????????????
ATL String 101: ABCDEFGHIJKLMNOPQRSTUVWXYZ
ATL String 102: ????????????????????????????????
Russian Locale: 1049 (0x419), Primary Language 25 (0x19), SubLanguage 1 (0x1), Sort 0 (0x0)
String 101: ABCDEFGHIJKLMNOPQRSTUVWXYZ
String 102: ????????????????????????????????
ATL String 101: ABCDEFGHIJKLMNOPQRSTUVWXYZ
ATL String 102: ????????????????????????????????
English Locale: 1033 (0x409), Primary Language 9 (0x9), SubLanguage 1 (0x1), Sort 0 (0x0)
String 101: ABCDEFGHIJKLMNOPQRSTUVWXYZ
String 102: ????????????????????????????????
ATL String 101: ABCDEFGHIJKLMNOPQRSTUVWXYZ
ATL String 102: ????????????????????????????????
The workaround for the problem is one of the following:
- define _CONVERSION_DONT_USE_THREAD_LOCALE before including ATL headers
- compile in Unicode character set
See also:
- _CONVERSION_DONT_USE_THREAD_LOCALE does not work: Won’t Fix on connect.microsoft.com
- Nothing stinks worse than the thread locale, other than the thread code page on blogs.microsoft.com
Visual C++.NET 2005 source code can be downloaded here.