Merging event function (InitializeWizard) implementations from different sources

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'.