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

拟墨画扇 提交于 2019-12-22 17:12:08

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!