问题
So, I have these comtools
tasks, which, as you can see, can have a different position in the tasks list, depending on which components were previously chosen. Moreover, they may not exist at all, if the user doesn't wish to install those components.
What I need is static text shown, but only when the cursor hovers over the comtools
tasks.
[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
Yes, I did see this, but that ties the description to index, which is not practical here. Also, that code shows description for all items in TasksList
.
----Edit----
So, the only change I made to the code after Martin's answer (aside from moving everything over to the tasks page) was adding Martin's function, and editing HoverComponentChanged
like this:
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
is a failsafe, since, when one of the components in deselected, then the index for the corresponding task is -1
, which means you will see the description for the first deselected component in this list, when your cursor is outside of TasksList
.
回答1:
There's really no straightforward way to identify, what tasks correspond to the items of TaskList
.
Quick and dirty way is to use item description.
In this case, it's better to define the description using a custom message, so that you can refer to it in the code. And it's a must anyway, if your installer is localized.
[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;
Use it like:
AC2ComToolsIndex := LookupTask('ac2comtools');
Another way is to reproduce the logic of Inno Setup for deciding, what tasks to show.
Use WizardIsComponentSelected function (IsComponentSelected
before Inno Setup 6.0.2).
{ 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;
If you want to create a full mapping from task name to TaskList
item index automatically, you can do something like this each time the task list changes, i.e. on call to CurPageChanged(wpSelectTasks):
- Remember current task state
- Check all task checkboxes
- Read WizardSelectedTasks(False) to get names of all tasks
- Generate the mapping
- Restore previous task state.
This is relatively easy, when there are only checkboxes, not radio buttons (i.e. no task with exclusive
flag).
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;
Now you can use the Tasks
to lookup corresponding task index:
AC2ComToolsIndex := Tasks.IndexOf('ac2comtools');
Though as you have exclusive
tasks, you would need much more complicated code.
来源:https://stackoverflow.com/questions/44370532/inno-setup-identify-what-tasks-correspond-to-the-items-of-tasklist-to-show-t