Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make VarToDoubleAsString use Delphi settings (not OS settings)

When one assigns a Variant containing a string value to a floating point variable Delphi calls VarToDoubleAsString to do the conversion, which in turn uses the OS settings for decimal and thousand separator (via VarR8FromStr). This is problematic if one has to change SysUtils.DecimalSeparator and SysUtils.ThousandSeparator. For example run the following program:

program VarStrToFloat;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Math;

function FormatFloatUsingDelphiSettings(Value: Extended): string;
begin
  Result := FormatFloat('#,##0.00', Value);
end;

procedure Test(const AMsg: string);
var
  r1, r2: Extended;
  s1, s2: string;
  v: Variant;
begin
  r1 := 5432.1;
  s1 := FormatFloatUsingDelphiSettings(r1);
  v := s1; // <== conversion uses OS settings
  r2 := v;
  s2 := FormatFloatUsingDelphiSettings(r2);

  Write(AMsg: 8, s1: 10, s2: 10, '  ');
  if SameValue(r1, r2) then
    Writeln('OK')
  else
    Writeln('FAIL');
end;

procedure SwapEm;
var
  tmp: Char;
begin
  tmp := DecimalSeparator;
  DecimalSeparator := ThousandSeparator;
  ThousandSeparator := tmp;
end;

begin
  Test('Default');
  SwapEm;
  Test('Changed');
  Readln;
end.

The first test works fine, the second one fails.

Is there a way to make the Variant conversion use SysUtils.DecimalSeparator and SysUtils.ThousandSeparator?

like image 489
Uli Gerhardt Avatar asked Feb 23 '11 11:02

Uli Gerhardt


Video Answer


1 Answers

You can replace the VarR8FromStr function in varutils.pas to your liking, and VarToDoubleAsString will use it instead:

function MyConversion(const strIn: WideString; LCID: Integer; dwFlags: Longint;
    out dblOut: Double): HRESULT; stdcall;
const
  CResult: array [False..True] of HRESULT = (VAR_INVALIDARG, VAR_OK);
var
  s: string;
begin
  s := StringReplace(StrIn, ThousandSeparator, '', [rfReplaceAll]);
  Result := CResult[TryStrToFloat(s, dblOut)];
end;

[...]

begin
  varutils.VarR8FromStr := MyConversion;
  [...]
like image 176
Sertac Akyuz Avatar answered Sep 28 '22 23:09

Sertac Akyuz