Inno setup Inno Setup在选中另一个任务时取消选中该任务

Inno setup Inno Setup在选中另一个任务时取消选中该任务,inno-setup,pascalscript,Inno Setup,Pascalscript,我试图截获向导form.TasksList.OnClickCheck事件,以便在选择其他任务时取消选中任务。我知道在这种情况下通常会使用单选按钮,但在选择另一个任务时自动取消选中一个任务在这里效果更好,因为使用了多个分层任务,而且如果使用单选按钮,则在任务子树的顶部总是必须选择两个任务中的一个。为了保持一致性,重新设计任务层次结构是不可行的,因为这将包括两个临时任务,它们将在安装程序的未来版本中删除。为此,我写了以下内容: var DefaultTasksClickCheck:TNotifyEv

我试图截获
向导form.TasksList.OnClickCheck
事件,以便在选择其他任务时取消选中任务。我知道在这种情况下通常会使用单选按钮,但在选择另一个任务时自动取消选中一个任务在这里效果更好,因为使用了多个分层任务,而且如果使用单选按钮,则在任务子树的顶部总是必须选择两个任务中的一个。为了保持一致性,重新设计任务层次结构是不可行的,因为这将包括两个临时任务,它们将在安装程序的未来版本中删除。为此,我写了以下内容:

var
DefaultTasksClickCheck:TNotifyEvent;
{根据选择的其他任务取消选中任务}
过程UpdateTasks();
变量
intIndex:整数;
开始
使用WizardForm.TasksList do
开始
如果选择了ISTASK1(“任务1”),则
开始
intIndex:=WizardForm.TasksList.Items.IndexOf('Task36说明');
检查项目(intIndex、ConCheck);
结束;
如果选择了ISTASK36(“任务36”),则
开始
intIndex:=WizardForm.TasksList.Items.IndexOf('Task1说明');
检查项目(intIndex、ConCheck);
结束;
结束;
结束;
{如果任务状态更改,请更新任务状态并还原原始事件处理程序过程}
程序任务ICKCheck(发送方:TObject);
开始
DefaultTasksClickCheck(发送方);
更新任务;
结束;
过程初始化Wizard();
开始
{将原始任务页面存储在ClickCheck事件过程和分配自定义过程上}
DefaultTasksClickCheck:=WizardForm.TasksList.OnClickCheck;
WizardForm.TasksList.OnClickCheck:=@TasksClickCheck;
结束;
但是,当我运行代码时,我会得到:

超出程序范围

错误,单击任何复选框时,使用
DefaultTasksClickCheck(发送者)突出显示为违规行。如果我注释掉这一行,我不再得到错误,但显然不再恢复原始事件处理程序,并且它仍然没有正确地检查和取消检查任务,在检查Task1时Task36不可检查。我做错了什么

  • Inno安装程序本身没有分配
    WizardForm.TasksList.OnClickCheck
    (与
    WizardForm.ComponentsList.OnClickCheck
    相反),因此无法调用它

    要解决此问题,请执行以下任一操作:

    • 完全删除
      defaulttaskslickcheck
    • 或者,如果您希望在事件开始在Inno Setup的未来版本中使用时被覆盖,请在调用它之前检查它是否为
      nil
  • 您无法知道最近在
    OnClickCheck
    处理程序中检查了什么任务。因此,您必须记住之前选中的任务,才能正确决定取消选中的任务

  • [任务]
    姓名:Task1 ;;说明:“任务1说明”
    姓名:Task36 ;;说明:“任务36说明”;标志:未选中
    [守则]
    变量
    DefaultTasksClickCheck:TNotifyEvent;
    Task1Selected:布尔值;
    程序更新任务;
    变量
    索引:整数;
    开始
    {刚刚选中Task1,取消选中Task36}
    如果(未选择任务1)和IsTaskSelected(“任务1”),则
    开始
    索引:=WizardForm.TasksList.Items.IndexOf('Task36说明');
    WizardForm.TasksList.CheckItem(索引、检查);
    Task1Selected:=真;
    结束
    其他的
    {Task36刚刚被选中,取消选中Task1}
    如果选择了Task1并选择了IsTask36,则
    开始
    索引:=WizardForm.TasksList.Items.IndexOf('Task1说明');
    WizardForm.TasksList.CheckItem(索引、检查);
    Task1Selected:=False;
    结束;
    结束;
    程序任务ICKCheck(发送方:TObject);
    开始
    如果DefaultTasksClickCheck为零,则
    DefaultTasksClickCheck(发送方);
    更新任务;
    结束;
    过程CurPageChanged(CurPageID:Integer);
    开始
    如果CurPageID=wpSelectTasks,则
    开始
    {任务列表现在才初始化,请检查当前状态}
    {这在升级期间尤其重要,}
    {当任务没有默认状态时}
    Task1Selected:=IsTaskSelected('Task1');
    结束;
    结束;
    过程初始化Wizard();
    开始
    DefaultTasksClickCheck:=WizardForm.TasksList.OnClickCheck;
    WizardForm.TasksList.OnClickCheck:=@TasksClickCheck;
    结束;
    
    在Inno Setup 6中,您还可以使用和来使用任务名称,而不是使用索引。有关示例,请参见



    有关检测已检查项目的更通用解决方案,请参阅。

    谢谢Martin。这就是错误的原因。但是,无论我是否使用
    CheckItem(intIndex,conCheck),取消选中都无法正常工作
    向导窗体.TasksList.Checked[intIndex]:=False。选中Task1时,Task36始终不可选中。我已完成答案。