Inno Setup - 识别,哪些任务对应于TaskList的项目(仅在某些任务的鼠标上显示文本)

时间:2017-06-05 13:51:17

标签: inno-setup pascalscript

所以,我有这些comtools个任务,正如你所看到的,在任务列表中可以有不同的位置,具体取决于之前选择的组件。此外,如果用户不希望安装这些组件,它们可能根本不存在。 我需要的是显示的静态文本,但仅当光标悬停在comtools任务上时。

[Tasks]
Name: "acorig"; Description: "ac original"; GroupDescription: "Choose which version of ac to install:"; Flags: exclusive; Components: ac
Name: "acenh"; Description: "ac enhanced"; GroupDescription: "Choose which version of ac to install:"; Flags: exclusive unchecked; Components: ac
Name: "ac2comtools"; Description: "ac2"; GroupDescription: "Also install community-made tools (unsupported) for:"; Flags: unchecked; Components: ac2
Name: "bccomtools"; Description: "bc"; GroupDescription: "Also install community-made tools (unsupported) for:"; Flags: unchecked; Components: bc
Name: "bc2comtools"; Description: "bc2"; GroupDescription: "Also install community-made tools (unsupported) for:"; Flags: unchecked; Components: bc
Name: "bc3comtools"; Description: "bc3"; GroupDescription: "Also install community-made tools (unsupported) for:"; Flags: unchecked; Components: bc3
Name: "bc4comtools"; Description: "bc4"; GroupDescription: "Also install community-made tools (unsupported) for:"; Flags: unchecked; Components: bc4

是的,我确实看到this,但这会将描述与索引联系起来,这在这里不切实际。此外,该代码还显示了TasksList中所有项目的说明。

---- ----编辑

所以,在Martin回答之后我对代码所做的唯一改变(除了将所有内容移到任务页面之外)是添加了Martin的功能,并且像这样编辑HoverComponentChanged

procedure HoverComponentChanged(Index: Integer);
var 
  Description: string;
begin
  case Index of
    -1: Description := '';
    LookupTask('ac2comtools'): Description := 'This is the description of AC2';
    LookupTask('bccomtools'): Description := 'This is the description of BC';
    LookupTask('bc2comtools'): Description := 'This is the description of BC2';
    LookupTask('bc3comtools'): Description := 'This is the description of BC3';
  else
    Description := '';
  end;
  TaskLabel.Caption := Description;
end;

-1是故障安全的,因为当取消选择其中一个组件时,相应任务的索引为-1,这意味着您将看到此中第一个取消选择的组件的描述列表,当光标位于TasksList之外时。

1 个答案:

答案 0 :(得分:2)

确实没有直接的方法来确定哪些任务与TaskList的项目相对应。

快速而肮脏的方式是使用物品描述。

在这种情况下,最好使用custom message定义描述,以便您可以在代码中引用它。如果您的安装程序已本地化,那么无论如何它都是必须的。

[CustomMessages]
AC2ComTools=ac2

[Tasks]
Name: "ac2comtools"; Description: {cm:AC2ComTools}
[Code]

function LookupTask(TaskCustomMessage: string): Integer;
var
  Description: string;
begin
  Description := CustomMessage(TaskCustomMessage);
  Result := WizardForm.TasksList.Items.IndexOf(Description);
  Log(Format('Index of "%s" task is %d', [Description, Result]));
end;

使用它像:

AC2ComToolsIndex := LookupTask('ac2comtools');

另一种方法是重现Inno Setup的逻辑,以决定要显示的任务。

在Inno Setup 6.0.2之前使用WizardIsComponentSelected functionIsComponentSelected)。

{ Before Inno Setup 6.0.2, use IsComponentSelected. }
if WizardIsComponentSelected('ac2') then
begin
  if WizardIsComponentSelected('ac') then AC2ComToolsIndex := 4
    else AC2ComToolsIndex := 1;
end
  else AC2ComToolsIndex := -1;

如果要自动创建从任务名称到TaskList项目索引的完整映射,每次任务列表更改时,即每次调用CurPageChanged(wpSelectTasks)时都可以执行类似的操作:

  • 记住当前的任务状态
  • 检查所有任务复选框
  • 阅读WizardSelectedTasks(False)以获取所有任务的名称
  • 生成映射
  • 恢复上一个任务状态。

当只有复选框而不是单选按钮(即没有带exclusive标志的任务)时,这相对容易。

var
  Tasks: TStringList;

procedure CurPageChanged(CurPageID: Integer);
var
  TasksChecked: array of Boolean;
  I: Integer;
begin
  if CurPageID = wpSelectTasks then
  begin
    SetArrayLength(TasksChecked, WizardForm.TasksList.Items.Count);
    { Remember current task state + Check all task checkboxes }
    for I := 0 to WizardForm.TasksList.Items.Count - 1 do
    begin
      TasksChecked[I] := WizardForm.TasksList.Checked[I];
      WizardForm.TasksList.Checked[I] := True;
    end;
    Tasks := TStringList.Create;
    Tasks.CommaText := WizardSelectedTasks(False);  
    for I := 0 to WizardForm.TasksList.Items.Count - 1 do
    begin
      { Insert blank items for "group descriptions" }
      if WizardForm.TasksList.ItemObject[I] = nil then
        Tasks.Insert(I, '');
      { Restore previous task state }
      WizardForm.TasksList.Checked[I] := TasksChecked[I];
    end;
  end;
end;

现在您可以使用Tasks查找相应的任务索引:

AC2ComToolsIndex := Tasks.IndexOf('ac2comtools');

虽然您有exclusive个任务,但您需要更复杂的代码。