I use this code to show elapsed time, percent time and estimated time progress:
[Code]
function GetTickCount: DWORD;
external 'GetTickCount@kernel32.dll stdcall';
var
StartTick: DWORD;
PercentLabel: TNewStaticText;
ElapsedLabel: TNewStaticText;
RemainingLabel: TNewStaticText;
function TicksToStr(Value: DWORD): string;
var
I: DWORD;
Hours, Minutes, Seconds: Integer;
begin
I := Value div 1000;
Seconds := I mod 60;
I := I div 60;
Minutes := I mod 60;
I := I div 60;
Hours := I mod 24;
Result := Format('%.2d:%.2d:%.2d', [Hours, Minutes, Seconds]);
end;
procedure InitializeWizard;
begin
PercentLabel := TNewStaticText.Create(WizardForm);
PercentLabel.Parent := WizardForm.ProgressGauge.Parent;
PercentLabel.Left := 0;
PercentLabel.Top := WizardForm.ProgressGauge.Top +
WizardForm.ProgressGauge.Height + 12;
ElapsedLabel := TNewStaticText.Create(WizardForm);
ElapsedLabel.Parent := WizardForm.ProgressGauge.Parent;
ElapsedLabel.Left := 0;
ElapsedLabel.Top := PercentLabel.Top + PercentLabel.Height + 4;
RemainingLabel := TNewStaticText.Create(WizardForm);
RemainingLabel.Parent := WizardForm.ProgressGauge.Parent;
RemainingLabel.Left := 0;
RemainingLabel.Top := ElapsedLabel.Top + ElapsedLabel.Height + 4;
end;
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpInstalling then
StartTick := GetTickCount;
end;
procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
if CurPageID = wpInstalling then
begin
Cancel := False;
if ExitSetupMsgBox then
begin
Cancel := True;
Confirm := False;
PercentLabel.Visible := False;
ElapsedLabel.Visible := False;
RemainingLabel.Visible := False;
end;
end;
end;
procedure CurInstallProgressChanged(CurProgress, MaxProgress: Integer);
var
CurTick: DWORD;
begin
CurTick := GetTickCount;
PercentLabel.Caption :=
Format('Done: %.2f %%', [(CurProgress * 100.0) / MaxProgress]);
ElapsedLabel.Caption :=
Format('Elapsed: %s', [TicksToStr(CurTick - StartTick)]);
if CurProgress > 0 then
begin
RemainingLabel.Caption :=
Format('Remaining: %s', [TicksToStr(
((CurTick - StartTick) / CurProgress) * (MaxProgress - CurProgress))]);
end;
end;
This code show this with my code:
How to update the progress bar to match 100% with the end of the progress bar?
I need to add more information? (Sorry for my bad English)
There's not much, you can do about this.
On modern versions of Windows, with the Aero themes, the progress bar has an "animation" effect. When you change progress bar position, it does not jump straight to the position, but instead animates the jump. For the animation to work, Window message queue must be pumped.
During last steps of the installation (after files are copied), Inno Setup stalls briefly and do not pump the queue. So while the progress bar is actually set to 100% position and the CurInstallProgressChanged
is called with CurProgress
equal to the MaxProgress
, visually the progress bar is not at 100% yet, because the animation is pending. And the animation actually never completes, because the progress bar is hidden before the animation is allowed to complete.
If you disable visual themes in Windows, what reverts the progress bar to legacy animation-less mode, you will see that the problem goes away.
The following screenshots are both from the same installation of Windows 7.
Windows Classic theme:
Windows 7 Aero Theme:
All you can probably do, is to use the hack shown here:
Disabling .NET progressbar animation when changing value?
procedure CurInstallProgressChanged(CurProgress, MaxProgress: Integer);
begin
WizardForm.ProgressGauge.Position := WizardForm.ProgressGauge.Position - 1;
WizardForm.ProgressGauge.Update;
{ ... }
end;
Though you will lose the animation effect.
And you obviously still cannot reach the 100%, but you can get very close to it: