Вопрос

Why can't I get one of my component's index by using this line:

WizardForm.ComponentsList.FindComponent('core').ComponentIndex

If I'm wrong, can anyone point out for me a way to get that index of component?

Это было полезно?

Решение

Currently, there's no way to find index of a component item in the ComponentsList by the component Name parameter. The Name parameter is stored in the TSetupComponentEntry structure, which is held by the ComponentsList.ItemObject[i] object collection, but you can't access it due to a lack of missing pointer support in Inno Setup Pascal Script.

The only way how to uniquely identify a component in the ComponentsList is by its Description parameter. To find index of a certain component by its description in the ComponentsList, you can use this:

[Components]
Name: "mycomponent"; Description: "Component description"; Types: full

[Code]
...
var
  ItemIndex: Integer;
begin
  ItemIndex := WizardForm.ComponentsList.Items.IndexOf('Component description');
  ...
end;

Другие советы

I found a way to do this through WizardSelectedComponents.

Define in var this array of String in order to save components name:

ComponentsName: array of String;

Define this function and this procedure:

Function StringToArray(const Text: String; const Cut: String): array of String;
var
    i: Integer;
    k: Integer;
Begin
    SetArrayLength(Result, 0);
    if Cut = '' then Cut:= #1310;
    Repeat
        k:= Pos(Cut,Text);
        if k = 1 then
        begin
            Delete(Text, 1, Length(Cut));
            CONTINUE
        end;
        SetArrayLength(Result, GetArrayLength(Result) +1); i:= GetArrayLength(Result) -1;
        if k = 0 then
            Result[i]:=Text
        else begin
            Result[i]:= Copy(Text, 1, k -1); Delete(Text, 1, Length(Result[i]) + Length(Cut));
        end;
    Until Length(Text) * k = 0;
End;

procedure InitializeComponentsName();
var
    I: Integer;
    CheckBack: array of boolean;
begin
    SetArrayLength(CheckBack, WizardForm.ComponentsList.ItemCount);

    for I:=0 to WizardForm.ComponentsList.ItemCount-1 do
    begin
        //Saves state in CheckBack.
        CheckBack[I]:=WizardForm.ComponentsList.Checked[I];
        //Only checks non checked components.
        if not CheckBack[I] then WizardForm.ComponentsList.Checked[I]:=true;
    end;

    //Saves components names in ComponentsName array
    ComponentsName:=StringToArray(WizardSelectedComponents(false), ',');

    //Unchecks components that was uncheck previouly.
    //If we try to check a checked component it may crash the Inno program (tested)
    for I:=0 to WizardForm.ComponentsList.ItemCount-1 do
    begin
        if not CheckBack[I] then WizardForm.ComponentsList.Checked[I]:=false;
    end;

    //LOG components name.
    log('COMPONENTS NAME:');
    for I:=0 to GetArrayLength(ComponentsName) -1 do
    begin
        log(ComponentsName[I]);
    end;

end;

You must call this procedure on InitializeWizard. Now we have all components name in ComponentsName array. You can use getComponentName to get your component name:

//Returns component name by Index.
function getComponentName(Index: Integer): String;
begin
    if ((Index>=0) and (Index<GetArrayLength(ComponentsName))) then Result:=ComponentsName[Index];
end;

and GetIndexComponent to get your Index component by name.

//Returns index component by Name. -1 if it doesn't exist.
function GetIndexComponent(ComponentName: String): Integer;
var
    J: Integer;
begin
    Result:= -1;
    for J:=0 to GetArrayLength(ComponentsName)-1 do
    begin
        if (ComponentName=ComponentsName[J]) then
        begin
            Result:=J;
            break;
        end;
    end;
end;

If you add another component to ComponentsList you must call InitializeComponentsName in order to update ComponentsList array.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top