How to allow only one checked box in [Run] section?

為{幸葍}努か 提交于 2021-02-16 14:03:26

问题


My Inno Setup program installs three programs during the installation.

I added the checkbox for each of the three programs to show after installation page in the [Run] section:

Filename: "{app}\Program1.exe"; Description: "{cm:LaunchProgram,{#StringChange("Program1", '&', '&&')}}"; Flags: nowait postinstall skipifsilent unchecked runascurrentuser;
Filename: "{app}\Program2.exe"; Description: "{cm:LaunchProgram,{#StringChange("Program2", '&', '&&')}}"; Flags: nowait postinstall skipifsilent unchecked runascurrentuser;
Filename: "{app}\Program3.exe"; Description: "{cm:LaunchProgram,{#StringChange("Program3", '&', '&&')}}"; Flags: nowait postinstall skipifsilent unchecked runascurrentuser;

How can I make it only allow to check one box at time?

Thank you


回答1:


You have these options:

  • Turn the checkboxes to radio buttons (this solution is shown below).

  • Programmatically make sure that when one checkbox is checked, all others get unchecked (this solution is shown below too)

    For a similar problem see also Inno Setup - Show children component as sibling and show check instead of square in checkbox.

  • Use Tasks entries with exclusive flag to trigger Run entries without the postinstall flag (instead of checkboxes created by Run entries with postinstall flag).


Turning the checkboxes to radio buttons

[Code]

var
  RunListModified: Boolean;

procedure CurPageChanged(CurPageID: Integer);
var
  I: Integer;
begin
  { The first time the Finished page shows, turn all checkboxes to radio buttons. }
  { (note that the Finished page can show multiple times, }
  { if the InfoAfterFile directive is set only, }
  { or if there is some custom page before the Finished page) }
  if (CurPageID = wpFinished) and (not RunListModified) then
  begin
    { Add a dummy "Run nothing" entry }
    WizardForm.RunList.AddRadioButton('Run nothing', '', 0, True, True, -1);

    for I := 0 to WizardForm.RunList.Items.Count - 2 do
    begin
      { For all entries - take the first checkbox in the list, clone it to the end }
      { as a radio button with the same properties }
      { (mainly the caption and the object, which is actually index to the run list). }
      { Note that the ItemSubItem is always empty, ItemLevel always 0 and ItemEnabled }
      { always True. }
      WizardForm.RunList.AddRadioButton(
        WizardForm.RunList.ItemCaption[0],
        WizardForm.RunList.ItemSubItem[0],
        WizardForm.RunList.ItemLevel[0],
        False,
        WizardForm.RunList.ItemEnabled[0],
        WizardForm.RunList.ItemObject[0]);

      { And delete the original checkbox, pulling the next on to the first place }
      { for the next round. }
      WizardForm.RunList.Items.Delete(0);
    end;

    RunListModified := True;
  end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
  if CurPageID = wpFinished then
  begin
    { Make sure we remove the dummy "Run nothing" entry, }
    { otherwise the Inno Setup fails processing it. }
    { The test for RunList.Count is for a case that a restart is needed and }
    { the RunList is never populated/shown. }
    { The test for ItemObject is here only in case we ever get here multiple time. }
    { But it should not really happen. }
    if (WizardForm.RunList.Items.Count > 0) and
       (Integer(WizardForm.RunList.ItemObject[0]) = -1) then
    begin
      WizardForm.RunList.Items.Delete(0);
    end;
  end;

  Result := True;
end;

For a similar question, see Showing run tasks as radio choices instead of check boxes?


Programmatically make sure that when one checkbox is checked, all others get unchecked

[Code]

var
  RunListLastChecked: Integer;

procedure RunListClickCheck(Sender: TObject);
var
  I: Integer;
  Checked: Integer;
begin
  { Find if some other checkbox got checked }
  Checked := -1;
  for I := 0 to WizardForm.RunList.Items.Count - 1 do
  begin
    if WizardForm.RunList.Checked[I] and (I <> RunListLastChecked) then
    begin
      Checked := I;
    end;
  end;

  { If it was, uncheck the previously checked box and remember the new one }
  if Checked >= 0 then
  begin
    if RunListLastChecked >= 0 then
    begin
      WizardForm.RunList.Checked[RunListLastChecked] := False;
    end;

    RunListLastChecked := Checked;
  end;

  { Or if the previously checked box got unchecked, forget it. }
  { (This is not really necessary, it's just to clean the things up) }
  if (RunListLastChecked >= 0) and
     (not WizardForm.RunList.Checked[RunListLastChecked]) then
  begin
    RunListLastChecked := -1;
  end;
end;

procedure InitializeWizard();
begin
  WizardForm.RunList.OnClickCheck := @RunListClickCheck;
  RunListLastChecked := -1;
end;


来源:https://stackoverflow.com/questions/35539827/how-to-allow-only-one-checked-box-in-run-section

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