Inno Setup当另一个任务被选中时,取消选中一个任务 [英] Inno Setup Uncheck a task when another task is checked

查看:175
本文介绍了Inno Setup当另一个任务被选中时,取消选中一个任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图拦截WizardForm.TasksList.OnClickCheck事件,以便在选择另一个任务时可以取消选中该任务.我知道通常在这种情况下会使用单选按钮,但是由于使用了多个分层任务,并且如果使用单选按钮,则您始终必须选择以下一项,因此在选择另一个任务时自动取消选中一个任务的效果更好在任务子树顶部时选择的两个.为了保持一致性,重新设计任务层次结构是不可行的,因为这将包括两个临时任务,这些临时任务将在安装程序的未来版本中删除.我写了以下代码来做到这一点:

I am trying to intercept the WizardForm.TasksList.OnClickCheck event so that I can uncheck a task when another task is selected. I know that normally radio buttons would be used in this situation, but automatically unchecking one task when another is selected works better here due to the use of multiple hierarchical tasks and the fact that if radio buttons are used, you always have to have one of the two selected when at the top of the task subtree. Redesigning the task hierarchy is not feasible in order to maintain consistency, as this is to include two temporary tasks that will be removed in a future version of the installer. I have written the following to do this:

var
  DefaultTasksClickCheck: TNotifyEvent;

{ Uncheck tasks based on what other tasks are selected }
procedure UpdateTasks();
var
  intIndex: Integer;
begin
  with WizardForm.TasksList do
    begin
      if IsTaskSelected('Task1') then
        begin
          intIndex := WizardForm.TasksList.Items.IndexOf('Task36 Description');
          CheckItem(intIndex, coUncheck);
        end;
      if IsTaskSelected('Task36') then
        begin
          intIndex := WizardForm.TasksList.Items.IndexOf('Task1 Description');
          CheckItem(intIndex, coUncheck);
        end;
    end;
end;

{ Update the task states if the task states change and restore the original event handler procedure }
procedure TasksClickCheck(Sender: TObject);
begin
  DefaultTasksClickCheck(Sender);
  UpdateTasks;
end;

procedure InitializeWizard();
begin
  { Store the original Tasks Page OnClickCheck event procedure and assign custom procedure }
  DefaultTasksClickCheck := WizardForm.TasksList.OnClickCheck;
  WizardForm.TasksList.OnClickCheck := @TasksClickCheck;
end;

但是,当我运行代码时,我得到:

However, when I run the code, I get an:

超出范围

单击任何复选框时出现

错误,突出显示DefaultTasksClickCheck(Sender);作为违规行.如果我注释掉这一行,我将不再收到错误,但显然不再还原原始事件处理程序,并且它仍然无法正确检查和取消选中任务,而在选中Task1时无法选中Task36.我做错了什么?

error, when clicking any checkbox, with DefaultTasksClickCheck(Sender); highlighted as the offending line. If I comment out this line, I no longer get the error, but am obviously no longer restoring the original event handler and it still doesn't check and uncheck the tasks correctly, with Task36 uncheckable when Task1 is checked. What have I done wrong?

推荐答案

  1. WizardForm.TasksList.OnClickCheck不是由Inno Setup本身分配的(与WizardForm.ComponentsList.OnClickCheck相反),因此您不能调用它.

  1. The WizardForm.TasksList.OnClickCheck is not assigned by the Inno Setup itself (contrary to WizardForm.ComponentsList.OnClickCheck), so you cannot call it.

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

To fix the problem, either:

  • 完全删除DefaultTasksClickCheck;
  • 或者如果希望在以后的Inno Setup版本中使用该事件以防万一,请在调用它之前检查它是否为nil.
  • completely remove the DefaultTasksClickCheck;
  • or if you want to be covered in case the event starts being used in future versions of Inno Setup, check if it is nil before calling it.

您不知道最近在OnClickCheck处理程序中检查了哪些任务.因此,您必须记住先前检查过的任务才能正确决定要取消选择的任务.

You cannot know what task was checked most recently in the OnClickCheck handler. So you have to remember the previously checked task to correctly decide what task to unselect.

[Tasks]
Name: Task1; Description: "Task1 Description"
Name: Task36; Description: "Task36 Description"; Flags: unchecked

[Code]

var
  DefaultTasksClickCheck: TNotifyEvent;
  Task1Selected: Boolean;

procedure UpdateTasks;
var
  Index: Integer;
begin
  { Task1 was just checked, uncheck Task36 }
  if (not Task1Selected) and IsTaskSelected('Task1') then
  begin
    Index := WizardForm.TasksList.Items.IndexOf('Task36 Description');
    WizardForm.TasksList.CheckItem(Index, coUncheck);
    Task1Selected := True;
  end
    else 
  { Task36 was just checked, uncheck Task1 }
  if Task1Selected and IsTaskSelected('Task36') then
  begin
    Index := WizardForm.TasksList.Items.IndexOf('Task1 Description');
    WizardForm.TasksList.CheckItem(Index, coUncheck);
    Task1Selected := False;
  end;
end;

procedure TasksClickCheck(Sender: TObject);
begin
  if DefaultTasksClickCheck <> nil then
    DefaultTasksClickCheck(Sender);
  UpdateTasks;
end;

procedure CurPageChanged(CurPageID: Integer);
begin
  if CurPageID = wpSelectTasks then
  begin
    { Only now is the task list initialized, check what is the current state }
    { This is particularly important during upgrades, }
    { when the task does not have its default state }
    Task1Selected := IsTaskSelected('Task1');
  end;
end;

procedure InitializeWizard();
begin
  DefaultTasksClickCheck := WizardForm.TasksList.OnClickCheck;
  WizardForm.TasksList.OnClickCheck := @TasksClickCheck;
end;

在Inno Setup 6中,除了使用索引之外,您还可以使用 WizardSelectTasks .例如,请参见 Inno设置:如果选择了另一个组件,如何自动选择一个组件?.

In Inno Setup 6, instead of using indexes, you can also use task names with use of WizardIsTaskSelected and WizardSelectTasks. For an example, see Inno Setup: how to auto select a component if another component is selected?.

有关检测已检查项目的更通用解决方案,请参见 Inno Setup在TasksList中检测已更改的任务/项目. OnClickCheck事件.

这篇关于Inno Setup当另一个任务被选中时,取消选中一个任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆