You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现带可折叠组件树的Inno Setup安装程序

无需修改Inno Setup主程序实现可折叠树形组件选择视图

我完全理解你不想修改Inno Setup可执行文件的顾虑——那种方案不仅维护性差,还可能因为版本更新失效,确实不太靠谱。下面给你一套纯脚本层面实现的方案,不用碰主程序,还能轻松支持50+组件,同时自定义默认展开的节点:

核心思路

利用Inno Setup自带的TNewCheckListBox控件原生树形结构支持,结合Pascal脚本实现折叠/展开交互,同时通过代码指定默认展开的节点,全程无需修改主程序文件。

具体实现步骤

1. 定义树形层级的组件结构

在[Components]段中,通过.分隔符来标记组件的父子层级,示例如下:

[Components]
Name: "core"; Description: "核心功能"; Types: full compact custom; Flags: fixed
Name: "tools"; Description: "工具集"; Types: full custom
Name: "tools.screenshot"; Description: "截图工具"; Types: full custom
Name: "tools.converter"; Description: "格式转换工具"; Types: full custom
Name: "plugins"; Description: "插件扩展"; Types: full custom
Name: "plugins.media"; Description: "媒体插件"; Types: full custom
Name: "plugins.media.video"; Description: "视频解码插件"; Types: full custom
Name: "plugins.media.audio"; Description: "音频增强插件"; Types: full custom

这里tools.screenshot表示它是tools的子组件,Inno Setup会自动识别并构建树形结构。

2. 编写脚本实现折叠/展开交互

在[Code]段中添加以下Pascal代码,实现点击父节点折叠/展开子节点,同时支持默认展开指定节点:

var
  MainCheckList: TNewCheckListBox;

// 切换节点的折叠/展开状态
procedure ToggleNode(Index: Integer);
var
  I, CurrentLevel, ChildLevel: Integer;
  IsExpanded: Boolean;
begin
  CurrentLevel := MainCheckList.ItemLevel[Index];
  IsExpanded := (Index + 1 < MainCheckList.Items.Count) and 
                (MainCheckList.ItemLevel[Index + 1] > CurrentLevel) and 
                MainCheckList.Visible[Index + 1];
  
  // 遍历后续节点,切换子节点的可见性
  for I := Index + 1 to MainCheckList.Items.Count - 1 do
  begin
    ChildLevel := MainCheckList.ItemLevel[I];
    if ChildLevel <= CurrentLevel then
      Break;
    MainCheckList.Visible[I] := not IsExpanded;
  end;
  
  // 更新父节点的描述标记(可选,增强用户体验)
  if IsExpanded then
    MainCheckList.ItemCaption[Index] := '+ ' + Copy(MainCheckList.ItemCaption[Index], 3, Length(MainCheckList.ItemCaption[Index]))
  else
    MainCheckList.ItemCaption[Index] := '- ' + Copy(MainCheckList.ItemCaption[Index], 3, Length(MainCheckList.ItemCaption[Index]));
end;

// 绑定点击事件
procedure CheckListClick(Sender: TObject; Index: Integer);
begin
  // 只处理顶级父节点(可根据需求调整层级)
  if MainCheckList.ItemLevel[Index] = 0 then
    ToggleNode(Index);
end;

procedure InitializeWizard();
var
  I: Integer;
begin
  MainCheckList := TNewCheckListBox(WizardForm.ComponentsList);
  // 绑定点击切换事件
  MainCheckList.OnClickCheck := @CheckListClick;
  
  // 初始化时隐藏所有子节点,只显示父节点
  for I := 0 to MainCheckList.Items.Count - 1 do
  begin
    if MainCheckList.ItemLevel[I] > 0 then
      MainCheckList.Visible[I] := False;
    // 给父节点添加折叠标记
    if MainCheckList.ItemLevel[I] = 0 then
      MainCheckList.ItemCaption[I] := '+ ' + MainCheckList.ItemCaption[I];
  end;
  
  // 默认展开指定节点(示例:展开"插件扩展"节点)
  for I := 0 to MainCheckList.Items.Count - 1 do
  begin
    if Pos('插件扩展', MainCheckList.ItemCaption[I]) > 0 then
    begin
      ToggleNode(I);
      Break;
    end;
  end;
end;

3. 自定义优化建议

  • 多级折叠支持:如果需要支持更深层级的折叠(比如子节点还有子节点),可以修改ToggleNode函数,增加递归逻辑处理下一级子节点。
  • 样式优化:可以通过修改MainCheckList的字体、缩进等属性,让树形结构更美观。
  • 批量操作:可以添加全选/反选父节点的逻辑,提升用户选择效率。

方案优势

  • 完全无需修改Inno Setup可执行文件,避免了版本兼容和安全问题。
  • 原生控件支持,性能稳定,轻松应对50+组件的场景。
  • 高度可定制,可根据需求调整默认展开节点、折叠逻辑和UI样式。

内容的提问来源于stack exchange,提问作者jaba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:55:30