GetThreadLocale返回的值与GetUserDefaultLCID不同?

时间:2009-11-20 02:26:49

标签: delphi windows-7

要获取区域设置,例如短日期格式,我们总是使用GetLocaleFormatSettings和GetThreadLocale。到目前为止,这一直没有问题。

我们的一些用户获得的GetThreadLocale值与Windows 7中的区域设置中的配置值不同。无论我们尝试什么,我都无法重现这一点,但我发送了一个用户获取测试程序以获取区域设置信息,并确定GetThreadLocale返回与GetUserDefaultLCID(2057)不同的LCID(1033)。因此,不是获取英国语言环境设置,而是最终使用美国语言环境设置。

我们是否错误地获取了区域设置信息?我们应该使用GetUserDefaultLCID而不是GetThreadLocale吗?

由于

5 个答案:

答案 0 :(得分:18)

有些背景资料请点击此处:

http://www.siao2.com/2010/03/19/9980203.aspx

因此,似乎这个问题在Vista和Windows 7上都会出现。这是因为Microsoft似乎正在弃用区域设置ID 以支持区域设置名称< / em>的。

总结:相关的API调用都可以在HKCU\Control Panel\International找到的注册表值上运行。值“ Locale ”是为了向后兼容性而维护的,并且在正常情况下与其名为“ LocaleName ”的新对应方保持同步。然而,这种同步过程在某些情况下不起作用。

无论如何,GetThreadLocale API调用从上面提到的“ Locale ”注册表项中获取其返回值,而其他调用(GetUserDefaultLCIDGetSystemDefaultLCID,等)使用“ LocaleName ”注册表项。

因此引起了混乱。

BTW,JP in a previous post提到的解决方案应该扩展到

initialization
  SetThreadLocale(GetUserDefaultLCID);
  GetFormatSettings;

因为(如果我正确地读它!)根据docco,GetUserDefaultLCID调用将考虑用户自定义。

经过一番研究后,Vista根本没有受到影响。我也有更多的细节......

相关的API调用都可以在HKCU\Control Panel\International找到的注册表值上运行。值“Locale”是为了向后兼容性而维护的,并且在正常情况下与其名为“LocaleName”的新对应方保持同步。至少在Windows 7下,此同步过程在其他用户(即RunAs或模拟)运行进程的情况下不起作用。在安装过程中似乎就是这种情况,安装程序从现有的Windows会话启动。但是,如果您从安装CD启动,它似乎可以正常工作。

  • GetThreadLocale从线程信息块或线程环境块(TIB或TEB)获取其值请参阅:http://en.wikipedia.org/wiki/Thread_Environment_Block 对于Vista和Windows 7,TIB在登录时使用HKCU\Control Panel\International\Locale注册表项进行初始化。这将成为会话期间创建的所有线程的默认区域设置。 在会话期间更改此注册表值不会影响GetThreadLocale API调用返回的值。用户必须注销并再次登录才能看到更改。 这是Delphi使用的API调用,用作初始化其所有语言环境格式字符串的基础(请参阅SysUtils.GetFormatSettings方法),从中格式化所有日期字段。

  • GetUserDefaultLCID:在Vista中,将其返回值基于HKCU\Control Panel\International\Locale注册表项。在Windows 7中,将其返回值基于HKCU\Control Panel\International\LocaleName注册表项。可以在会话期间更改相应的注册表项,结果会立即反映在此API调用返回值中。

  • SetThreadLocale更新TIB以反映此调用的参数中提供的区域设置。请注意,这只会影响执行API调用的线程。 API调用SetThreadLocale(LOCALE_USER_DEFAULT)SetThreadLocale(GetUserDefaultLCID)在功能上是等效的。它们都导出源语言环境,如上面的GetUserDefaultLCID API调用中所述。

答案 1 :(得分:15)

你不是唯一一个。我在新西兰的Windows 7中也看到了这一点,据我所知,它似乎只是因为某些原因而绊倒Delphi应用程序。

我们发现奇怪的是,通过控制面板切换到不同的区域设置,然后切换回NZ解决了这个问题。我很想知道相同的解决方法是否能解决它,只是为了验证我们是否看到了相同的现象。

我想知道是否通过Windows 7安装过程选择非美国区域设置并不是以某种微妙的方式“做正确的事情”,因为某些原因只会绊倒Delphi应用程序。

为了跟踪它并找到一个软件解决方法,我得到了与JP类似的测试代码,但我们的QA人员后来发现了'区域设置切换器'的解决方法,他并不想再完全重新安装Windows 7由于某种原因回到原来的时髦状态: - )

答案 2 :(得分:6)

当我开始使用新的Windows 7计算机时,我注意到了同样的问题。 我花了一些时间试图找到导致这种情况的原因,但一无所获。 所以我只是将这两行添加到某些单元初始化部分。

initialization
  SetThreadLocale(LOCALE_USER_DEFAULT);
  GetFormatSettings;

奇怪的是,这种行为只发生在我的电脑上,因为我们办公室里的其他Win7电脑也很少。

答案 3 :(得分:1)

我刚刚测试了Windows 7 Starter Edition的新安装,并遇到了同样的问题,但我发现GetThreadLocale返回的区域设置恰好是Windows安装程序提取的区域设置,但我在安装过程中将其更改为另一个,这是GetUserDefaultLCID返回的那个,也是我想要使用的那个(我为此制作了一个小程序)。因此,区域设置已更改为用户,但某处仍然指定了第一个区域设置,并且它已由GetThreadLocale返回。正如JP评论的那样,安装确实存在问题,它不会在可以找到它的所有位置更改区域设置。似乎通过控制面板更改区域设置可以很好地完成工作,这可以解释为什么将其更改为提议的工作,顺便说一下,它解释了为什么其他计算机不会遇到相同的问题(如果您在更改期间没有更改区域设置)安装)。 希望这有帮助。

答案 4 :(得分:1)

new post in the RTL forum在SysUtils-&gt; InitSysLocale中建议此修复:

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

进一步解释:

  

它必须默认设置为LOCALE_USER_DEFAULT而不是0x409!   此错误发生在2010年,XE和XE2