Inno setup 如何从代码部分完全禁用Inno设置中的特定组件?

Inno setup 如何从代码部分完全禁用Inno设置中的特定组件?,inno-setup,Inno Setup,我有一个Inno设置脚本,其中有一个带有复选框和组合框的组件页面。我想取消选中并禁用代码部分中的某些组件,我过去经常这样做,现在我有了以下代码: [Setup] AppName=My Program AppVersion=1.5 DefaultDirName={pf}\My Program DefaultGroupName=My Program UninstallDisplayIcon={app}\MyProg.exe OutputDir=userdocs:Inno Setup Examples

我有一个Inno设置脚本,其中有一个带有复选框和组合框的组件页面。我想取消选中并禁用代码部分中的某些组件,我过去经常这样做,现在我有了以下代码:

[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
UninstallDisplayIcon={app}\MyProg.exe
OutputDir=userdocs:Inno Setup Examples Output

[Types]
Name: "full"; Description: "Full installation"
Name: "compact"; Description: "Compact installation"
Name: "custom"; Description: "Custom installation"; Flags: iscustom

[Components]
Name: "program"; Description: "Program Files"; Types: full compact custom; 
Name: "help"; Description: "Help File"; Types: full
Name: "readme"; Description: "Readme File"; Types: full
Name: "readme\en"; Description: "English"; Flags: exclusive
Name: "readme\de"; Description: "German"; Flags: exclusive

[code]
procedure CurPageChanged(CurPageID: Integer);
begin
  if CurPageID = wpSelectComponents then
    if (True) then  //Here my own condition instead of "(True)"
    begin
      WizardForm.ComponentsList.Checked[1] := False;
      WizardForm.ComponentsList.ItemEnabled[1] := False;
    end;
end;
使用此选项,复选框“帮助”将被取消选中并从代码中禁用,但是,即使用户无法单击“帮助”复选框进行选中,他仍然可以使用组合框选择“完全安装”,从而将“帮助”复选框的状态从未选中更改为已选中(即使复选框保持禁用状态)


我想做的是完全禁用此组件,并阻止用户选择它(不考虑用户如何尝试,不考虑单击它或在组合框中选择“完全安装”)

这里是另一种仍然很难做到的方法。我在这里使用了不同的概念。本质上,它是关于准备一个应该被禁用和取消选中的组件索引数组(我在这里称之为ghosted),并调用
UpdateHostItems(False)
,取消选中并禁用组件列表中准备好的数组中的索引项

从“安装类型”组合框中,仅更新“更改事件”,通过调用
updateHostItems(True)
,选中此组合框可能更改的状态:


我知道我可以做到,但我想让用户保留使用组合框的可能性(当然,如果组件是启用的)。事实上,根据某些条件,我的一半组件可以从代码中禁用,因此如果我删除所有组件的类型,我就没有兴趣拥有一个带有预定义选项的组合框。但我想保留它,因为这是一个很好的功能,可以为用户使用。我明白你的观点,但是,pfew,那将是丑陋的,丑陋的代码。由于缺少对基础项属性的访问,您将需要截取该组合框更改事件(因为当该组合框更改选中复选框时,组件列表本身不会触发任何事件),并且在该截取中取消选中刚刚选中的组件,by,err,disabled状态?不,禁用的组件可能也是固定组件,需要通过一些额外的标志进行控制。你准备好了吗?好的,我从你的解释中确实看出这并不简单!但我仍然很有兴趣做这件事。
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program

[Types]
Name: "full"; Description: "Full installation"
Name: "compact"; Description: "Compact installation"
Name: "custom"; Description: "Custom installation"; Flags: iscustom

[Components]
Name: "program"; Description: "Program Files"; Types: full compact custom; 
Name: "help"; Description: "Help File"; Types: full
Name: "readme"; Description: "Readme File"; Types: full
Name: "readme\en"; Description: "English"; Flags: exclusive
Name: "readme\de"; Description: "German"; Flags: exclusive

[Code]
var
  TypeChange: TNotifyEvent;
  GhostItems: array of Integer;

procedure UpdateGhostItems(CheckOnly: Boolean);
var
  I: Integer;
begin
  for I := 0 to GetArrayLength(GhostItems) - 1 do
  begin
    WizardForm.ComponentsList.Checked[GhostItems[I]] := False;
    if not CheckOnly then
      WizardForm.ComponentsList.ItemEnabled[GhostItems[I]] := False;
  end;
end;

procedure TypesComboChange(Sender: TObject);
begin
  // call the original event method
  TypeChange(Sender);
  // this will uncheck all the items from the GhostItems array;
  // this includes those that were checked by the above method
  // call; for GhostItems array description see below
  UpdateGhostItems(True);
end;

procedure InitializeWizard;
begin
  // store the original TypesCombo change event method
  TypeChange := WizardForm.TypesCombo.OnChange;
  // and assign it our interceptor
  WizardForm.TypesCombo.OnChange := @TypesComboChange;

  // the following code block is for setting ghosted components;
  // in real you might call it in some later stage of your setup

  // quite comfortable looks to me using array of indices of the
  // components that should remain always unchecked and disabled
  // I'm gonna prepare this array at the initialization but it's
  // really upon you when would you do so; so let's ghost 1 item
  SetArrayLength(GhostItems, 1);
  // ...with index 1
  GhostItems[0] := 1;
  // this call will uncheck and disable all the items from the
  // prepared GhostItems array; do note that this is a one way
  // road - once you disable a component, it won't get enabled
  // again (you would have to remember their previous state)
  UpdateGhostItems(False);
end;