LOCALE_INVARIANT的GetLocaleFormatSettings返回Windows XP German下的用户设置

时间:2013-04-17 23:37:29

标签: delphi localization delphi-2010

我写入文件以进行交换的所有数字都使用以下代码:

GetLocaleFormatSettings(LOCALE_INVARIANT, fsInvariant);
FloatToStrF(Value, fsInvariant);

当我读到数字时,我会使用此

GetLocaleFormatSettings(LOCALE_INVARIANT, fsInvariant);
if TryStrToFloat(value, floatval, fsInvariant) then
  result := floatVal

在Windows 7下运行,包括德语版本,但在德语版的Windows XP中失败。

问题似乎出现在GetLocaleFormatSettings过程中,因为它为LOCALE_INVARIANT和LOCALE_DEFAULT_USER提供了相同的值。

这里有一些显示我的问题的代码:

unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, ValEdit;

type
  TForm1 = class(TForm)
    VLEditor: TValueListEditor;
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
var
  fsInvariant : TFormatSettings;
  fsLocaleUser : TFormatSettings;
begin
  GetLocaleFormatSettings(LOCALE_INVARIANT, fsInvariant);
  VLEditor.InsertRow('Invariant Decimal Seperator', fsInvariant.DecimalSeparator, true);
  VLEditor.InsertRow('Invariant Thousand Seperator', fsInvariant.ThousandSeparator , true);
  VLEditor.InsertRow('Invariant List Seperator', fsInvariant.ListSeparator , true);

  GetLocaleFormatSettings(LOCALE_USER_DEFAULT, fsLocaleUser);
  VLEditor.InsertRow('Locale Decimal Seperator', fsLocaleUser.DecimalSeparator, true);
  VLEditor.InsertRow('Locale Thousand Seperator', fsLocaleUser.ThousandSeparator, true);
  VLEditor.InsertRow('Locale List Seperator', fsLocaleUser.ListSeparator, true);
end;

end.

当我在Windows XP Pro - SP3 - GERMAN中运行exe时,它会为相同的分隔符显示相同的字符。在德语版Windows 7中,它按预期显示。

我在这里缺少什么?怎么会给出不同的输出?

谢谢, 托马斯

更新 GetLocaleFormatSettings首先使用kernel32函数IsValidLCID(LCID, LCID_INSTALLED)检查LCID是否有效。问题在于使用LCID_INSTALLED而不是LCID_SUPPORTED。支持LOCALE_INVARIANT,但未在Windows XP系统上安装。因此,GetLocaleFormatSettings例程始终会恢复为用户LCID。

修复它的最佳方法是什么?编写我自己的GetLocaleFormatSettings例程?更改Delphi的SysUtils.pas文件中的代码?

1 个答案:

答案 0 :(得分:4)

早期版本的Delphi确实在初始化TFormatSettings时遇到了问题。例如,当未安装指定的LCID时,D2010确实存在关于ShortMonthNamesLongMonthNamesShortDayNamesLongDayNames数组的初始化错误(但这不会影响您的例)。在较新的版本中已经有与格式相关的错误修复。

在某些情况下,在单元的SetThreadLocale()部分中调用GetFormatSettings()initialization有助于解决格式问题。

仅供参考,GetLocaleFormatSettings()现已在最近的版本中弃用,而采用新的TFormatSettings.Create()方法:

procedure TForm1.FormShow(Sender: TObject);
var
  fsInvariant : TFormatSettings;
  fsLocaleUser : TFormatSettings;
begin
  fsInvariant := TFormatSettings.Create(LOCALE_INVARIANT);
  ...
  fsLocaleUser := TFormatSettings.Create(LOCALE_USER_DEFAULT);
  ...
end;