Skipping custom pages based on optional components in Inno Setup

Dr.YSG picture Dr.YSG · Dec 17, 2012 · Viewed 11.4k times · Source

In a prior question I asked how to have three optional components, where the user could also specify the locations for each component separately (e.g. a code part and two HTML web applications). @Miral gave me a great answer which I have now implemented:
three components in three user defined locations

I have a small esthetic issue remaining. I am always creating and asking the user for a CreateInputDirPage, in the wizard. The question comes after the wpSelectComponents.

Question: How do I skip the page if the component was not selected. That is, how do I skip my custom page?

I have a feeling it has to do with ShouldSkipPage(). But I have no idea what the PageID for my custom page is, and how to test to see what components were selected.

function ShouldSkipPage(PageID: Integer): Boolean;

The wizard calls this event function to determine whether or not a particular page (specified by PageID) should be shown at all. If you return True, the page will be skipped; if you return False, the page may be shown.

My script is enclosed below:

[Components]
Name: "Watson"; Description: "Watson Component"; Types: onlywatson full
Name: "Toby"; Description: "Toby Component"; Types: onlytoby full
Name: "Sherlock"; Description: "Sherlock Component"; Types: onlysherlock full

[Code]
var 
    TobyDirPage: TInputDirWizardPage;
    SherlockDirPage: TInputDirWizardPage;

procedure InitializeWizard;
begin
  TobyDirPage := CreateInputDirPage(wpSelectComponents,
    'Select Location for Toby Web Pages', 'Where should we store the sample Toby application files?',
    'The sample Toby stand-alone map application will be saved in the following folder.'#13#10#13#10 +
    'To continue, click Next. If you would like to select a different folder, click Browse.',
    False, 'New Folder');
  { Add item (with an empty caption) }
  TobyDirPage.Add('');
  { Set initial value (optional) }
  TobyDirPage.Values[0] := ExpandConstant('c:\wwwroot\Toby');
  
  SherlockDirPage := CreateInputDirPage(wpSelectComponents,
    'Select Location for Sherlock Web Pages', 'Where should we store the Sherlock Catalog Search Tool?',
    'Sherlock.html and it'#39 + 's associated files will be saved in the following folder.'#13#10#13#10 +
    'To continue, click Next. If you would like to select a different folder, click Browse.',
    False, 'New Folder');
  { Add item (with an empty caption) }
  SherlockDirPage.Add('');
  { Set initial value (optional) }
  SherlockDirPage.Values[0] := ExpandConstant('c:\wwwroot\Sherlock');
end;

function GetTobyDir(Param: String): String;
begin
  { Return the selected TobyDir }
  Result := TobyDirPage.Values[0];
end;

function GetSherlockDir(Param: String): String;
begin
  { Return the selected TobyDir }
  Result := SherlockDirPage.Values[0];
end;

Answer

TLama picture TLama · Dec 17, 2012

As you correctly forefelt, you need to use the ShouldSkipPage event handler to conditionally skip the page. To check if a certain component is selected use the IsComponentSelected function and finally, to get ID of your custom page you need to store its ID. Putting all together might give you the following example script:

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
OutputDir=userdocs:Inno Setup Examples Output

[Components]
Name: "help"; Description: "Help File";

[Code]
var
  CustomPageID: Integer;

procedure InitializeWizard;
var
  CustomPage: TInputDirWizardPage;
begin
  CustomPage := CreateInputDirPage(wpSelectComponents, 'Caption', 
    'Description', 'SubCaption', False, 'NewFolderName');
  CustomPage.Add('Input');
  { store your custom page ID to further use in the ShouldSkipPage event }
  CustomPageID := CustomPage.ID;
end;

function ShouldSkipPage(PageID: Integer): Boolean;
begin
  { initialize result to not skip any page (not necessary, but safer) }
  Result := False;
  { if the page that is asked to be skipped is your custom page, then... }
  if PageID = CustomPageID then
    { if the component is not selected, skip the page }
    Result := not IsComponentSelected('help');
end;