加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

使VarToDoubleAsString使用Delphi设置(不是OS设置)

发布时间:2020-12-15 09:39:46 所属栏目:大数据 来源:网络整理
导读:当一个包含字符串值的Variant分配给一个浮点变量时,Delphi调用VarToDoubleAsString来进行转换,转换又使用十进制和千位分隔符的OS设置(通过VarR8FromStr).如果必须更改SysUtils.DecimalSeparator和SysUtils.ThousandSeparator,则会出现问题.例如,运行以下程序
当一个包含字符串值的Variant分配给一个浮点变量时,Delphi调用VarToDoubleAsString来进行转换,转换又使用十进制和千位分隔符的OS设置(通过VarR8FromStr).如果必须更改SysUtils.DecimalSeparator和SysUtils.ThousandSeparator,则会出现问题.例如,运行以下程序:

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.

第一个测试工作正常,第二个测试失败.

有没有办法让Variant转换使用SysUtils.DecimalSeparator和SysUtils.ThousandSeparator?

解决方法

您可以根据自己的喜好替换varutils.pas中的VarR8FromStr函数,VarToDoubleAsString将使用它:

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;
  [...]

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读