Inno Setup - Dynamic positioning of controls/checkboxes

北城以北 提交于 2019-12-19 05:04:15

问题


I have a bunch of checkboxes on a page, and all of those are conditionally visible, and the Top position is defined relative to the previous checkbox, e.g.

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

When at least one of the components is set to be invisible, the result looks like this:

What I'd like the checkboxes to do, is to shift upwards, if the previous one is set to invisible. Prog3 should be right underneath Prog1, or, if both Prog2 and Prog3 are hidden, Prog4 should be right underneath Prog1.


EDIT: My code after the answer:

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;

回答1:


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

Use TStringList (or array of string) to maintain association between the created checkboxes and the paths.

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;

To process the selected checkboxes/paths, use a code like this:

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;

Assuming C:\dir1 and C:\dir3 exist and C:\dir2 does not, you will get:


If you cannot use TInputOptionWizardPage, e.g. because you need the checkboxes on an uninstaller form or on a custom form, just create the TNewCheckListBox (what TInputOptionWizardPage uses internally).

The following example places the TNewCheckListBox on a blank custom TWizardPage, but you can of course place it, wherever you want.

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;



来源:https://stackoverflow.com/questions/44251985/inno-setup-dynamic-positioning-of-controls-checkboxes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!