2

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

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 函数检查 LCID 是否有效IsValidLCID(LCID, LCID_INSTALLED)。问题在于使用LCID_INSTALLED而不是LCID_SUPPORTED. 受LOCALE_INVARIANT支持,但未安装在 Windows XP 系统上。因此,GetLocaleFormatSettings例程总是返回到用户 LCID。

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

4

1 回答 1

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;
于 2013-04-18T01:11:52.277 回答