2016-09-02 14 views
2

WizardForm.TasksList.OnClickCheckイベントを傍受しようとしています。別のタスクが選択されたときにタスクのチェックを外すことができます。私は通常のラジオボタンがこの状況で使用されることを知っていますが、別のものが選択されたときに自動的に1つのタスクのチェックを外すのは、複数の階層的なタスクの使用とラジオボタンを使用すると、 2つはタスクサブツリーの先頭にあるときに選択されます。一貫性を維持するために、タスク階層を再設計することは現実的ではありません。これは、インストーラの将来のバージョンで削除される2つの一時的なタスクを含めるためです。すべてのチェックボックスをクリックすると、Inno Setup別のタスクがチェックされているときにタスクのチェックを外す

PROC範囲外エラー:私は、コードを実行したときしかし、私が手

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; 

:私はこれを行うには、次を書かれています、DefaultTasksClickCheck(Sender);が違反行として強調表示されています。この行をコメントアウトするとエラーは発生しなくなりますが、もはや元のイベントハンドラを元に戻すことはなくなり、Task1をチェックするとTask36をチェックしないようにしてタスクを正しくチェックしたりチェックを外したりしません。私は何を間違えたのですか?

答えて

2
  1. WizardForm.TasksList.OnClickCheckは、Inno Setupの自身(WizardForm.ComponentsList.OnClickCheckに反して)によって割り当てられていないので、あなたはそれを呼び出すことはできません。この問題を解決するには

    、次のいずれか

    • 完全DefaultTasksClickCheckを削除します。
    • 、またはイベントがInno Setupの将来のバージョンで使用される場合に備えておきたい場合は、それを呼び出す前にnilであるかどうかを確認してください。
  2. 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 Detect changed task/item in TasksList.OnClickCheck eventを参照してください。

+0

ありがとうございました。それはエラーを説明します。しかし、CheckItem(intIndex、coUncheck);または 'WizardForm.TasksList.Checked [intIndex]:= False; 'を使用するかどうかにかかわらず、チェック解除は正しく機能しません。 Task1をチェックすると、Task36は常にチェックが外されます。 –

+0

私は答えを完了しました。 –

関連する問題