Inno Setup 在选中另一个任务时取消选中一个任务
Inno Setup Uncheck a task when another task is checked
我正在尝试拦截 WizardForm.TasksList.OnClickCheck
事件,以便在选择另一个任务时取消选中一个任务。我知道通常在这种情况下会使用单选按钮,但是由于使用了多个分层任务,而且如果使用单选按钮,您总是必须拥有其中一个,因此在选择另一个任务时自动取消选中一个任务在这里效果更好在任务子树的顶部时选择的两个。重新设计任务层次结构以保持一致性是不可行的,因为这将包括两个临时任务,这些任务将在安装程序的未来版本中删除。为此,我编写了以下内容:
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;
但是,当我 运行 代码时,我得到一个:
Out of Proc Range
错误,单击任何复选框时,DefaultTasksClickCheck(Sender);
突出显示为有问题的行。如果我注释掉这一行,我将不再收到错误,但显然不再恢复原始事件处理程序,它仍然无法正确检查和取消选中任务,选中 Task1 时无法选中 Task36。我做错了什么?
WizardForm.TasksList.OnClickCheck
不是由Inno Setup本身赋值的(与WizardForm.ComponentsList.OnClickCheck
相反),所以你不能调用它。
要解决此问题,可以:
- 完全删除
DefaultTasksClickCheck
;
- 或者,如果您希望在事件开始在 Inno Setup 的未来版本中使用时被覆盖,请在调用它之前检查它是否
nil
。
您无法知道最近在 OnClickCheck
处理程序中检查了哪个任务。所以你必须记住之前检查过的任务才能正确决定取消选择什么任务。
[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 中,除了使用索引之外,您还可以通过 WizardIsTaskSelected
and WizardSelectTasks
. For an example, see .
使用任务名称
有关检测已检查项目的更通用解决方案,请参阅 Inno Setup Detect changed task/item in TasksList.OnClickCheck event。
我正在尝试拦截 WizardForm.TasksList.OnClickCheck
事件,以便在选择另一个任务时取消选中一个任务。我知道通常在这种情况下会使用单选按钮,但是由于使用了多个分层任务,而且如果使用单选按钮,您总是必须拥有其中一个,因此在选择另一个任务时自动取消选中一个任务在这里效果更好在任务子树的顶部时选择的两个。重新设计任务层次结构以保持一致性是不可行的,因为这将包括两个临时任务,这些任务将在安装程序的未来版本中删除。为此,我编写了以下内容:
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;
但是,当我 运行 代码时,我得到一个:
Out of Proc Range
错误,单击任何复选框时,DefaultTasksClickCheck(Sender);
突出显示为有问题的行。如果我注释掉这一行,我将不再收到错误,但显然不再恢复原始事件处理程序,它仍然无法正确检查和取消选中任务,选中 Task1 时无法选中 Task36。我做错了什么?
WizardForm.TasksList.OnClickCheck
不是由Inno Setup本身赋值的(与WizardForm.ComponentsList.OnClickCheck
相反),所以你不能调用它。要解决此问题,可以:
- 完全删除
DefaultTasksClickCheck
; - 或者,如果您希望在事件开始在 Inno Setup 的未来版本中使用时被覆盖,请在调用它之前检查它是否
nil
。
- 完全删除
您无法知道最近在
OnClickCheck
处理程序中检查了哪个任务。所以你必须记住之前检查过的任务才能正确决定取消选择什么任务。
[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 中,除了使用索引之外,您还可以通过 WizardIsTaskSelected
and WizardSelectTasks
. For an example, see
有关检测已检查项目的更通用解决方案,请参阅 Inno Setup Detect changed task/item in TasksList.OnClickCheck event。