Inno Setup下载页显示文件计数及选中组件统计实现方法
假设正在使用官方示例CodeDownloadFiles.iss,希望向用户提示下载状态,显示*“第N个/共Y个文件”*形式的下载进度计数。
最初的思路是先获取选中组件的总数,但不知道如何修改下载页上*“Downloading additional files...”*的提示标签。尝试直接给类属性赋值失败,错误写法如下:
TDownloadWizardPage.DownloadingLabel := 'Downloading additional files... file 1 of 3, please wait...'
当前已编写的代码尚未实现选中组件总数的获取逻辑,不确定是否可以通过自定义函数遍历校验组件选中状态实现统计,现有代码如下:
function NextButtonClick(CurPageID: Integer): Boolean; begin //Download Components if CurPageID = wpReady then begin DownloadPage.Clear; if WizardIsComponentSelected('Database\ABC') then begin TDownloadWizardPage.DownloadingLabel := 'Downloading additional files... file 1 of 3, please wait...' DownloadPage.Add('https://example.com/MyDB1.sqlite', 'MyDB1.sqlite', ''); end; if WizardIsComponentSelected('Database\DEF') then begin TDownloadWizardPage.DownloadingLabel := 'Downloading additional files... file 2 of 3, please wait...' DownloadPage.Add('https://example.com/MyDB2.sqlite', 'MyDB2.sqlite', '');; end; if WizardIsComponentSelected('Database\GHI') then begin TDownloadWizardPage.DownloadingLabel := 'Downloading additional files... file 3 of 3, please wait...' DownloadPage.Add('https://example.com/MyDB3.sqlite', 'MyDB3.sqlite', '');; end; DownloadPage.Show; try try DownloadPage.Download; Result := True; except SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbCriticalError, MB_OK, IDOK); Result := False; end; finally DownloadPage.Hide; end; end else Result := True; end;
核心诉求:
- 解决下载页提示标签修改失败的问题,实现动态显示「当前下载文件序号/总文件数」的效果
- 找到程序化统计选中组件对应待下载文件总数量的实现方法
1. 标签修改失败的原因
TDownloadWizardPage是类类型,不是实例对象,直接给类的属性赋值是无效的。你创建的DownloadPage才是页面实例,而且DownloadingLabel本质是实例上的TLabel控件,需要修改它的Caption属性才能生效。
另外原有写法是在添加文件的时候就修改标签,但下载过程是批量执行的,标签不会在每个文件下载开始时自动切换,需要绑定下载进度回调来实时更新。
2. 统计逻辑说明
不需要单独遍历组件统计总数,在给DownloadPage添加下载项的时候同步计数即可,逻辑更准确——毕竟未选中的组件不会添加下载任务,计数结果和实际要下载的文件数完全一致。如果确实需要单独统计选中组件数量,可以遍历WizardForm.ComponentsList条目判断选中状态实现。
3. 完整可运行实现代码
[Code] var DownloadPage: TDownloadWizardPage; TotalDownloadFiles: Integer; // 下载进度回调,实时更新标签 procedure OnDownloadProgress(const Url, FileName: String; const Progress, ProgressMax: Int64); var CurrentFileIndex: Integer; begin // 匹配当前正在下载的文件序号 for CurrentFileIndex := 0 to DownloadPage.ItemCount - 1 do begin if DownloadPage.ItemURL[CurrentFileIndex] = Url then begin // 序号从1开始计算 DownloadPage.DownloadingLabel.Caption := Format('Downloading additional files... file %d of %d, please wait...', [CurrentFileIndex + 1, TotalDownloadFiles]); Break; end; end; end; procedure InitializeWizard(); begin DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), @OnDownloadProgress); end; function NextButtonClick(CurPageID: Integer): Boolean; begin if CurPageID = wpReady then begin DownloadPage.Clear; TotalDownloadFiles := 0; // 逐个判断组件选中状态,添加下载项,同步计数 if WizardIsComponentSelected('Database\ABC') then begin DownloadPage.Add('https://example.com/MyDB1.sqlite', 'MyDB1.sqlite', ''); TotalDownloadFiles := TotalDownloadFiles + 1; end; if WizardIsComponentSelected('Database\DEF') then begin DownloadPage.Add('https://example.com/MyDB2.sqlite', 'MyDB2.sqlite', ''); TotalDownloadFiles := TotalDownloadFiles + 1; end; if WizardIsComponentSelected('Database\GHI') then begin DownloadPage.Add('https://example.com/MyDB3.sqlite', 'MyDB3.sqlite', ''); TotalDownloadFiles := TotalDownloadFiles + 1; end; // 无需要下载的文件直接跳过 if TotalDownloadFiles = 0 then begin Result := True; Exit; end; // 初始化标签为第一个文件的状态 DownloadPage.DownloadingLabel.Caption := Format('Downloading additional files... file 1 of %d, please wait...', [TotalDownloadFiles]); DownloadPage.Show; try try DownloadPage.Download; Result := True; except SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbCriticalError, MB_OK, IDOK); Result := False; end; finally DownloadPage.Hide; end; end else Result := True; end;
补充说明
如果需要单独统计选中组件的数量(而非待下载文件数),可以用如下自定义函数实现:
function GetSelectedComponentCount: Integer; var i: Integer; begin Result := 0; for i := 0 to WizardForm.ComponentsList.Items.Count - 1 do begin if WizardForm.ComponentsList.Checked[i] then Result := Result + 1; end; end;
如果存在父组件和子组件联动选中的情况,上述组件计数函数会把父子条目都算入统计,如果需要过滤父级条目,根据组件层级增加判断逻辑即可。
内容的提问来源于stack exchange,提问作者orecchione bruno

