I do not like the thread locale.

Yes, GetThreadLocale and SetThreadLocale are two of the many NLS functions that the GIFT team supports.

And yes, if we are to look at the functions we own as if they are our children then we are supposed to love them all.

But in that case, I guess I am a lousy parent (if you will recall, I think that SetLocaleInfo really stinks, too).

First of all, there are the weird dependencies in USER32 and SHELL32 that probably ought to be using the user locale but instead use the thread locale and fall back to the system locale if something goes wrong.

Second of all, there is the poor story in GetThreadLocale:

Return Values

The function returns the system's default user locale.

Remarks

When a thread is created, it uses the system default user locale. The system reads the system default user locale from the registry when the system boots. This system default can be modified for future process and thread creation using Control Panel's International application.

Since it always returns the thread locale, which starts its life as the user locale (set in Regional Options) but can be changed by a call to SetThreadLocale, you can make a fair case that both parts of the text are losuy.

Third of all, there is the worse story in SetThreadLocale:

Return Values

If the function succeeds, the return value is a nonzero value.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

When a thread is created, it uses the system default thread locale. The system reads the system default thread locale from the registry when the system boots. This system default can be modified for future process and thread creation using Control Panel's International application.

The SetThreadLocale function affects the selection of resources that are defined with a LANGUAGE statement. This affects such functions as CreateDialog, DialogBox, LoadMenu, LoadString, and FindResource, and sets the code page implied by CP_THREAD_ACP, but does not affect FindResourceEx.

Windows 2000/XP: Do not use SetThreadLocale to select a UI language. To select the proper resource that is defined with a LANGUAGE statement, use FindResourceEx.

Where do I start? The function should return an LCID on success -- the previous thread locale! -- not a BOOL. Just like functions like SetWindowLong does. Oh well, I guess that is not the end of the world.

There is that same type of silly text about the 'system default thread locale' which is a beast not found in nature. The notion that it is read from the registry on boot is also crap. it is based on user locale. Always.

Then there is the text about how resource loading is affected -- and a warning sans explanation to not use that functionality on Win2000 and later. Since it is not supported on Win9x, what it is really saying is "good for only NT 3.1, 3.5x, and 4.0". In other words a warning that the function is not useful on modern platforms unless you want to affect the Shell and User subsystem in strange ways. Although it does not bother to say so.

Fourth of all, the fact is that resource loading is incredibly complicated, in part because of this questionable functionality. It is not based on the user locale, and it is not in essence based on the thread locale unless you change it. In which case it suddenly is based on the thread locale. Unless it is based on the UI language -- which it should always be. I swear you need a spirit dancer and a Ouija board to know what resources load if you start mucking with the various locale settings, and that is mostly because of this weird setting that hovers between UI language and user locale -- the thread locale.

On older platforms it is worse -- the system locale is the one that is used except when you set the thread locale (even though the thread locale is initially the user locale). I guess that is about the same as Win2000 and later, just substitute system locale for UI language.

This is by the way (now that I think about it) the first reasonable explanation for the strange Visual Basic <= 6.0 behavior where in the IDE the user locale is the language used for resource loading, even though in the compiled application that would not work -- VB was setting the the thread locale to the user locale and confusing millions of VB developers with this never-before-now-fully-explained behavior. Geez.

Anyway, we document that developers should use LOCALE_USER_DEFAULT and not GetThreadLocale when they are trying to respect the user's preferences.

If you ask me, we should treat every case where the thread locale is currently used as a bug to be fixed and not as a legacy behavior to be coddled. We have been slowly breaking the behavior anyway with each version without explaining why since it was already broken, so why not just cut the cord and stop using this dastardly functionality?

The thread locale really stinks, after all!

 

This post brought to you by "ײ" (U+05f2, HEBREW LIGATURE YIDDISH DOUBLE YOD)