GetThreadLocale returns different value than GetUserDefaultLCID?

前端 未结 5 698
迷失自我
迷失自我 2020-12-08 05:30

To get the locale settings, e.g. short date format, we\'ve always used GetLocaleFormatSettings with GetThreadLocale. This has always worked without problem until now.

<
相关标签:
5条回答
  • 2020-12-08 05:46

    I noticed same problem, when I started using new Windows 7 computer. I spent some time trying to find what causes this, but found nothing. So I just added these two lines to some units initialization section.

    initialization
      SetThreadLocale(LOCALE_USER_DEFAULT);
      GetFormatSettings;
    

    Strange is that this behavior occurs only in my computer as we have few other Win7 computers in office also.

    0 讨论(0)
  • 2020-12-08 05:51

    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.

    0 讨论(0)
  • 2020-12-08 05:57

    I've just tested a new installation of Windows 7 Starter Edition, and had the same problem, but I found that the locale that GetThreadLocale returns was exactly the locale sugested by the Windows installation program, but I changed it during installation to another, wich is the one that GetUserDefaultLCID returns, also the one I wanted to use, (I maked a small program just for this). So, the locale changed for user, but somewhere was still specified the first locale and it's been returned by GetThreadLocale. As JP commented, really there is an issue with installation, it doesn't change the locale at all places where it can be found. It seems that changing the locale via Control Panel does the job fine, and that could explain wy changing it as proposed works, by the way, it explains why other computers could not have the same problem (if you didn't change the locale during installation). Hope this help.

    0 讨论(0)
  • 2020-12-08 06:02

    A new post in the RTL forum suggests this fix in SysUtils->InitSysLocale:

    SetThreadLocale(LOCALE_USER_DEFAULT); 
    SysLocale.DefaultLCID := LOCALE_USER_DEFAULT; 
    GetFormatSettings;
    

    And further explains:

    It Must be set by default to LOCALE_USER_DEFAULT and not to 0x409! This bug is in 2010, XE and XE2

    0 讨论(0)
  • 2020-12-08 06:13

    You're not the only one. I've seen this too with Windows 7 here in New Zealand and it seems to only trip up Delphi applications for some reason as far as I can tell.

    The strange thing we found is that switching to a different regional settings via Control Panel and then switching back to NZ resolves the issue. I'd be curious to know if the same workaround resolves it for you just to verify that we're seeing the same phenomenon.

    I'm wondering if selecting non-US regional settings via the Windows 7 install process is not quite 'doing the right thing' in some subtle way that only trips up Delphi applications for some reason.

    I'd arrived at similar test code to JP's in an attempt to track it down and find a software workaround but our QA guy had since found the 'regional settings switcheroo' workaround and he didn't fancy completely reinstalling Windows 7 again to get back to the original funky state for some reason :-)

    0 讨论(0)
提交回复
热议问题