Search code examples
windowslocalizationinternationalizationlanguage-agnostic

What does SetThreadLocale actually do?


I've spent the last week trying to demistify the behavior of embedded resources (via .rc files) in conjunction with internationalization, and it sure feels like some bizarre kind of computer archaeology.

Most information on this function is outdated or unhelpful, including the official documentation.

Michael Kaplan does not think highly of it either, the information provided in that blog post seems no longer correct (i.e. I have not been able to reproduce any scenario in which SetThreadLocale has an observable effect).

On a reasonably modern system (say, Win7 and newer), what does SetThreadLocale actually do, i.e. which APIs are affected by "The Thread Locale" (whatever that is supposed to be)?

I've ruled out any resource loading FindResource[Ex], including LoadString, dialog and menu functions; FormatMessage; the strsafe.h *Printf family; datetimeapi.h's GetDateFormat et al; and standard message boxes.


Solution

  • My recent investigation shows that, SetThreadLocale() and GetThreadLocale() has almost been obsolete. At least from Win7+, DialogBox, FindResource etc's resource LANGUAGE matching behavior is not affected by SetThreadLocale() but affected by GetThreadUILanguage().

    I have a dedicated test program to show this conclusion: https://github.com/chjfth/trivials/tree/master/mswin/About2-muires

    The MSDN page for SetThreadLocale lacks maintenance for many years. Some Microsoft staff updated it by patching, not by reworking. That page says,

    SetThreadLocale affects the selection of resources with a LANGUAGE statement.

    I'm now almost certain it is only true for Windows NT4, or for Windows 95/98, quite out-dated Windows versions that no one is sticking to in year 2022. So everyone should agree to delete that paragraph to avoid misleading.

    The only effect of SetThreadLocale I found is when we call some WinAPI related to CP_THREAD_ACP, for example, MultiByteToWideChar(CP_THREAD_ACP, ...), the thread-locale value set by SetThreadLocale() will determine the codepage used by MultiByteToWideChar.