title: Inno Setup - Correctly timing update of progress bar
body: <p>I forgotten how to update a progress bar correctly in Inno Setup according to a condition and I wrote a code to update a progress bar I created in Wizard.</p>
  
  <p>The problem is I am getting 95, 96, 97, 98, or 100, 101 for the ProgressBar's last Position and its updating is not same from time to time when I runs my Installer. And the value I used to divide (here it is 6) won't work on all systems similarly as their performance is very different from each system. </p>
  
  <p>I like to know a way to correctly update progress bar without having such problems.</p>
  
  <pre class="lang-pascal prettyprint-override"><code>[Files]
  Source: "C:\Program Files (x86)\Inno Setup 5\Examples\MyProg.exe"; DestDir: "{app}"; Flags: ignoreversion
  Source: "C:\InnoCallback.dll"; DestDir: "{app}"; Flags: ignoreversion
  
  [Code]
  Type
    TTimerProc = procedure(HandleW, msg, idEvent, TimeSys: LongWord);
  
  function SetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc: LongWord): LongWord; external 'SetTimer@User32.dll stdcall';
  function WrapTimerProc(Callback: TTimerProc; ParamCount: Integer): LongWord; external 'wrapcallback@{tmp}\InnoCallback.dll stdcall delayload';
  function KillTimer(hWnd, nIDEvent: LongWord): LongWord; external 'KillTimer@User32.dll stdcall';
  
  var
    TTimer: LongWord;
    ConditionTracker: String;
    P: Integer;
    TestingPB: TNewProgressBar;
  
  procedure Install;
  var
    ErrorCode: Integer;
  begin
    if ShellExec('Open', 'Timeout.exe', '/T 10', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode) = True then
      ConditionTracker := 'DONE';
  end;
  
  procedure UpdateProgressBar(HandleW, msg, idEvent, TimeSys: LongWord);
  begin
    if ConditionTracker = 'DONE' then begin
      KillTimer( 0, TTimer);
      TestingPB.State := npbsPaused;
    end else begin
      P := P + 1;
      Log('ProgressBar Position: ' + IntToStr(P div 6));
      TestingPB.Position := P div 6;
      if (P div 6) = 100 then P := 600;
    end;
  end;
  
  procedure InitializeWizard;
  begin
    TestingPB := TNewProgressBar.Create(WizardForm);
    with TestingPB do begin
      Parent := WizardForm;
      Width := WizardForm.ProgressGauge.Width;
      Top := 200;
      Left := (WizardForm.ClientWidth - Width) div 2;
      Max := 100;
      Position := 0;
      Hide;
      ExtractTemporaryFile('InnoCallback.dll'); 
      P := 0;
    end;
  end;
  
  procedure CurPageChanged(CurPageID: Integer);
  begin
    if CurPageID = wpSelectTasks then begin
      TestingPB.Show;
      TTimer := SetTimer( 0, 0, 0, WrapTimerProc(@UpdateProgressBar, 4));
      Install;
    end else
      TestingPB.Hide;
  end;
  </code></pre>
  
  <p>Thanks in advance.</p>