Вопрос Вывод размера из SpaceComponentsLabel

Tolyak26

Новичок
Есть скрипт. В нем я сделал вывод размера программы в байтах, килобайтах, мегабайтах и т.д. Как вырезать лишние пробелы для значений в строке SpaceComponentsLabel.Caption. Пытался юзать Trim(); но не работает.

Код:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program


[Components]
Name: a; Description: 1; ExtraDiskSpaceRequired: 2641404888; Types: full;
Name: b; Description: 2; ExtraDiskSpaceRequired: 26214400; Types: full
Name: c; Description: 3; ExtraDiskSpaceRequired: 41943040; Types: full



[Code]
var
    OldCompListOnClickCheckProc: TNotifyEvent;
    SpaceComponentsLabel: TLabel;
    DiskSpace: Extended;


function GetFloatFormText(const UndefText: String): Extended;
var
  i: Integer;
  ss: string;
begin
  for i := 1 to Length(UndefText) do
  case UndefText[i] of
    '0','1','2','3','4','5','6','7','8','9': ss := ss + UndefText[i];
    ',': ss := ss + '.';
  end;
  Result:= StrToFloat(Trim(ss));
end;

function NumToStr(Float: Extended): string;
begin
  Result:= Format('%.2n', [Float]);
  StringChange(Result, ',', '.');
while ((Result[Length(Result)] = '0') or (Result[Length(Result)] = '.')) and (Pos('.', Result) > 0) do
  SetLength(Result, Length(Result)-1);
end;

function ToByte(Float: Extended): string;
begin
Result:= NumToStr(Float*1048576);
end;

function ToKB(Float: Extended): string;
begin
Result:= NumToStr(Float*1024);
end;

function ToMB(Float: Extended): string;
begin
Result:= NumToStr(Float);
end;

function ToGB(Float: Extended): string;
begin
Result:= NumToStr(Float/1024);
end;

function ToTB(Float: Extended): string;
begin
Result:= NumToStr(Float/(1024*1024));
end;

procedure ComponentsListOnClickCheck(Sender: TObject);
begin
    OldCompListOnClickCheckProc(TNewCheckListBox(Sender));
    DiskSpace:= GetFloatFormText(WizardForm.ComponentsDiskSpaceLabel.Caption)-GetFloatFormText(WizardForm.DiskSpaceLabel.Caption);
    SpaceComponentsLabel.Caption := 'Б: '+ToByte(DiskSpace)+' | КБ: '+ToKB(DiskSpace)+' | МБ: '+ToMB(DiskSpace)+' | ГБ: '+ToGB(DiskSpace)+' | ТБ: '+ToTB(DiskSpace);
end;

procedure InitializeWizard();
var
  i: Integer;
  k: Array [0..99] of Boolean;
begin
    WizardForm.ComponentsDiskSpaceLabel.Hide;
    OldCompListOnClickCheckProc := WizardForm.ComponentsList.OnClickCheck;
    for i:=0 to WizardForm.ComponentsList.ItemCount-1 do
    if WizardForm.ComponentsList.Checked[i] then
    k[i]:= True;
    for i:=0 to WizardForm.ComponentsList.ItemCount-1 do
    WizardForm.ComponentsList.Checked[i]:= False;
    WizardForm.ComponentsList.OnClickCheck(nil);
    for i:=0 to WizardForm.ComponentsList.ItemCount-1 do
    WizardForm.ComponentsList.Checked[i]:= k[i];
    OldCompListOnClickCheckProc(nil);
    WizardForm.ComponentsList.OnClickCheck := @ComponentsListOnClickCheck;

    SpaceComponentsLabel:= TLabel.Create(nil);
    with SpaceComponentsLabel do
    begin
        Parent := WizardForm.SelectComponentsPage;
        SetBounds(ScaleX(WizardForm.ComponentsDiskSpaceLabel.Left), ScaleY(WizardForm.ComponentsDiskSpaceLabel.Top), ScaleX(WizardForm.ComponentsDiskSpaceLabel.Width), ScaleY(WizardForm.ComponentsDiskSpaceLabel.Height));
        AutoSize := False;
        Font.Style := [fsBold];
    end;
end;


procedure CurPageChanged(CurPageID: Integer);
begin
    case CurPageID of
        wpSelectComponents: ComponentsListOnClickCheck(WizardForm.ComponentsList);
    end;
end;

т.е. нужно убрать пробелы между цифрами:


Но Trim(); и ему подобные функции не дают должного результата.
 
Последнее редактирование:

Шуль

Новичок
Я к сожалению не смогу помочь, но хочу сказать - с пробелами выглядит лучше.
 

Tolyak26

Новичок
Я к сожалению не смогу помочь, но хочу сказать - с пробелами выглядит лучше.
В данном случае мне нужно убрать эти пробелы для того что бы менять значение "UninstallDisplaySize=" в [Setup] в зависимости от выбранных компонетов и их размеров.
 

Nemko

Дилетант
Модератор
Tolyak26, замените функцию NumToStr на эту. Чет я перемудрил (наверное), но это первое что пришло в голову (избавится от функции Format).

Код:
function NumToStr(Float: Extended): string;
var
  i: integer;
  s: string;
begin
  s:= FloatToStr(Float);
for i:=1 to Length(s) do begin
  if (s[i] = '.') then begin
    if (s[i+2] <> '0') and (i+2 < Length(s)) then begin
      Result:=Result+'.';
      Result:=Result+s[i+1];
      if (s[i+2] <> '0') and (i+2 < Length(s)) then Result:=Result+s[i+2];
     end;
    exit;
   end;
  if (s[i] <> ' ') then Result:=Result+s[i] else Continue;
 end;
end;
 
Последнее редактирование:

sergey3695

Ветеран
Модератор
Код:
  TotalNeedSize:= {#TotalNeedSize}*1024; // TotalNeedSize: Cardinal; в мб.
if IsWin64 then
  RegWriteDWordValue(HKLM,'Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{#AppId}_is1', 'EstimatedSize',TotalNeedSize)
else
  RegWriteDWordValue(HKLM,'Software\Microsoft\Windows\CurrentVersion\Uninstall\{#AppId}_is1', 'EstimatedSize',TotalNeedSize);
 

Tolyak26

Новичок
Я попробую ваши варианты чуть позже. Нашел баг, что когда запускаешь инсталлятор на en-us версии Windows то получаешь это безобразие:

Тот же неизмененный код, что и в первом посту. Те же выбранные компоненты. Та же расширенная версия сборки 5.5.1.ee2 Unicode.

Но прикол в том, что все работает прекрасно на ru-ru версии.

Компиляция в обеих системах ничего не дает.
 

sergey3695

Ветеран
Модератор
т.е. нужно убрать пробелы между цифрами
там нет пробелов.
Format
Result:= Format('%.2n', [Float]); -> Result:= Format('%.2f', [Float]);
Код:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
OutputDir=.

[Components]
Name: a; Description: 1; ExtraDiskSpaceRequired: 2641404888; Types: full;
Name: b; Description: 2; ExtraDiskSpaceRequired: 26214400; Types: full
Name: c; Description: 3; ExtraDiskSpaceRequired: 41943040; Types: full

[Code]
var
    OldCompListOnClickCheckProc: TNotifyEvent;
    SpaceComponentsLabel: TLabel;
    DiskSpace: Extended;

function GetFloatFormText(const UndefText: String): Extended;
var
  i: Integer;
  ss: string;
begin
  ss:= '';
  for i := 1 to Length(UndefText) do
  case UndefText[i] of
    '0','1','2','3','4','5','6','7','8','9': ss := ss + UndefText[i];
    ',': ss := ss + '.';
  end;
  Result:= StrToFloat(ss);
end;

function NumToStr(Float: Extended): string;
begin
  Result:= Format('%.2f', [Float]);
  StringChange(Result, ',', '.');
while ((Result[Length(Result)] = '0') or (Result[Length(Result)] = '.')) and (Pos('.', Result) > 0) do
  SetLength(Result, Length(Result)-1);
end;

function ToByte(Float: Extended): string;
begin
  Result:= NumToStr(Float*1048576);
end;

function ToKB(Float: Extended): string;
begin
  Result:= NumToStr(Float*1024);
end;

function ToMB(Float: Extended): string;
begin
  Result:= NumToStr(Float);
end;

function ToGB(Float: Extended): string;
begin
  Result:= NumToStr(Float/1024);
end;

function ToTB(Float: Extended): string;
begin
  Result:= NumToStr(Float/(1024*1024));
end;

procedure ComponentsListOnClickCheck(Sender: TObject);
begin
    OldCompListOnClickCheckProc(nil);
    DiskSpace:= GetFloatFormText(WizardForm.ComponentsDiskSpaceLabel.Caption)-GetFloatFormText(WizardForm.DiskSpaceLabel.Caption);
    SpaceComponentsLabel.Caption := 'Б: '+ToByte(DiskSpace)+' | КБ: '+ToKB(DiskSpace)+' | МБ: '+ToMB(DiskSpace)+' | ГБ: '+ToGB(DiskSpace)+' | ТБ: '+ToTB(DiskSpace);
end;

procedure InitializeWizard();
begin
    WizardForm.ComponentsDiskSpaceLabel.Hide;

    SpaceComponentsLabel:= TLabel.Create(WizardForm);
    with SpaceComponentsLabel do
    begin
        Parent := WizardForm.SelectComponentsPage;
        SetBounds(WizardForm.ComponentsDiskSpaceLabel.Left, WizardForm.ComponentsDiskSpaceLabel.Top, WizardForm.ComponentsDiskSpaceLabel.Width, WizardForm.ComponentsDiskSpaceLabel.Height);
        AutoSize := False;
        WordWrap := False;
        Font.Style := [fsBold];
    end;
    OldCompListOnClickCheckProc := WizardForm.ComponentsList.OnClickCheck;
    WizardForm.ComponentsList.OnClickCheck := @ComponentsListOnClickCheck;
    ComponentsListOnClickCheck(nil);
end;
 

Tolyak26

Новичок
там нет пробелов.
Format
Result:= Format('%.2n', [Float]); -> Result:= Format('%.2f', [Float]);
Я смотрел про format у float, но что-то недоуяснил. В принципе это то, что мне и требовалось. Теперь остается решить баг с англоязычным вариантом инсталлятора вместе с этим кодом. Спасибо.
 

Tolyak26

Новичок
sergey3695, пока я заметил то, что если общий размер программы равен 1047527424 байт (999 мегабайт) и больше, то значения в байтах, килобайтах и т.д. начинают уходить в минус и принимать неадекватно большие отрицательные значения как на втором скриншоте.

Если меньше 999 мегабайт, то они в 10 раз больше становятся от изначальных, т.е. если я у компонента указываю размер в 10 мегабайт и , то код его показывает в 10 раз больше, т.е. в итоге получается 100 МБ. Опять же по непонятным мне причинам это происходит только на EN-US версии Windows, установленной с en_ оригинального образа.


Если поделить Float на 10, то общий размер компонентов меньше 999 мегабайт уже принимает действительно верные значения.

Result:= Format('%.2f', [Float/10]);




Если для размеров меньше 999 мегабайт все исправляется через костыли, то что делать с размером больше 999 мегабайт я пока не сообразил.

На RU-RU версии Windows без Float/10:
 
Последнее редактирование:

Edison007

Ветеран
Модератор
Скорее всего дело в разделителях
если присмотреться в ру версии это пробел, а в английской запятая
 

Tolyak26

Новичок
Скорее всего дело в разделителях
если присмотреться в ру версии это пробел, а в английской запятая
Так оно и есть.

Код:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program


[Components]
Name: a; Description: 1; ExtraDiskSpaceRequired: 1048576000; Types: full;
Name: b; Description: 2; ExtraDiskSpaceRequired: 26214400; Types: full
Name: c; Description: 3; ExtraDiskSpaceRequired: 1047527424; Types: full
Name: d; Description: 4; ExtraDiskSpaceRequired: 943718400; Types: full



[Code]
var
    OldCompListOnClickCheckProc: TNotifyEvent;
    SpaceComponentsLabel: TLabel;
    DiskSpace: Extended;


function GetFloatFormText(const UndefText: String): Extended;
var
  i: Integer;
  ss: string;
begin
  ss:= '';
  for i := 1 to Length(UndefText) do
  case UndefText[i] of
    '0','1','2','3','4','5','6','7','8','9': ss := ss + UndefText[i];
//    ',': ss := ss + '.';
  end;
  Result:= StrToFloat(ss);
end;

function NumToStr(Float: Extended): string;
begin
  Result:= Format('%.2f', [Float/10]);
  StringChange(Result, ',', '.');
while ((Result[Length(Result)] = '0') or (Result[Length(Result)] = '.')) and (Pos('.', Result) > 0) do
  SetLength(Result, Length(Result)-1);
end;

function ToByte(Float: Extended): string;
begin
Result:= NumToStr(Float*1048576);
end;

function ToKB(Float: Extended): string;
begin
Result:= NumToStr(Float*1024);
end;

function ToMB(Float: Extended): string;
begin
Result:= NumToStr(Float);
end;

function ToGB(Float: Extended): string;
begin
Result:= NumToStr(Float/1024);
end;

function ToTB(Float: Extended): string;
begin
Result:= NumToStr(Float/(1024*1024));
end;

procedure ComponentsListOnClickCheck(Sender: TObject);
begin
    OldCompListOnClickCheckProc(TNewCheckListBox(Sender));
    DiskSpace:= GetFloatFormText(WizardForm.ComponentsDiskSpaceLabel.Caption)-GetFloatFormText(WizardForm.DiskSpaceLabel.Caption);
    SpaceComponentsLabel.Caption := 'Б: '+ToByte(DiskSpace)+' | КБ: '+ToKB(DiskSpace)+' | МБ: '+ToMB(DiskSpace)+' | ГБ: '+ToGB(DiskSpace)+' | ТБ: '+ToTB(DiskSpace);
end;

procedure InitializeWizard();
var
  i: Integer;
  k: Array [0..99] of Boolean;
begin
    WizardForm.ComponentsDiskSpaceLabel.Hide;
    OldCompListOnClickCheckProc := WizardForm.ComponentsList.OnClickCheck;
    for i:=0 to WizardForm.ComponentsList.ItemCount-1 do
    if WizardForm.ComponentsList.Checked[i] then
    k[i]:= True;
    for i:=0 to WizardForm.ComponentsList.ItemCount-1 do
    WizardForm.ComponentsList.Checked[i]:= False;
    WizardForm.ComponentsList.OnClickCheck(nil);
    for i:=0 to WizardForm.ComponentsList.ItemCount-1 do
    WizardForm.ComponentsList.Checked[i]:= k[i];
    OldCompListOnClickCheckProc(nil);
    WizardForm.ComponentsList.OnClickCheck := @ComponentsListOnClickCheck;

    SpaceComponentsLabel:= TLabel.Create(nil);
    with SpaceComponentsLabel do
    begin
        Parent := WizardForm.SelectComponentsPage;
        SetBounds(ScaleX(WizardForm.ComponentsDiskSpaceLabel.Left), ScaleY(WizardForm.ComponentsDiskSpaceLabel.Top), ScaleX(WizardForm.ComponentsDiskSpaceLabel.Width), ScaleY(WizardForm.ComponentsDiskSpaceLabel.Height));
        AutoSize := False;
        Font.Style := [fsBold];
    end;
end;


procedure CurPageChanged(CurPageID: Integer);
begin
    case CurPageID of
        wpSelectComponents: ComponentsListOnClickCheck(WizardForm.ComponentsList);
    end;
end;

Я не знаю, правильным ли было решение закомментировать ',': ss := ss + '.'; , но факт в том что это решает проблему и дает мне то, что и требовалось от кода на обеих системах с разными языками. Ну и еще я оставил деление Float на 10, ибо размер все равно по-умолчанию получается в 10 раз больше, но уже нет отрицательных неадекватных значений.
 

sergey3695

Ветеран
Модератор
Сверху