Search code examples
inno-setuppascalscript

Merging event function (InitializeWizard) implementations from different sources


I am now combining the script that I want but it has an error.

Screenshot

When I put a period, it will run but missing other feature.

Here is my code:

procedure InitializeWizard;
begin
  MessageBoxTimeout(WizardForm.Handle, 'MsgBox ' +
    Timeout 'Setup', MB_OK or MB_ICONINFORMATION, 0, 2000);
end;

var
  TuneLabel: TLabel;

begin
  ExtractTemporaryFile('tune.xm');
  if BASS_Init(-1, 44100, 0, 0, 0) then
  begin
    SoundCtrlButton := TNewButton.Create(WizardForm);
    Music := BASS_MusicLoad(False, 
      ExpandConstant('{tmp}\tune.xm'), 0, 0, 
      EncodingFlag or BASS_SAMPLE_LOOP, 0);
    BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, 10000);
    BASS_ChannelPlay(Music, False);

    SoundCtrlButton := TNewButton.Create(WizardForm);
    SoundCtrlButton.Parent := WizardForm;
    SoundCtrlButton.Left := 10;
    SoundCtrlButton.TabStop := False;
    SoundCtrlButton.Top := WizardForm.ClientHeight - 
      SoundCtrlButton.Height - 9;
    SoundCtrlButton.Width := 40;
    SoundCtrlButton.Caption :=
      ExpandConstant('{cm:SoundCtrlButtonCaptionSoundOff}');
    SoundCtrlButton.OnClick := @SoundCtrlButtonClick;
    TuneLabel := TLabel.Create(WizardForm);
    TuneLabel.Parent := WizardForm;
    TuneLabel.Caption := 'Tune';
    TuneLabel.Left := SoundCtrlButton.Left + SoundCtrlButton.Width + ScaleX(5);
    TuneLabel.Top :=
      SoundCtrlButton.Top + ((SoundCtrlButton.Height - TuneLabel.Height) div 2);
  end;
end;

The error refers to a line after the last end;.

Please help me through.


Solution

  • When you are reusing various feature implementations from different sources, those commonly implement the same Inno Setup event functions (like the InitializeWizard).

    The solution for Inno Setup 6 is very simple, as shown below. In older versions it's more complicated. See lower.


    Inno Setup 6

    Inno Setup 6 has event attributes features that helps solving this problem.

    Just make sure that each of your event implementation have an unique name, e.g. appending unique suffix. And add event attribute with the name of the implemented event.

    [Code]
    procedure InitializeWizard;
    begin
      Log('InitializeWizard called');
    end;
    
    <event('InitializeWizard')>
    procedure InitializeWizard2;
    begin
      Log('InitializeWizard2 called');
    end;
    

    Inno Setup 5

    In old versions of Inno Setup that does not support the event attributes, you have to merge these event functions as there can be just one function implementation.

    You can do that by appending unique suffix to the different implementation and than calling them from a main implementation.

    The main implementation have to be below the other implementations.

    For example, if one source has InitializeWizard event function implemented as:

    var
      GlobalVariable1: Integer;
    
    procedure SubProcedure1;
    begin
      { blah }
    end;
    
    procedure InitializeWizard;
    var
      Variable1: Integer;
      Variable2: Integer;
    begin
      Variable1 := GlobalVariable1;
      SubProcedure1;
    end;
    

    And the other source as:

    var
      GlobalVariableA: Integer;
    
    procedure SubProcedureA;
    begin
      { blah }
    end;
    
    procedure InitializeWizard;
    var
      VariableA: Integer;
    begin
      VariableA := GlobalVariableA;
      SubProcedureA;
    end;
    

    Then merged code should be:

    var
      GlobalVariable1: Integer;
    
    procedure SubProcedure1;
    begin
      { blah }
    end;
    
    procedure InitializeWizard1;
    var
      Variable1: Integer;
      Variable2: Integer;
    begin
      Variable1 := GlobalVariable1;
      SubProcedure1;
    end;
    
    var
      GlobalVariableA: Integer;
    
    procedure SubProcedureA;
    begin
      { blah }
    end;
    
    procedure InitializeWizard2;
    var
      VariableA: Integer;
    begin
      VariableA := GlobalVariableA;
      SubProcedureA;
    end;
    
    procedure InitializeWizard;
    begin
      InitializeWizard1;
      InitializeWizard2;
    end;
    

    See also Inno Setup - Merging implementations of event functions that return boolean (like InitializeSetup).


    So, in your specific case the code should be:

    procedure InitializeWizard1;
    begin
      MessageBoxTimeout(WizardForm.Handle, 'MsgBox ' +
        Timeout 'Setup', MB_OK or MB_ICONINFORMATION, 0, 2000);
    end;
    
    procedure InitializeWizard2;
    var
      TuneLabel: TLabel;
    begin
      ExtractTemporaryFile('tune.xm');
      if BASS_Init(-1, 44100, 0, 0, 0) then
      begin
        SoundCtrlButton := TNewButton.Create(WizardForm);
        Music := BASS_MusicLoad(False, 
          ExpandConstant('{tmp}\tune.xm'), 0, 0, 
          EncodingFlag or BASS_SAMPLE_LOOP, 0);
        BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, 10000);
        BASS_ChannelPlay(Music, False);
    
        SoundCtrlButton := TNewButton.Create(WizardForm);
        SoundCtrlButton.Parent := WizardForm;
        SoundCtrlButton.Left := 10;
        SoundCtrlButton.TabStop := False;
        SoundCtrlButton.Top := WizardForm.ClientHeight - 
          SoundCtrlButton.Height - 9;
        SoundCtrlButton.Width := 40;
        SoundCtrlButton.Caption :=
          ExpandConstant('{cm:SoundCtrlButtonCaptionSoundOff}');
        SoundCtrlButton.OnClick := @SoundCtrlButtonClick;
        TuneLabel := TLabel.Create(WizardForm);
        TuneLabel.Parent := WizardForm;
        TuneLabel.Caption := 'Tune';
        TuneLabel.Left := SoundCtrlButton.Left + SoundCtrlButton.Width + ScaleX(5);
        TuneLabel.Top :=
          SoundCtrlButton.Top + ((SoundCtrlButton.Height - TuneLabel.Height) div 2);
      end;
    end;
    
    procedure InitializeWizard;
    begin
      InitializeWizard1;
      InitializeWizard2;
    end;
    

    If you are using Inno Setup Script #Includes (ISSI), see Implementing event functions InitializeWizard while using ISSI (to add background image) in Inno Setup: Duplicate identifier 'INITIALIZEWIZARD'.