2016-09-02 3 views
2

다른 작업을 선택했을 때 작업을 선택 취소 할 수 있도록 WizardForm.TasksList.OnClickCheck 이벤트를 가로 채려고합니다. 나는 보통의 라디오 버튼이이 상황에서 사용될 것이지만, 다른 하나가 선택 될 때 하나의 태스크를 자동으로 체크 해제하는 것은 다중 계층 적 태스크의 사용과 라디오 버튼이 사용된다면 당신은 항상 두 개는 작업 하위 트리의 맨 위에있을 때 선택됩니다. 일관성을 유지하기 위해 작업 계층 구조를 다시 설계하는 것은 적합하지 않습니다. 이는 이후 버전의 설치 프로그램에서 제거 될 두 가지 임시 작업을 포함하기 때문입니다. 나는이 코드를 실행하면Inno Setup 다른 작업이 선택되었을 때 작업을 선택 해제하십시오.

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은 이노 설정 자체 (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

답변을 완료했습니다. –