【问题标题】:InnoSetup Dynamic ComboBox, check which item is selected and execute programInnoSetup Dynamic ComboBox,检查选择了哪个项目并执行程序
【发布时间】:2012-10-11 09:21:13
【问题描述】:

在 InnoSetup 中,我想在 Finished Page 上显示一个 ComboBox,显示已安装的组件。 您可以选择“无”或任何已安装的组件,并在单击完成时启动相关程序。

这是我目前的代码:

procedure CurPageChanged(CurPageID: Integer);
var
  NewComboBox1: TNewComboBox;
begin
  if (CurPageID = wpFinished) then begin
  NewComboBox1 := TNewComboBox.Create(WizardForm);
  with NewComboBox1 do begin
    Parent := WizardForm.FinishedPage;
    Left := ScaleX(256);
    Top := ScaleY(208);
    Width := ScaleX(145);
    Height := ScaleY(21);
    ItemIndex := 0;
    Style := csDropDownList;
    Items.Add('None');
    if IsComponentSelected('1') then
    Items.Add('Component 1');
    if IsComponentSelected('2') then
    Items.Add('Component 2');
    if IsComponentSelected('3') then
    Items.Add('Component 3');
    end;
  end;
end;

首先我想将“无”设置为自动选择。当页面显示时。我查找了许多 Pascal 论坛,但没有一个解决方案有效,例如 NewComboBox1.ItemSelected=0 (或类似的,不记得正确......)。那么我该如何实现呢?

然后我不知道如何在单击完成时启动程序。我以为

function NextButtonClick

可能会有所帮助,但设置中没有“下一步”按钮。

也许还有一个问题,因为列表是根据选择的组件创建的,所以项目 1 不是组件 1,如果没有选择组件 1,而是组件 2。

我认为可以通过使项目不可见而不是根本不创建它们来解决这个问题。

我查看了 IS 帮助文件中的 Support Classes Reference,但没有找到任何可以帮助我的内容。

期待你的回答!

【问题讨论】:

  • 您将ItemIndex 设置得太早了。您需要输入组合框,然后设置项目索引。在当前代码中设置 ItemIndex 静默失败,因为还没有索引为 0 的项目。
  • 好吧,我在最后设置了ItemIndex,现在None会自动显示!谢谢你!现在我只需要知道如何获取所选项目的价值...
  • 你不会得到 value,你想打开在组合框中选择的组件 behind 的文件,不要'你呢?
  • 您确实应该在InitializeWizard() 事件函数中添加控件。然后,您可以(清除并)添加所需的任何项目并在CurPageChanged(wpFinished) 中选择默认值。
  • 是的,每个组件都会安装一个 .exe 文件。使用 ComboBox,我想为用户提供启动已安装 .exe 文件之一的选项。

标签: select dynamic combobox inno-setup


【解决方案1】:

由于缺少对组件绑定到的文件名和目标目录的访问权限,因此没有简单的方法可以做到这一点。即使TSetupComponentEntry 内部记录也不包含此信息,但即使包含,您也无法访问它。因此,以下脚本使用其自己的单独数组,其中包含此任务所需的组件/文件链接:

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program

[Components]
Name: "program_32"; Description: "Program 32-bit"
Name: "program_x64"; Description: "Program 64-bit"
Name: "program_ia64"; Description: "Program IA 64-bit"

[Files]
Source: "MyProg.exe"; DestDir: "{app}"; Components: program_32
Source: "MyProg-x64.exe"; DestDir: "{app}"; Components: program_x64
Source: "MyProg-IA64.exe"; DestDir: "{app}"; Components: program_ia64

[Code]
type
  TFileData = record
    Component: string;
    Description: string;
    FileName: string;
    Parameters: string;
  end;  
var  
  ComponentCombo: TNewComboBox;
  ComponentArray: array of TFileData;
  SelectionArray: array of TFileData;

procedure InitializeWizard;
begin
  // this is a weakness of this solution - you need to fill the array
  // of components that can be added to the final combo box when they
  // are selected on component selection page. This is needed because
  // you can't get neither file name nor destination directory of the
  // file for the component from script. As first, set how many items
  // you want to add to your component array storage
  SetArrayLength(ComponentArray, 2);
  // the Component member must match to the "Name" parameter from the
  // [Components] section item since it's used in IsComponentSelected
  // function call
  ComponentArray[0].Component := 'program_32';
  // the Description member is the text displayed in the combo item
  ComponentArray[0].Description := 'Program 32-bit';
  // the FileName member is the name of the file including path. This
  // member may contain InnoSetup constants
  ComponentArray[0].FileName := '{app}/MyProg.exe';
  // the Parameters member contains execution parameters
  ComponentArray[0].Parameters := '-a';
  // this is the second item that can be added to the combo box, note
  // that the program_ia64 component is not added to this array, what
  // means, that it cannot be added to the "run" combo box. It's such
  // kind of a filter for components like help files etc.
  ComponentArray[1].Component := 'program_x64';
  ComponentArray[1].Description := 'Program 64-bit';
  ComponentArray[1].FileName := '{app}/MyProg-x64.exe';
  ComponentArray[1].Parameters := '-b';
end;

procedure CurPageChanged(CurPageID: Integer);
var
  I: Integer;
begin
  if (CurPageID = wpFinished) then
  begin
    ComponentCombo := TNewComboBox.Create(WizardForm);
    ComponentCombo.Parent := WizardForm.FinishedPage;
    ComponentCombo.Left := ScaleX(256);
    ComponentCombo.Top := ScaleY(208);
    ComponentCombo.Width := ScaleX(145);
    ComponentCombo.Height := ScaleY(21);
    ComponentCombo.Style := csDropDownList;

    ComponentCombo.Items.Add('None');
    for I := 0 to GetArrayLength(ComponentArray) - 1 do
      if IsComponentSelected(ComponentArray[I].Component) then
      begin
        ComponentCombo.Items.Add(ComponentArray[I].Description);
        SetArrayLength(SelectionArray, GetArrayLength(SelectionArray) + 1);
        SelectionArray[High(SelectionArray)] := ComponentArray[I];
      end;      
    ComponentCombo.ItemIndex := 0;
  end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
var
  FileData: TFileData;
  ResultCode: Integer;
begin
  Result := True;
  if (CurPageID = wpFinished) and (ComponentCombo.ItemIndex > 0) then
  begin
    FileData := SelectionArray[ComponentCombo.ItemIndex - 1];
    Exec(ExpandConstant(FileData.FileName), FileData.Parameters, '', SW_SHOW,
      ewNoWait, ResultCode);
  end;
end;

【讨论】:

  • 哇!感谢您的努力!我只是想尝试一下,但出现错误:第 185 行:第 24 列:未知标识符 'High' .... 它位于 "SelectionArray[High(SelectionArray)] := ComponentArray[I];" 行中
  • 不客气!我已经在 Unicode InnoSetup 5.5.1 中测试过这个脚本,此时应该是最新版本,所以也许它不在某些旧版本中。
  • 还有一个更新的版本,5.5.2,但我有非 unicode 版本...我安装了 IS-Unicode 然后它工作了!再次感谢您!
  • D'oh,我的最新版本晚了 3 天 :-) 我现在必须升级!
  • 如果High(x) 不可用,可以用GetArrayLength(x)-1 替换。 (以防万一有人想在不切换到 Unicode 的情况下使用此代码。)
猜你喜欢
  • 1970-01-01
  • 2015-10-20
  • 1970-01-01
  • 2012-12-28
  • 2016-08-26
  • 1970-01-01
  • 1970-01-01
  • 2011-04-14
  • 1970-01-01
相关资源
最近更新 更多