代码之家  ›  专栏  ›  技术社区  ›  Mick

GetThreadLocale返回的值与GetUserDefaultLCID不同?

  •  16
  • Mick  · 技术社区  · 16 年前

    要获取区域设置,例如短日期格式,我们总是将getLocaleForMateSettings与getThreadLocale一起使用。直到现在,这一直都是毫无问题的。

    我们的一些用户获得的getthreadLocale值与在Windows7中的区域设置中配置的值不匹配。无论我们尝试什么,我们都无法重现这个过程,但是我向一个用户发送了一个测试程序来获取区域设置信息,并且确保getthreadLocale返回的LCID(1033)与getuserdefaultLCID(2057)不同。因此,他们没有得到英国地区设置,而是最终得到美国地区设置。

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

    谢谢

    5 回复  |  直到 14 年前
        1
  •  15
  •   Paul Heinz    16 年前

    你不是唯一一个。我在新西兰的windows 7中也看到过这种情况,据我所知,它似乎只是出于某种原因绊倒了Delphi应用程序。

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

    我想知道,通过Windows7安装过程选择非美国地区设置是否在某种微妙的方式上“做对了事情”,因为某种原因,Delphi应用程序只能被绊倒。

    我找到了与JP类似的测试代码,试图追踪它并找到一个软件解决方案,但我们的QA人员后来找到了“区域设置切换”解决方案,他不想完全重新安装Windows 7以返回原始的时髦状态,原因如下:—)

        2
  •  18
  •   Community Mohan Dere    9 年前

    有关某些背景信息,请查看以下内容:

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

    因此,这个问题似乎在Vista和Windows7上都有体现。出现这种情况是因为微软似乎在贬低 区域标识 有利于 区域名称 .

    总结一下:相关的API调用都对注册表值进行操作,可以在 HKCU\Control Panel\International .价值观” 现场 “出于向后兼容性的原因而维护,并且在正常情况下保持与其新的对应项同步,称为” 本地名 “。但是,这种同步过程在某些情况下不起作用。

    不管怎样, GetThreadLocale API调用从“”获取其返回值 现场 “上面提到的注册表项,而其他项( GetUserDefaultLCID , GetSystemDefaultLCID 等)使用“ 本地名 “注册表项。

    因此产生了混乱。

    顺便说一句,所提到的解决方案 JP in a previous post 应该扩展到

    initialization
      SetThreadLocale(GetUserDefaultLCID);
      GetFormatSettings;
    

    因为(如果我读对了!)根据docco,getuserdefaultlcid调用将负责用户自定义。

    经过更多的研究,Vista完全不受影响。我还有一些细节…

    相关的API调用都对注册表值进行操作,这些值可以在 香港中文大学\控制面板\国际 . 值“locale”是为了向后兼容而维护的,在正常情况下,它与新的对应项“localename”保持同步。但是,至少在Windows7下,当进程作为另一个用户运行时(即运行方式或模拟),此同步进程不起作用。在安装过程中,安装程序似乎是从现有的Windows会话启动的。但是,如果您从安装光盘引导,它似乎可以正常工作。

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

    • 获取用户默认LCID :在Vista中,其返回值基于 hkcu \控制面板\国际\地区 注册表项。在Windows 7中,其返回值基于 HKCU\Control Panel\International\LocaleName 注册表项。可以在会话期间更改相应的注册表项,结果立即反映在此API调用返回值中。

    • SetThreadLocale 更新TIB以反映此调用的参数中提供的区域设置。注意,这只会影响执行API调用的线程。 API调用 SetThreadLocale(LOCALE_USER_DEFAULT) SetThreadLocale(GetUserDefaultLCID) 在功能上是等效的。它们都派生源区域设置,如中所述 获取用户默认LCID 上面的API调用。

        3
  •  6
  •   J.Pelttari    16 年前

    当我开始使用新的Windows7计算机时,我注意到了同样的问题。 我花了一段时间试图找出造成这种情况的原因,但一无所获。 所以我把这两行添加到了一些单元初始化部分。

    initialization
      SetThreadLocale(LOCALE_USER_DEFAULT);
      GetFormatSettings;
    

    奇怪的是,这种行为只发生在我的计算机上,因为办公室里几乎没有其他的Win7计算机。

        4
  •  1
  •   Erwin    16 年前

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

        5
  •  1
  •   mjn anonym    14 年前

    new post in the RTL forum 建议在sysutils->initsyslocale中使用此修复程序:

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

    并进一步解释:

    必须将其默认设置为区域设置用户默认值,而不是0x409! 这个bug在2010年,xe和xe2

    推荐文章