2

交換目的でファイルに書き込むすべての番号は、次のコードを使用します。

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

数字を読むときはこれを使います

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

これは、Windows 7 で動作します。ドイツ語版では失敗しますが、ドイツ語版の Windows XP では失敗します。

LOCALE_INVARIANT と LOCALE_DEFAULT_USER に対して同じ値が得られるため、問題は GetLocaleFormatSettings プロシージャにあるようです。

ここに私の問題を示すいくつかのコードがあります:

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 には、、、、および配列に関する初期化バグがありShortMonthNamesます(ただし、例には影響しません)。新しいリリースでは、フォーマット関連のバグ修正が行われています。LongMonthNamesShortDayNamesLongDayNames

場合によっては、単元のセクションでand を呼び出す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 に答える