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;

Почему бы не использовать AfterInstall для каждой записи файла для изменения изображения?