2009-07-25 2 views
1

다음은 코드입니다.Delphi 2K9에서 런타임시 구성 요소 비활성화 및 활성화. 이상한 문제

procedure DisableContrlOL(const cArray : array of string; ReEnable : boolean = False); 
// can be called from VKP/RAW/Generation clicks 
var 
    AComponent: TComponent; 
    CompListDis, CompListEna : TStringList; 
begin 
    CompListDis := TStringList.Create; 
    CompListEna := TStringList.Create; 
    for i := Low(cArray) to High(cArray) do begin 
    AComponent := FindComponent(cArray[i]); 
    if Assigned(AComponent) then 
     if (AComponent is TControl) then begin 
     if TControl(AComponent).Enabled then 
      CompListEna.Add(TControl(AComponent).Name) 
     else 
      CompListDis.Add(TControl(AComponent).Name); 
     ShowMessage(TControl(AComponent).Name); 
     if ReEnable then begin // if reenabling needed, then all whi 
      if not TControl(AComponent).Enabled then 
      TControl(AComponent).Enabled := True; 
     end else if (TControl(AComponent).Enabled) then 
      TControl(AComponent).Enabled := False; 
     end; 
    end; 
end; 

더 이상 설명이 필요 없다고 생각합니다. ShowMessage는 각 구성 요소의 이름을 올바르게 표시하지만 StringLists에는 아무 것도 추가되지 않습니다. 왜?


업데이트 : 질문이 꽤 거칠어 짐에 따라 나는 약간의 도움이되는 대답을 확인했습니다.

나는이 코드 라인이 상용 프로젝트의 일부이고, 취미와 심장의 문제이기 때문에 매우 명확하지는 않지만 매우 제한적이라는 것을 이해합니다. 주요 문제는 이미 6h 전에 발견되었지만 Rob은이 모든 질문을 확장하기를 원했습니다. D 아니오, 불쾌감은 없습니다, 친구, 괜찮습니다. 기꺼이 도움이되는 게시물을 기쁘게받습니다. 다시 한번 감사드립니다.

+0

귀하의 문제는 '런타임'과 관련이 있다고 생각합니다. 아마도 당신이 덜 신비한 사건으로 제한한다면 그것은 효과가있을 것입니다. :-) – robsoft

+0

@robsoft : 고쳐졌습니다. –

+0

HX : 아직 답변을 얻지 못했습니다 ** ** **. 나는 약간의 상향 투표를 할 것이지만, 나는 당신이하지 않은 것을 분명히하고 싶기 때문에 뒤로 물러 설 것이다. 당신의 질문에 대답하는 사람들이 왜이 무례하다고 생각할 수 있는지 이해하십니까? 당신은 어떻게 유권자에게 투표 할 수 있는지 알고 있습니까? – Argalatyr

답변

4

목록에 아무것도 추가되지 않았다는 것을 어떻게 알 수 있습니까? 이 코드에서 코드를 작성하고 해당 코드에 대한 유일한 참조는 지역 변수에 있습니다. 이 함수가 반환 될 때 객체가 유출되므로 실제로 아무데도 사용하지 마십시오.

"모듈 테스트"에 대한 코드가 있다고하셨습니다. 그 코드는 여기에 없기 때문에 코드가이 함수의 일부가 아니라고 가정해야합니다. 그러나 목록의 내용을 검사해야하는 외부 코드가 있으면 목록을 로컬 변수로 사용할 수 없습니다. 다른 코드로 액세스 할 수 없습니다. 이 목록을 반환하거나 외부에서받은 목록을 수락하여 채워야합니다. 다음은 후자의 예 :이 기능의

procedure DisableContrlOL(const cArray: array of string; 
          Reenable: Boolean 
          CompListDis, CompListEna: TStrings); 
// can be called from VKP/RAW/Generation clicks 
var 
    AComponent: TComponent; 
    AControl: TControl; 
    i: Integer; 
begin 
    for i := Low(cArray) to High(cArray) do begin 
    AComponent := FindComponent(cArray[i]); 
    if not Assigned(AComponent) or not (AComponent is TControl) then 
     continue; 

    AControl := TControl(AComponent); 
    if AControl.Enabled then 
     CompListEna.Add(AControl.Name) 
    else 
     CompListDis.Add(AControl.Name); 
    ShowMessage(AControl.Name); 

    AControl.Enabled := Reenable; 
    end; 
end; 

발신자는 각 목록에 대한 TStrings 후손를 제공해야합니다. TStringList이 될 수도 있고 TMemo.Lines과 같은 다른 자손이 될 수도 있으므로 프로그램에서 해당 내용을 직접 볼 수 있습니다. (즉, 추상 클래스이기 때문에 그들은하지만, 단지 TStrings 수 없습니다.) 당신이 볼 수 있듯이


, 나는 코드에 다른 변경했습니다. Reenable 매개 변수를 사용하는 모든 코드를 단일 문으로 단순화 할 수 있습니다. 이미 활성화 된 컨트롤을 활성화하고 이미 비활성화 된 컨트롤을 비활성화하면 아무 작업도 수행되지 않기 때문입니다.

또한 NameTComponent의 공개 재산입니다. 이 속성을 읽기 전에 TControl으로 캐스팅 할 필요는 없지만 다른 곳에서 자주 캐스팅하는 경우 유형 캐스팅 된 TControl 값을 보유 할 새 변수를 도입하는 것이 좋으며 이로 인해 코드를 읽기가 쉽다. 읽기 쉬운 코드는 이해하기 쉬운 코드이므로 쉽게 디버깅 할 수 있습니다.이 것을 강조

+0

흠, 끈에 대한 팁, 롭 감사합니다! 그 재사용 가능한 매개 변수에 관해서 - nop, tyhere는 약간 다른 이유입니다. 내가 애플 리케이션 소스의 일부를 coppy해야 할 것이라고 설명하는 것은 꽤 길 것이다. 또한, 구성 요소에 대한 팁보다. 나는이 사실을 알고 있었지만 거의 모든 예제에서이 코드를 발견했기 때문에 ... –

+0

내 질문에 대한 답변을 잊어 버린 것 같군요 : * 어떻게 ** 당신의 코드에 문제가 있습니까? * 분명히 , "더 이상 설명이 필요 없다"는 주장은 거짓입니다. –

+0

bi는 내가 breakpoints로 단계 때 문자열 목록 pllus에 내가 dcus와 devug, thetre 아니 varable 또는 메모리 주소를 집어 들고 있으며 연속 코드에서 내가 필요한 코드를 사용하기 때문에 그것을 알고 있기 때문에 (현재 그것은 모듈 테스트를위한 것입니다), 나는 runetime리스트를 벗어났습니다. 그게 내가 뭔가 잘못 알고 있다는 것을. –

0

확실히 작동해야하는 것처럼 보입니다. 이것은 디버거가 우리가 할 수있는 것보다 더 많은 도움을 줄 수있는 종류의 것입니다.

은과 같이, 여러 라인들로 문제가있는 라인을 깨는 시도 :

if TControl(AComponent).Enabled then 
    CompListEna.Add(TControl(AComponent).Name) 
    else CompListDis.Add(TControl(AComponent).Name); 

은의 "사용 디버그 DCUs"옵션을 다시 작성하고 if 문에 중단 점을 배치합니다. 그런 다음 F7을 사용하여 논리를 따라 길을 추적하고 진행 상황을 확인하십시오.

+0

Nop, 작동하지 않습니다. 모든 문자열 목록에는 아무런 변화가 없습니다. FindComponenet(); 그냥 컨트롤 이름과 그걸로 모든 걸립니다 ... 추신 내가 dcu의를 사용 ... –

2

크게 롭의 우수한 제안을 기반으로, 그것은 당신의 코드를 단순화 할 수있는 것처럼 보인다 :

procedure DisableContrlOL(const cArray : array of string; 
           ReEnable : boolean = False); 
var 
    AComponent: TComponent; 
begin 
    for i := Low(cArray) to High(cArray) do 
    begin 
    AComponent := FindComponent(cArray[i]); 
    if Assigned(AComponent) then 
     if (AComponent is TControl) then 
     begin 
     ShowMessage(TControl(AComponent).Name); 
     TControl(AComponent).Enabled := ReEnable; 
     end; 
    end; 
end; 

명확하지 실행이를 떠날 때 그 내용이 손실 된 이후 stringlists을 위해 무엇인지 이 절차의 범위. 반환하려는 경우 호출 코드에서 생성하여 해제해야합니다.

+0

예, 고맙습니다. 이론적으로 문제가 발견되어 제거되었습니다. 감사합니다. 그러나 문자열 목록은 정렬 할 때 사용되었습니다. 실행시에 활성화되어 있고 어떤 comopoent가 정렬되어 있지 않습니다. Thasthow 나는 그들을 가능하게하거나 불가능하게 할 때마다 매개 변수를 reenable로 결정할 수 있습니다. 문자열리스트에 전혀 값이 저장되지 않았다고 생각했기 때문에 이것은 내 질문에 포함되지 않았습니다. 다시 한 번 고맙습니다. 불합리한 태도로 죄송합니다. 이 시점에서 모든 사람들이 올바른 대답을 가지고 있습니다. ;) –

+1

... 아직 그들 중 아무도 투표하지 않았습니다! 도움이되는 질문에 답해야합니다 (자신의 질문뿐만 아니라 모든 질문에 대해). * 자신의 질문에 대한 최선의 대답을 수락하십시오. – Argalatyr

+2

호출 코드에서 생성하고 해방한다면, 그것들을'var' 매개 변수로 만들면 안됩니다. 예를 들어 나의 편집 된 답변을보십시오. –