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 https://stackoverflow.com/a/37796528/3993104, 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
.
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)
:
WizardSelectedTasks(False)
to get names of all tasksThis 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.