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

时间:2015-06-17 08:52:38

标签: inno-setup

我有一个Inno-setup脚本,其中包含带复选框和组合框的组件页面。我想取消选中并禁用“代码”部分中的某些组件,我使用this answer来执行此操作,现在我有了这段代码:

[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;

使用此复选框" help"未经检查并禁用代码,但即使用户无法点击"帮助"复选框来检查它,他仍然可以选择"完全安装"使用组合框可以改变"帮助"复选框从未选中复选(即使复选框保持禁用状态)。

我想要做的是完全禁用此组件并阻止用户选择它(不考虑用户如何尝试这样做,点击它或选择"完全安装" in组合框。)

1 个答案:

答案 0 :(得分:3)

这是另一种,仍然是hacky方式来做你想要的。我在这里使用了不同的概念。本质上,它是关于准备一组应该禁用和取消选中的组件索引(我在这里调用 ghosted )并调用UpdateGhostItems(False)取消选中和禁用组件列表中准备好的数组的索引项。

从安装类型组合框更改事件更新仅通过调用UpdateGhostItems(True)检查此组合框可能更改的状态:

[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;
相关问题