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
个任务,但您需要更复杂的代码。
所以,我有这些 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
个任务,但您需要更复杂的代码。