Inno Setup-отображение нескольких изображений (слайд-шоу) на странице wpInstalling в строке ProgressGauge
я подготовил простой скрипт, который отображает изображения под ProgressGauge
bar on wpInstalling
страница.
но... Мне нужна более сложная функциональность.
мне нужно несколько изображений, каждое после X (например, 7) секунд (с циклом при установке дольше, чем X секунд * количество изображений) или каждый после X (например, 10) процентов установки. Я попытался встроить отображение изображений в ProgressGauge.Position
, но я потерпел неудачу.
вот что у меня есть:
procedure CurPageChanged(CurPageID: Integer);
var
BmpFile: TBitmapImage;
begin
ExtractTemporaryFile('01.bmp');
ExtractTemporaryFile('02.bmp');
ExtractTemporaryFile('03.bmp');
if CurPageID = wpInstalling then
begin
BmpFile:= TBitmapImage.Create(WizardForm);
BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}.bmp'));
BmpFile.Width:= ScaleX(420);
BmpFile.Height:= ScaleY(180);
BmpFile.Left := WizardForm.ProgressGauge.Left + ScaleX(0);
BmpFile.Top := WizardForm.ProgressGauge.Top + ScaleY(35);
// BmpFile.Parent:= WizardForm.InstallingPage;
// BmpFile:= TBitmapImage.Create(WizardForm);
// BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}.bmp'));
// BmpFile.Width:= ScaleX(420);
// BmpFile.Height:= ScaleY(400);
// BmpFile.Left := WizardForm.ProgressGauge.Left + ScaleX(0);
// BmpFile.Top := WizardForm.ProgressGauge.Top + ScaleY(35);
// BmpFile.Parent:= WizardForm.InstallingPage;
// BmpFile:= TBitmapImage.Create(WizardForm);
// BmpFile.Bitmap.LoadFromFile(ExpandConstant('{tmp}.bmp'));
// BmpFile.Width:= ScaleX(420);
// BmpFile.Height:= ScaleY(400);
// BmpFile.Left := WizardForm.ProgressGauge.Left + ScaleX(0);
// BmpFile.Top := WizardForm.ProgressGauge.Top + ScaleY(35);
// BmpFile.Parent:= WizardForm.InstallingPage;
end;
end;
цель есть:
На wpInstalling
должны отображаться изображения X, каждые следующие X секунд или после X процентов установки.
2 ответов
С ProgressGauge
не имеет событий изменения прогресса, и нет способа обработать сообщения приложения установки, вам нужно будет использовать таймер Windows API. Этот таймер нуждается в функции обратного вызова, которую вы не можете определить в сценарии установки Inno, к сожалению, поэтому вам понадобится внешняя библиотека для выполнения этой работы. Однако есть InnoCallback
библиотека, которая может сделать именно это.
для следующего кода скопируйте InnoCallback.dll
библиотека в каталог установки, объединить этот код со сценарием установки Inno и реализовать какой-то слайд-шоу страницы превращения в OnSlideTimer
событие, которое будет вызываться периодически (с текущими настройками каждую секунду).
[Files]
Source: "InnoCallback.dll"; DestDir: "{tmp}"; Flags: dontcopy
[code]
var
TimerID: Integer;
type
TTimerProc = procedure(Wnd: HWND; Msg: UINT; TimerID: UINT_PTR;
SysTime: DWORD);
function WrapTimerProc(Callback: TTimerProc; ParamCount: Integer): LongWord;
external 'wrapcallback@files:InnoCallback.dll stdcall';
function SetTimer(hWnd: HWND; nIDEvent, uElapse: UINT;
lpTimerFunc: UINT): UINT; external 'SetTimer@user32.dll stdcall';
function KillTimer(hWnd: HWND; uIDEvent: UINT): BOOL;
external 'KillTimer@user32.dll stdcall';
procedure OnSlideTimer(Wnd: HWND; Msg: UINT; TimerID: UINT_PTR;
SysTime: DWORD);
begin
{ here you can turn your slideshow pages; use some variable to store the }
{ current index of the slide you are on, note that this procedure is called }
{ periodically each 1000 ms (see below why), so here you can also check the }
{ progress value, if you want to }
end;
procedure StartSlideTimer;
var
TimerCallback: LongWord;
begin
TimerCallback := WrapTimerProc(@OnSlideTimer, 4);
{ third parameter here is the timer's timeout value in milliseconds }
TimerID := SetTimer(0, 0, 1000, TimerCallback);
end;
procedure KillSlideTimer;
begin
if TimerID <> 0 then
begin
if KillTimer(0, TimerID) then
TimerID := 0;
end;
end;
function InitializeSetup: Boolean;
begin
Result := True;
TimerID := 0;
end;
procedure DeinitializeSetup;
begin
KillSlideTimer;
end;
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpInstalling then
StartSlideTimer
else
KillSlideTimer;
end;