Объединение этих двух кусок кода вместе:
Обратите внимание на недостатки использования расширения DLL в деинсталлятора, описанной в question linked from the first question above.
[Files]
Source: "InnoCallback.dll"; DestDir: "{app}"
[Code]
type
TTimerProc = procedure(H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
function SetTimer(hWnd: longword; nIDEvent, uElapse: LongWord;
lpTimerFunc: LongWord): LongWord; external '[email protected] stdcall';
function GetTickCount: DWORD;
external '[email protected] stdcall';
function WrapTimerProcUninstall(Callback: TTimerProc; ParamCount: Integer): LongWord;
external '[email protected]{%TEMP}\innocallback.dll stdcall uninstallonly delayload';
var
UninstallStartTick: DWORD;
UninstallPercentLabel: TNewStaticText;
UninstallElapsedLabel: TNewStaticText;
UninstallRemainingLabel: 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 CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
if CurUninstallStep = usUninstall then
begin
UninstallStartTick := GetTickCount;
end;
end;
procedure UninstallTimerProc(
h: LongWord; AMsg: LongWord; IdEvent: LongWord; dwTime: LongWord);
var
CurTick: DWORD;
CurProgress: Integer;
MaxProgress: Integer;
begin
MaxProgress := UninstallProgressForm.ProgressBar.Max;
CurProgress := UninstallProgressForm.ProgressBar.Position;
if MaxProgress > 0 then
begin
CurTick := GetTickCount;
UninstallPercentLabel.Caption :=
Format('Done: %.2f %%', [(CurProgress * 100.0)/MaxProgress]);
UninstallElapsedLabel.Caption :=
Format('Elapsed: %s', [TicksToStr(CurTick - UninstallStartTick)]);
if CurProgress > 0 then
begin
UninstallRemainingLabel.Caption :=
Format('Remaining: %s', [TicksToStr(
((CurTick - UninstallStartTick)/CurProgress) * (MaxProgress - CurProgress))]);
end;
end;
end;
procedure InitializeUninstallProgressForm();
var
TimerCallback: LongWord;
begin
UninstallPercentLabel := TNewStaticText.Create(UninstallProgressForm);
UninstallPercentLabel.Parent := UninstallProgressForm.ProgressBar.Parent;
UninstallPercentLabel.Left := UninstallProgressForm.ProgressBar.Left;
UninstallPercentLabel.Top := UninstallProgressForm.ProgressBar.Top +
UninstallProgressForm.ProgressBar.Height + ScaleY(12);
UninstallElapsedLabel := TNewStaticText.Create(UninstallProgressForm);
UninstallElapsedLabel.Parent := UninstallProgressForm.ProgressBar.Parent;
UninstallElapsedLabel.Left := UninstallPercentLabel.Left;
UninstallElapsedLabel.Top :=
UninstallPercentLabel.Top + UninstallPercentLabel.Height + ScaleY(4);
UninstallRemainingLabel := TNewStaticText.Create(UninstallProgressForm);
UninstallRemainingLabel.Parent := UninstallProgressForm.ProgressBar.Parent;
UninstallRemainingLabel.Left := UninstallPercentLabel.Left;
UninstallRemainingLabel.Top :=
UninstallElapsedLabel.Top + UninstallElapsedLabel.Height + ScaleY(4);
if FileCopy(
ExpandConstant(
'{app}\innocallback.dll'), ExpandConstant('{%TEMP}\innocallback.dll'), False) then
begin
TimerCallback := WrapTimerProcUninstall(@UninstallTimerProc, 4);
SetTimer(0, 0, 100, TimerCallback); { every 100 ms }
end;
end;