2013-06-18 2 views
0

에서 개체의 속성을 설정 내가 어떤 특성을 가진 개체가 있습니다다른 프로 시저

Obj.Big 
Obj.Rotate 
Obj.Paint 
Obj.Lines 

등 그들은 모두 부울 유형의 속성입니다.

procedure TMainForm.Create(Sender:TObject); 
begin 
    SetParameter(BigCheckBox, Obj.Big); 
    SetParameter(RotateCheckBox, Obj.Rotate); 
    SetParameter(PaintCheckBox, Obj.Paint); 
    SetParameter(LinesCheckBox, Obj.Lines); 
end; 

SetParameter 절차는 다음과 같이 간다 :

procedure TMainForm.SetParameter(ACheckBox : TCheckBox; ABoolOption : Boolean); 
begin 
    if(ACheckBox.Checked) and (ACheckBox.Enabled) then begin 
     ABoolOption := true; 
    end 
    else if(not ACheckBox.Checked) and (ACheckBox.Enabled) then begin 
     ABoolOption := false; 
    end; 
end; 

그것은 체크 박스 객체와 객체로 건네의 부울 속성의 속성과를 받아 내 주요 절차에서

, 나는 다른 프로 시저를 호출 ABoolOption. LinesCheckBox.Checked := Obj.Lines을 간단히 처리 할 수 ​​없습니다. 체크 박스가 채워 졌을 때 "아무 것도하지 마십시오"라는 동작이 필요하기 때문입니다 (모두 트라이 상태입니다). 이걸 실행하면 해당 객체의 매개 변수가 변경되지 않습니다. 왜 이런거야?

+0

을 : 당신은 D2010 +를 사용하는 경우,

uses ..., TypInfo; procedure TMainForm.Create(Sender:TObject); begin SetBooleanParameter(BigCheckBox, Obj, 'Big'); SetBooleanParameter(RotateCheckBox, Obj, 'Rotate'); SetBooleanParameter(PaintCheckBox, Obj, 'Paint'); SetBooleanParameter(LinesCheckBox, Obj, 'Lines'); end; procedure TMainForm.SetBooleanParameter(ACheckBox : TCheckBox; Obj: TObject; const PropName: String); begin if ACheckBox.Enabled then begin // NOTE: this only works if the properties are declared as 'published' SetOrdProp(Obj, PropName, Ord(ACheckBox.Checked)); end; end; 

을 또는 : 당신이 실제로 속성 값을 업데이트 할 경우, 예를 들어, 하나 대신 RTTI를 켄이 시사하는 무엇, 또는 사용할 필요가 간단한 변수를 전달하더라도 변경되지 않습니다. 'out-parameters'와'var-parameters'에 대해서 읽어보십시오. 프로 시저는 값을 얻고 원하는대로 변경할 수 있습니다. 프로 시저 본문 외부로 절대 이동하지 않습니다. –

답변

5

당신은 속성을 전달하지 않습니다. 해당 속성의 을 전달 중입니다. IOW, SetParameterACheckBox, True 또는 ACheckBox, False이 수신되고 있으므로 변경할 내용이 없습니다.

function TMainForm.SetBooleanValue(const ACheckBox: TCheckBox): Boolean; 
begin 
    Result := (ACheckBox.Checked) and (ACheckBox.Enabled); 
end; 

그리고 그것을 좋아 사용 : 더 나은 방법은 함수에 SetParameter 절차를 변경할 수 있습니다 당신은 세 번째 옵션을 허용해야하는 경우 전에 먼저, 당신이 그것을 확인해야합니다

Obj.Big := SetBooleanValue(BigCheckbox); 
Obj.Rotate := SetBooleanValue(RotateCheckBox); 
Obj.Paint := SetBooleanValue(PaintCheckBox); 
Obj.Lines := SetBooleanValue(LinesCheckBox); 

SetBooleanValue :

if not ThirdCondition then 
    Obj.Big := SetBooleanValue(BigCheckBox); 
+0

나는 'BigCheckBox.State = cbGrayed'를 if 문 비교로 사용하고 주 프로 시저에서 객체의 속성을 설정하고 함수의 결과를 사용하여 집합을 수행했습니다. 이 모든 것이 현재 작동합니다. 감사. – ikathegreat

1

귀하의 절차는 귀하가 생각하는대로 수행되지 않습니다. 아니요 속성 자체를 전달하는 대신 속성의 CURRENT VALUE을 전달합니다.

uses 
    ..., Rtti; 

procedure TMainForm.Create(Sender:TObject); 
begin 
    SetBooleanParameter(BigCheckBox, Obj, 'Big'); 
    SetBooleanParameter(RotateCheckBox, Obj, 'Rotate'); 
    SetBooleanParameter(PaintCheckBox, Obj, 'Paint'); 
    SetBooleanParameter(LinesCheckBox, Obj, 'Lines'); 
end; 

procedure TMainForm.SetBooleanParameter(ACheckBox : TCheckBox; Obj: TObject; const PropName: String); 
var 
    Ctx: TRttiContext; 
begin 
    if ACheckBox.Enabled then 
    begin 
    // NOTE: this approach does not need the properties to be declared as 'published' 
    Ctx.GetType(Obj.ClassType).GetProperty(PropName).SetValue(Obj, TValue.From<Boolean>(ACheckBox.Checked)); 
    end; 
end; 
+0

왜 TRttiContext.Create를 호출 한 다음 ctx.Free를 호출합니까? –

+0

@DavidHeffernen : 오래된 습관. –

관련 문제