4

I've a file the must be installed only if a specific component is also installed. But I also allow custom install. So there is the need to auto-check the component if a specific component is also checked (and vice versa, disable if the other component is not enabled). I know I can simply attach the file itself to the specific component, but I want to provide to user the feedback about this prerequisite being installed.

So, short version: how to auto check component 'A' based to check status of component 'B' ?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
realtebo
  • 23,922
  • 37
  • 112
  • 189

2 Answers2

5

A simple implementation for checking B, if A is checked:

[Components]
Name: "A"; Description: "A"
Name: "B"; Description: "B"

[Code]

var
  PrevItemAChecked: Boolean;
  TypesComboOnChangePrev: TNotifyEvent;
  ComponentsListClickCheckPrev: TNotifyEvent;

procedure ComponentsListCheckChanges;
begin
  if PrevItemAChecked <> WizardIsComponentSelected('A') then
  begin
    if WizardIsComponentSelected('A') then
      WizardSelectComponents('B');

    PrevItemAChecked := WizardIsComponentSelected('A');
  end;
end;

procedure ComponentsListClickCheck(Sender: TObject);
begin
  { First let Inno Setup update the components selection }
  ComponentsListClickCheckPrev(Sender);
  { And then check for changes }
  ComponentsListCheckChanges;
end;

procedure TypesComboOnChange(Sender: TObject);
begin
  { First let Inno Setup update the components selection }
  TypesComboOnChangePrev(Sender);
  { And then check for changes }
  ComponentsListCheckChanges;
end;

procedure InitializeWizard();
begin
  { The Inno Setup itself relies on the TypesCombo.OnChange and OnClickCheck. }
  { so we have to preserve their  handlers. }

  ComponentsListClickCheckPrev := WizardForm.ComponentsList.OnClickCheck;
  WizardForm.ComponentsList.OnClickCheck := @ComponentsListClickCheck;

  TypesComboOnChangePrev := WizardForm.TypesCombo.OnChange;
  WizardForm.TypesCombo.OnChange := @TypesComboOnChange;

  { Remember the initial state }
  { (by now the components are already selected according to }
  { the defaults or the previous installation) }
  PrevItemAChecked := WizardIsComponentSelected('A');
end;

The code requires Inno Setup 6 for WizardIsComponentSelected and WizardSelectComponents (for a version of the code without those functions, see the answer history)


The above is based on Inno Setup ComponentsList OnClick event.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
1

I have modified a little the approved Answer. It does not include unchecking of the related component (B). I also added a piece of code in the procedure InitializeWizard() to update the check states according to previous value of state A. Variable PrevItemAChecked is not necessary.


    [Components]
    Name: "A"; Description: "A"
    Name: "B"; Description: "B"

    [Code]

    var
      TypesComboOnChangePrev: TNotifyEvent;
      ComponentsListClickCheckPrev: TNotifyEvent;

    procedure ComponentsListCheckChanges;
    begin
      if WizardIsComponentSelected('A') then begin
        { Select Component B}
        WizardSelectComponents('B');
      end else begin
        { Unselect Component B}
        WizardSelectComponents('!B');
      end;
    end;

    procedure ComponentsListClickCheck(Sender: TObject);
    begin
      { First let Inno Setup update the components selection }
      ComponentsListClickCheckPrev(Sender);
      { And then check for changes }
      ComponentsListCheckChanges;
    end;

    procedure TypesComboOnChange(Sender: TObject);
    begin
      { First let Inno Setup update the components selection }
      TypesComboOnChangePrev(Sender);
      { And then check for changes }
      ComponentsListCheckChanges;
    end;

    procedure InitializeWizard();
    begin
      { The Inno Setup itself relies on the TypesCombo.OnChange and OnClickCheck. }
      { so we have to preserve their  handlers. }

      ComponentsListClickCheckPrev := WizardForm.ComponentsList.OnClickCheck;
      WizardForm.ComponentsList.OnClickCheck := @ComponentsListClickCheck;

      TypesComboOnChangePrev := WizardForm.TypesCombo.OnChange;
      WizardForm.TypesCombo.OnChange := @TypesComboOnChange;

      { Remember the initial state }
      { (by now the components are already selected according to }
      { the defaults or the previous installation) }
      //PrevItemAChecked := WizardIsComponentSelected('A');
      { Update check states according to previous value of state A }
      SQLComponentsListCheckChanges;
    end;
Mark
  • 11
  • 3