For some background information have a look here:
http://www.siao2.com/2010/03/19/9980203.aspx
So it seems this problem manifests itself on Vista as well as Windows 7. It occurs because Microsoft seems to be in the process of deprecating the Locale ID in favor of the Locale Name.
To summarize: The relevant API calls all operate on registry values that can be found at HKCU\Control Panel\International
. The value "Locale" is maintained for backward compatibility reasons and under normal circumstances is kept in synch with its newer counterpart called "LocaleName". This synch process however doesn't work under some circumstances.
Anyway, the GetThreadLocale
API call gets its return value from the "Locale" registry entry mentioned above, while the others (GetUserDefaultLCID
, GetSystemDefaultLCID
, etc) use the "LocaleName" registry entry.
Hence the confusion.
BTW, the solution mentioned by JP in a previous post should probably be extended to
initialization
SetThreadLocale(GetUserDefaultLCID);
GetFormatSettings;
because (if i'm reading it correctly!) according to the docco the GetUserDefaultLCID call will account for user customizations.
After a bit more research, Vista is not affected at all. I've got some more detail too ...
The relevant API calls all operate on registry values that can be found at HKCU\Control Panel\International
. The value " Locale " is maintained for backward compatibility reasons and under normal circumstances is kept in synch with its newer counterpart called " LocaleName ". Under Windows 7 at least, this synch process however doesn't work where processes are being run as another user (i.e. RunAs or Impersonation). This seems to be the case during installation, where the installer is launched from an existing windows session. It does however seem to work correctly if you've booted from the install CD.
GetThreadLocale
gets its value from Thread Information Block or Thread Environment Block (TIB or TEB) See: http://en.wikipedia.org/wiki/Thread_Environment_Block
For both Vista and Windows 7, the TIB is initialised with the HKCU\Control Panel\International\Locale
registry entry at logon. This becomes the default Locale for all threads created during the session.
Changing this registry value during a session has no effect on the value returned by the GetThreadLocale API call. The user must log out and log in again to see a change.
This is the API call that Delphi uses as the basis to initialize all its locale format strings ( See SysUtils.GetFormatSettings
method), from which all date fields are formatted.
GetUserDefaultLCID
: in Vista, bases its return value on the HKCU\Control Panel\International\Locale
registry entry. In Windows 7, bases its return value on the HKCU\Control Panel\International\LocaleName
registry entry. The respective registry entry can be changed during a session and the result is immediately reflected in this API call return value.
SetThreadLocale
updates the TIB to reflect the locale provided in the parameter to this call. Note that this only ever effects the thread the API call is executed from.
The API calls SetThreadLocale(LOCALE_USER_DEFAULT)
and SetThreadLocale(GetUserDefaultLCID)
are functionally equivalent. They both derive the source locale as described in the GetUserDefaultLCID
API call above.