2

我需要计算我的设置中所有组件的总大小。由于一些自定义代码,我不能为此使用 Inno Setup 的内部功能。

问题是组件共享大量文件。所以我为每个组件定义了一个字符串,其中包含他们使用的文件的变量。然后,我将这些字符串添加到单个字符串中,如果在该字符串中找到某个变量,则将文件的大小(以字节为单位)添加到 type 的变量“size”中Single。最后“大小”显示安装需要多少空间。

实际上这很好用,但我想在下一页显示以 GB 为单位的大小。但是该函数FloatToStr在小数点后添加了很多数字,而我只想有两个。

这是脚本(问题出现在最后几行):

function NextButtonClick(CurPageID: Integer): Boolean;
var
  size: Single;

  if (CurPageID = wpSelectDir) then { I have swapped the Components and SelectDir pages }
  begin

  size := 0; { this will contain the size in the end }
  xg := '';  { this is the string which contains the list of files needed by every single component }
  for I := 0 to GetArrayLength(ComponentArray) - 1 do
  if IsComponentSelected(ComponentArray[I].Component) then
  begin
    xg := xg + ComponentArray[I].GCF; 
  end;    
  { here the files are being added to the string, everything's working as intended.. }


  MsgBox(xg, mbInformation, MB_OK); { this is for testing if the string has been created correctly }
  if Pos('gcf1', xg) > 0 then size := size + 1512820736; { here the Pos-function searches for the given string and if it is found it adds the value to "size", ok... }
  if Pos('gcf2', xg) > 0 then size := size + 635711488;
  if Pos('gcf3', xg) > 0 then size := size + 286273536;
size := size / 1024 / 1024 / 1024; { now all sizes have been added and the number is converted to be displayed GB, not bytes }
  { Format('%.2n', [size]); }
  { size := (round(size * 10) / 10); }
  { size := Format('%.2n', [size]); }
  { FloatToStr(size); }
  MsgBox(FloatToStr(size), mbInformation, MB_OK); { Here the size is shown but with several unneeded places after the decimal point (2.267589569092) }
  end;
end;

如您所见,我尝试了几件事来摆脱数字。问题是 中的FloatToStr函数MsgBox,它会自动添加所有数字。如果我选择Integer“大小”的类型,它仍然显示长数字,但我不能使用IntegerIntToStrMsgBox什么可以解决问题),因为这里处理的数字太大,我想在点后有两位小数。

我也尝试将Format函数放入,MsgBox但我也得到了“类型不匹配”错误。

FloatToStrFInno Setup 不支持。

预先使用转换“大小”FloatToStr并截断它也不起作用,因为编译器会检查“大小”声明的类型并坚持在后面FloatToStr使用MsgBox

我不知道如何将这个数字四舍五入。也许一些不同的方法会有所帮助?

我期待着您的回答!

4

1 回答 1

2

您可以使用该Format功能。

看看这个例子:

procedure TestClick(Sender: TObject);
var
  Size: Extended;
begin
  Size := 0;
  Size := Size + 1512820736
  Size := Size + 635711488;
  Size := Size + 286273536;
  Size := Size / 1024 / 1024 / 1024; { now all sizes have been added and the number is converted to be displayed GB, not bytes }
  MsgBox(Format('%.2f Gb.', [Size]), mbInformation, MB_OK); 
end;

我将数据类型从 更改SingleExtended,将其作为个人选择。

或者使用此函数作为更明智的选择,根据字节数添加正确的维度:

const
  KFactor = 1024;

function FormatBytes(const Bytes: Extended): string;
var
  Amount: Extended;
  Idx: Byte;
  Dms: array[1..5] of string;
  FmtStr: string;
begin
  Dms[1] := 'B'; Dms[2] := 'KB'; Dms[3] := 'MB'; Dms[4] := 'GB'; Dms[5] := 'TB';
  Amount := Bytes;
  Idx := 1;
  while Amount > (0.9 * KFactor) do
  begin
    Idx := Idx + 1;
    Amount := Amount / KFactor;
  end;
  if Abs(Amount - Trunc(Amount)) < 0.07 then
    FmtStr := '%.0f %s'
  else
    FmtStr := '%.2f %s';
  Result := Format(FmtStr, [Amount, Dms[Idx]]);
end;

如果要显示接近精确数量的 KB/MB/GB/TB,则已编辑答案以调整小数位数。

于 2012-11-12T06:40:15.270 回答