Inno Setup - controls/checkboxes 的动态定位

Inno Setup - Dynamic positioning of controls/checkboxes

我在一个页面上有一堆复选框,所有这些都是有条件可见的,并且 Top 位置是相对于前一个复选框定义的,例如

CheckBox4.Top := CheckBox3.Top + CheckBox3.Height + 5;

当至少一个组件设置为不可见时,结果如下所示:

如果前一个复选框设置为不可见,我想让复选框向上移动。 Prog3 应该在 Prog1 的正下方,或者,如果 Prog2Prog3 都被隐藏,Prog4 应该在 Prog1 的正下方。


编辑:答案后我的代码:

var
  PageNameLabel,PageDescriptionLabel: TLabel;
  TypesComboOnChangePrev: TNotifyEvent;
  UninstallConfigssPage: TNewNotebookPage;
  UninstallNextButton: TNewButton;
  CheckListBox: TNewCheckListBox;
  Dirs: TStringList;

procedure UpdateUninstallWizard;
begin
  UninstallProgressForm.PageNameLabel.Caption := CustomMessage('UninstPNL');
  UninstallProgressForm.PageDescriptionLabel.Caption := CustomMessage('UninstPDL');
  UninstallNextButton.Caption := CustomMessage('UninstBtn');
  UninstallNextButton.ModalResult := mrOK;
end;  

procedure UninstallNextButtonClick(Sender: TObject);
begin
  UninstallNextButton.Visible := False;
end;

procedure AddDirCheckbox(Path: string; Caption: string);
begin
  if DirExists(Path) then
  begin
    Dirs.Add(Path);
    CheckListBox.AddCheckBox(Caption, '', 0, False, True, False, False, nil);
  end;
end;

procedure InitializeUninstallProgressForm();
var
  PageText: TNewStaticText;
  PageNameLabel,PageDescriptionLabel: string;
  CancelButtonEnabled: Boolean;
  CancelButtonModalResult: Integer;
begin
  if not UninstallSilent then
  begin
    UninstallProgressForm.Caption := CustomMessage('Uninst');

    UninstallConfigssPage:= TNewNotebookPage.Create(UninstallProgressForm);
    UninstallConfigssPage.Notebook := UninstallProgressForm.InnerNotebook;
    UninstallConfigssPage.Parent := UninstallProgressForm.InnerNotebook;
    UninstallConfigssPage.Align := alClient;

    PageText := TNewStaticText.Create(UninstallProgressForm);
    PageText.Parent := UninstallConfigssPage;
    PageText.Top := UninstallProgressForm.StatusLabel.Top;
    PageText.Left := UninstallProgressForm.StatusLabel.Left - ScaleX(20);
    PageText.Width := UninstallProgressForm.StatusLabel.Width;
    PageText.Height := UninstallProgressForm.StatusLabel.Height;
    PageText.AutoSize := True;
    PageText.ShowAccelChar := False;
    PageText.Caption := CustomMessage('UninstTxt');

    Dirs := TStringList.Create();
    CheckListBox := TNewCheckListBox.Create(UninstallConfigssPage);
    CheckListBox.Parent := UninstallConfigssPage;
    CheckListBox.SetBounds(PageText.Left,ScaleY(30),PageText.Width,ScaleY(220));
    CheckListBox.BorderStyle := bsNone;
    CheckListBox.Color := clBtnFace;
    CheckListBox.MinItemHeight := ScaleY(20);

    AddDirCheckbox(ExpandConstant('{app}\Alien Shooter'), 'Prog1');
    AddDirCheckbox(ExpandConstant('{app}\Theseus'), 'Prog2');
    AddDirCheckbox(ExpandConstant('{app}\Alien Shooter Revisited'), 'Prog3');
    AddDirCheckbox(ExpandConstant('{app}\Alien Shooter 2'), 'Prog4');
    AddDirCheckbox(ExpandConstant('{app}\Alien Shooter 2 Reloaded'), 'Prog5');
    AddDirCheckbox(ExpandConstant('{app}\Alien Shooter 2 Conscription'), 'Prog6');
    AddDirCheckbox(ExpandConstant('{app}\Zombie Shooter'), 'Prog7');
    AddDirCheckbox(ExpandConstant('{app}\Zombie Shooter 2'), 'Prog8');

    UninstallProgressForm.InnerNotebook.ActivePage := UninstallConfigssPage;

    PageNameLabel := UninstallProgressForm.PageNameLabel.Caption;
    PageDescriptionLabel := UninstallProgressForm.PageDescriptionLabel.Caption;

    UninstallNextButton := TNewButton.Create(UninstallProgressForm);
    UninstallNextButton.Parent := UninstallProgressForm;
    UninstallNextButton.Left := UninstallProgressForm.CancelButton.Left - UninstallProgressForm.CancelButton.Width - ScaleX(35);
    UninstallNextButton.Top := UninstallProgressForm.CancelButton.Top;
    UninstallNextButton.Width := UninstallProgressForm.CancelButton.Width + ScaleX(30);
    UninstallNextButton.Height := UninstallProgressForm.CancelButton.Height;
    UninstallNextButton.OnClick := @UninstallNextButtonClick;
    UninstallNextButton.TabOrder := UninstallProgressForm.CancelButton.TabOrder - 1;

    UpdateUninstallWizard;
    CancelButtonEnabled := UninstallProgressForm.CancelButton.Enabled
    UninstallProgressForm.CancelButton.Enabled := True;
    CancelButtonModalResult := UninstallProgressForm.CancelButton.ModalResult;
    UninstallProgressForm.CancelButton.ModalResult := mrCancel;

    if UninstallProgressForm.ShowModal = mrCancel then Abort;

    UninstallProgressForm.CancelButton.Enabled := CancelButtonEnabled;
    UninstallProgressForm.CancelButton.ModalResult := CancelButtonModalResult;

    UninstallProgressForm.PageNameLabel.Caption := PageNameLabel;
    UninstallProgressForm.PageDescriptionLabel.Caption := PageDescriptionLabel;

    UninstallProgressForm.InnerNotebook.ActivePage := UninstallProgressForm.InstallingPage;
  end;
end;

使用TInputOptionWizardPage, which is designed for this kind of tasks/layouts. Create it using CreateInputOptionPage.

使用TStringList(或array of string)来维护创建的复选框和路径之间的关联。

var
  Page: TInputOptionWizardPage;
  Dirs: TStringList;

procedure AddDirCheckbox(Path: string; Caption: string);
begin
  if DirExists(Path) then
  begin
    Dirs.Add(Path);
    Page.Add(Caption);
  end;
end;

procedure InitializeWizard();
begin
  Page :=
    CreateInputOptionPage(
      wpWelcome, 'Configuration files found', 'Choose an action for configuration files',
      'Choose the configuration files you''d like to be deleted.', False, False);
  Dirs := TStringList.Create();
  AddDirCheckbox('C:\dir1', 'Prog 1');
  AddDirCheckbox('C:\dir2', 'Prog 2');
  AddDirCheckbox('C:\dir3', 'Prog 3');
end;

要处理选定的 checkboxes/paths,请使用如下代码:

procedure CurStepChanged(CurStep: TSetupStep);
var
  Index: Integer;
begin
  if CurStep = ssInstall then
  begin
    for Index := 0 to Dirs.Count - 1 do
    begin
      if Page.Values[Index] then
      begin
        MsgBox(Format('Deleting %s', [Dirs[Index]]), mbInformation, MB_OK);
      end;
    end;
  end;
end;

假设 C:\dir1C:\dir3 存在而 C:\dir2 不存在,您将得到:


如果您不能使用 TInputOptionWizardPage,例如因为您需要卸载程序表单或自定义表单上的复选框,只需创建 TNewCheckListBoxTInputOptionWizardPage 内部使用的内容)。

以下示例将 TNewCheckListBox 放置在空白自定义 TWizardPage 上,但您当然可以将其放置在任何您想要的位置。

var
  Page: TWizardPage;
  CheckListBox: TNewCheckListBox;
  Dirs: TStringList;

procedure AddDirCheckbox(Path: string; Caption: string);
begin
  if DirExists(Path) then
  begin
    Dirs.Add(Path);
    CheckListBox.AddCheckBox(Caption, '', 0, False, True, False, False, nil);
  end;
end;

procedure InitializeWizard();
begin
  Page :=
    CreateCustomPage(
      wpWelcome, 'Configuration files found',
      'Choose an action for configuration files');
  Dirs := TStringList.Create();
  CheckListBox := TNewCheckListBox.Create(Page);
  CheckListBox.Parent := Page.Surface;
  CheckListBox.Width := Page.SurfaceWidth;
  CheckListBox.Height := Page.SurfaceHeight;

  { The same styling as used by TInputOptionWizardPage }
  CheckListBox.BorderStyle := bsNone;
  CheckListBox.Color := clBtnFace;
  CheckListBox.WantTabs := True;
  CheckListBox.MinItemHeight := ScaleY(22);

  AddDirCheckbox('C:\dir1', 'Prog 1');
  AddDirCheckbox('C:\dir2', 'Prog 2');
  AddDirCheckbox('C:\dir3', 'Prog 3');
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  Index: Integer;
begin
  if CurStep = ssInstall then
  begin
    for Index := 0 to Dirs.Count - 1 do
    begin
      if CheckListBox.Checked[Index] then
      begin
        MsgBox(Format('Deleting %s', [Dirs[Index]]), mbInformation, MB_OK);
      end;
    end;
  end;
end;