Inno Setup - 确定哪些任务对应于 TaskList 的项目(仅针对某些任务在鼠标悬停时显示文本)

Inno Setup - Identify, what tasks correspond to the items of TaskList (to show text on mouse over for certain tasks only)

所以,我有这些 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.

之外时

确实没有直接的方法来识别,哪些任务对应于 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 的逻辑来决定要显示什么任务。

使用WizardIsComponentSelected function(Inno Setup 6.0.2 之前的IsComponentSelected)。

{ 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 个任务,但您需要更复杂的代码。