2017-08-20 50 views
4

私はDelphiのGetPropValue()関数を使用して、TControlのオブジェクトの特定のプロパティの値を取得しています。 Value,Opacityなどの単純なプロパティ値を取得するとすべて正常に動作しますが、私はfiremonkeyを使用しているため、RotationCenterなどの拡張プロパティがあり、RotationCenter.XRotationCenter.Y、またはTextSettingsのテキストプロパティもあります。これらのサブタイプのプロパティでは値を取得できません。この例ではDelphi - GetPropValue()でプロパティ値を取得

私が正しく値を取得:

If IsPublishedProp (Component_cc, 'Value') then 
    EditValue.Text: = GetPropValue (Component_cc, 'Value', true); 

Component_cc:TControl。また、動的に作成され、あらゆるタイプのFiremonkeyコンポーネント(これまでのすべては問題ありません。すべて動作します)でもかまいません。

以下のフォームを使用する必要がある場合、動作しません。

If IsPublishedProp (Component_cc, 'RotationCenter.X') then 
    EditRotationCenterX.Text: = GetPropValue (CC_component, 'RotationCenter.X', true); 

この機能でこれらのプロパティを拡張する方法を知っている人はいますか?

+0

あなたは構造でより深く行く必要があります。 'TPosition'オブジェクトに' X'プロパティを求めます。 – Victoria

答えて

6

まず、CC_componentのRotationCenterプロパティは、TPersistentから降順であるTPositionクラスのインスタンスです。

第2に、IsPublishedPropを呼び出すときにドット表記を使用することはできません。

あなたはまず内部TPositionインスタンスを取得し、そこからXプロパティにアクセスするためにGetObjectPropを使用することができます。

Button1EditRotationCenterX呼ばTEditと呼ばれるTButtonが含まれている一つの形を持つ単純なFMXアプリケーションを想定します。)

procedure TForm1.Button1Click(Sender: TObject); 

var 
    CC_component : TComponent; 
    CC_component_RotationCenter : TPosition; 

begin 
    CC_component := Button1; 

    if IsPublishedProp(CC_component, 'RotationCenter') then 
     begin 
     CC_component_RotationCenter := TPosition(GetObjectProp(CC_component, 'RotationCenter')); 
     EditRotationCenterX.Text := CC_component_RotationCenter.X.ToString; 
     end 
end; 

TYのプロパティの更新、 pe Set:

Set typeプロパティの場合、GetOrdPropを使用して順序値を取得する必要があります。これは、現在の値にどの要素が含まれているかを表すビットの配列になります。次に、適切なビットが設定されているかどうかをテストします。これは私が好む方法です。

また、GetSetPropを使用すると、セットの現在の値の要素のテキスト表現が返されます。たとえば、Setの値が[TCorner.BottonLeft, TCorner.TopRight]の場合、文字列値 "TopRight、BottonLeft"が返されます。次に、ターゲット要素の名前が返された文字列のどこにでも現れるかどうかを確認します。このメソッドは、Delphi RTLまたはFMXライブラリが将来変更されると失敗する可能性があります。

(この例では、古いRTTIについて話したとき、あなたはこれを行うことができ

:)上記
procedure TForm1.Button1Click(Sender: TObject); 

var 
    CC_component : TComponent; 
    CC_component_Corners : nativeint; 

    CC_component_CornersAsString : string; 

begin 
    CC_component := Rectangle1; 
    if IsPublishedProp(CC_component, 'Corners') then 
     begin 
     // Using this method will make your code less sensitive to 
     // changes in the ordinal values of the Set's members or  
     // changes to names of the enumeration elements.  
     //  
     CC_component_Corners := GetOrdProp(CC_component,'Corners'); 

     cbCornerBottonRight.IsChecked := ((1 shl ord(TCorner.BottomRight)) and CC_component_Corners) <> 0; 


     // This approach may break if the names of the elements of 
     // the TCorner enumeration are ever changed. (BTW, they have 
     // been in the past: "cvTopLeft", "cvTopRight", "cvBottomLeft", 
     // and "cvBottomRight" are now deprecated) 
     //  
     CC_component_CornersAsString := GetSetProp(CC_component,'Corners'); 

     cbCornerBottonRight.IsChecked := CC_component_CornersAsString.IndexOf('BottomRight') >= 0; 
     end; 
end; 
+0

こんにちは。私はもっ​​と助けを求めたいと思っています。あなたが教えた方法で様々なプロパティを理解し管理しましたが、コーナーのようないくつかのプロパティでは値を取得できません。ここで私はどのようにしたのですか: if IsPublishedProp(Component_cc、 'Corners')then begin Cornersv:= TCorner(GetObjectProp(Componente_cc、 'Corners'))); ckCornerBottonRight.IsChecked:= Cornersv.crBottomRight; end' erroêeste: E2010互換性のないタイプ: 'Boolean'と 'TCorner'。 ckCornerBottonRightは 'TCheckbox'です – Anderson

+0

' Corners'プロパティはオブジェクトインスタンスではありません。 ** Set **のタイプです。これは 'TPosition'オブジェクトインスタンスとは全く異なる操作を必要とします。 ** Set **型のプロパティの値を取得する方法を含めるように答えを更新しました。 –

+0

また、この拡張機能を** Set ** typeプロパティに含めるように質問を更新することもできます。 –

5

から簡単なFMXアプリケーションへRectangle1と呼ばTRectangle形状とcbCornerBottonRightと呼ばれるTCheckBoxを追加します。あなたは構造を深く理解する必要があります。TPositionオブジェクトXプロパティを求める:

var 
    O: TObject; 
    X: Integer; 
begin 
    if PropIsType(Component_cc, 'RotationCenter', tkClass) then 
    begin 
    O := GetObjectProp(Component_cc, 'RotationCenter'); 
    if Assigned(O) and PropIsType(O, 'X', tkInteger) then 
     X := GetOrdProp(O, 'X'); 
    end; 
end; 
+3

'TPosition'オブジェクトをすでに持っている人は、直接読むことができるときにRTTIを使って' X'プロパティを読む価値はありません。 'S:= RotationCenter.X.ToString; ' –

+0

ありがとう、ビクトリア! – Anderson

+0

@Remyなので、RTTIを使って 'TPosition'オブジェクトを取得する価値はありません。私はあなたのポイントを見ます(' RotationCenter'変数を使うべきではありません)。鉱山からコピーされた回答にあなたのコメントをドロップすることができます(より安全ではないタイプキャストで)。私はこれを時間内に削除しようとしています.. – Victoria

関連する問題