7

我准备了简单的脚本,ProgressGauge在页面的栏下显示图像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}\01.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}\03.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}\03.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;  

目标是:每隔 X 秒或 X% 的安装后,应该显示 X 个图像
wpInstalling

4

1 回答 1

9

Since the ProgressGauge has no progress change events and there is no way to process setup application messages you will need to use the Windows API timer. This timer needs a callback function which you can't define in Inno Setup script unfortunately so you will need some external library to do this job for you. However there's the InnoCallback library which can do exactly this.

For the following code copy the InnoCallback.dll library into your setup directory, merge this code with your Inno Setup script and implement some kind of a slideshow page turning in the OnSlideTimer event which will be called periodically (with the current settings each second).

[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;
于 2012-04-12T19:44:38.417 回答