Search code examples
inno-setuppascalscript

Using combo box to select what paths and registry keys to use


Purpose:

With Inno Setup I want to create an installer with a dropdown list in the install wizard.

The choice made in the wizards defines 2 variables:
One for the folder location and the other for the location in the registry.

Problem:

Variables are defined as global in [Code], but are not used in [Files] and [Registry]

Code:

The two variables are: strData1 & strData2

I was trying to retrieve them with functions: strData1returner & strData2returner

[Setup]
...

[Dirs]    
Name: "C:\Program Files\CompanyName\{code:strData1returner}"

[Files]
Source: "C:\SomeDll.dll"; \
  DestDir: "C:\Program Files\CompanyName\{code:strData1returner}\"; Flags: ignoreversion;

[Registry]
Root: HKCU; subkey: "{code:strData2returner}"; flags: createvalueifdoesntexist

[Code]
var
  Button: TNewButton;
  ComboBox: TNewComboBox;
  CustomPage: TWizardPage;     
  strData1: string;
  strData2: string;

procedure ComboBoxChange(Sender: TObject);
begin
  case ComboBox.ItemIndex of
    0:
    begin
      strData1 := 'Subfolder';
      strData2 := 'SOFTWARE\CompanyName';
    end;
  end;
end;

procedure InitializeWizard;
var
  DescLabel: TLabel;
begin
  CustomPage := CreateCustomPage(wpSelectDir, 'Caption', 'Description');

  DescLabel := TLabel.Create(WizardForm);
  DescLabel.Parent := CustomPage.Surface;
  DescLabel.Left := 0;
  DescLabel.Top := 0;
  DescLabel.Caption := 'Select an item...';

  ComboBox := TNewComboBox.Create(WizardForm);
  ComboBox.Parent := CustomPage.Surface;
  ComboBox.Left := 0;
  ComboBox.Top := DescLabel.Top + DescLabel.Height + 6;  
  ComboBox.Width := 220;
  ComboBox.Style := csDropDownList;
  ComboBox.Items.Add('Choice1');
  ComboBox.ItemIndex := 0;
  ComboBox.OnChange := @ComboBoxChange;
end;

function strData1returner(Param: String): String;
begin
  Result :=  strData1;
end;

function strData2returner(Param: String): String;
begin
  Result :=  strData2;
end;

Solution

  • There was only a single option: "Choice1" - So I added a second (Choice2), and alternative values for that second option, under index 1.

    You should also initialize the two variables in InitializeWizard, in case the user doesn't change the combobox value. The ComboBoxChange procedure is only executed when the value actually changes, not when the default is accepted via no action.

    Also, in trying to reproduce your problem I noticed a syntax problem causing compilation errors with createvalueifdoesntexistcreatevalueifdoesntexist - naturally, you just need one of those.

    [Dirs]    
    Name: "C:\Program Files\CompanyName\{code:strData1returner}"
    
    [Files]
    Source: "C:\SomeDll.dll"; DestDir: "C:\Program Files\CompanyName\{code:strData1returner}\"; Flags: ignoreversion;
    
    [Registry]
    Root: HKCU; subkey:"{code:strData2returner}"; flags: createvalueifdoesntexist
    
    [Code]
    var
      Button: TNewButton;
      ComboBox: TNewComboBox;
      CustomPage: TWizardPage;     
      strData1: string;
      strData2: string;
    
    procedure ComboBoxChange(Sender: TObject);
    begin
      case ComboBox.ItemIndex of
        0:
        begin
          strData1 := 'Subfolder';
          strData2 := 'SOFTWARE\CompanyName';
        end;
        1:
        begin
          strData1 := 'Subfolder2';
          strData2 := 'SOFTWARE\CompanyName2';
        end;
      end;
    end;
    
    procedure InitializeWizard;
    var
      DescLabel: TLabel;
    begin
      CustomPage := CreateCustomPage(wpSelectDir, 'Caption', 'Description');
    
      DescLabel := TLabel.Create(WizardForm);
      DescLabel.Parent := CustomPage.Surface;
      DescLabel.Left := 0;
      DescLabel.Top := 0;
      DescLabel.Caption := 'Select an item...';
    
      ComboBox := TNewComboBox.Create(WizardForm);
      ComboBox.Parent := CustomPage.Surface;
      ComboBox.Left := 0;
      ComboBox.Top := DescLabel.Top + DescLabel.Height + 6;  
      ComboBox.Width := 220;
      ComboBox.Style := csDropDownList;
      ComboBox.Items.Add('Choice1');
      ComboBox.Items.Add('Choice2');
      ComboBox.ItemIndex := 0;
      ComboBox.OnChange := @ComboBoxChange;
      strData1 := 'Subfolder';
      strData2 := 'SOFTWARE\CompanyName';
    end;
    
    function strData1returner(Param: String): String;
    begin
      Result :=  strData1;
    end;
    
    function strData2returner(Param: String): String;
    begin
      Result :=  strData2;
    end;
    

    The code above is working as I think you expect it to here.