Inno Setup - Динамическое позиционирование элементов управления / флажков

У меня есть несколько флажков на странице, и все они условно видны, и Top позиция определяется относительно предыдущего флажка, например

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

Когда хотя бы один из компонентов установлен как невидимый, результат выглядит так:

разрыв

Я бы хотел, чтобы флажки были смещены вверх, если предыдущий установлен на невидимый. Prog3 должно быть прямо под Prog1или, если оба Prog2 а также Prog3 скрыты, 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;

1 ответ

Решение

Использование TInputOptionWizardPage, который предназначен для такого рода задач / макетов. Создайте его, используя 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;

Для обработки выбранных флажков / путей используйте код, подобный следующему:

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:\dir1 а также C:\dir3 существовать и C:\dir2 нет, вы получите:

Проверьте список


Если вы не можете использовать TInputOptionWizardPage Например, поскольку вам нужны флажки в форме удаления или в пользовательской форме, просто создайте TNewCheckListBox (какие TInputOptionWizardPage использует внутренне).

Следующий пример помещает 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;

введите описание изображения здесь

Другие вопросы по тегам