これは、コントロールのTextSettings.Font
プロパティにRTTIでアクセスしているother RTTI issueに似ています。同じことは、ネストされた各サブプロパティについて
など、Stroke.Color
のように、任意のネストされた財産のために適用され、必要に応じて、希望するサブオブジェクトに到達するまで、あなたがして、繰り返し、に含むオブジェクトを取得する必要がありますを取得/設定することができます。
ので、この場合には、あなたは、あなたは、そのオブジェクトのプロパティを設定するためにSetPropValue()
を使用することができ、Stroke
プロパティオブジェクトを取得するためにGetObjectProp()
を使用する必要があります。たとえば、次のように
uses
..., TypInfo;
var
Componente_cc: TControl;
procedure TfrmPrincipal.AlteraPropriedades;
var
Stroke: TObject;
begin
if IsPublishedProp(Componente_cc, 'Stroke') then
begin
Stroke := GetObjectProp(Componente_cc, 'Stroke');
if Stroke <> nil then
SetPropValue(Stroke, 'Color', ...);
end;
end;
または、指定されたプロパティの二重のRTTIの検索を避けるために:
より強力な
Enhanced RTTIは、Delphi 2010で導入されたことをメモ(このRTTIはちょうど公表に限定されるものではない
uses
..., TypInfo;
var
Componente_cc: TControl;
procedure TfrmPrincipal.AlteraPropriedades;
var
PropInfo: PPropInfo;
Stroke: TObject;
begin
PropInfo := GetPropInfo(Componente_cc, 'Stroke', [tkClass]);
if PropInfo <> nil then
begin
Stroke := GetObjectProp(Componente_cc, PropInfo);
if Stroke <> nil then
SetPropValue(Stroke, 'Color', ...);
end;
end;
例えば古いスタイルRTTIがあるなどのプロパティ、)、:
uses
..., System.Rtti;
var
Componente_cc: TControl;
procedure TfrmPrincipal.AlteraPropriedades;
var
Ctx: TRttiContext;
Prop: TRttiProperty;
Stroke: TObject;
begin
Ctx := TRttiContext.Create;
Prop := Ctx.GetType(Componente_cc.ClassType).GetProperty('Stroke');
if (Prop <> nil) and (Prop.PropertyType.TypeKind = tkClass) {and (Prop.Visibility = mvPublished)} then
begin
Stroke := Prop.GetValue(Componente_cc).AsObject;
if Stroke <> nil then
begin
Prop := Ctx.GetType(Stroke.ClassType).GetProperty('Color');
if (Prop <> nil) {and (Prop.Visibility = mvPublished)} then
Prop.SetValue(Stroke, ...);
end;
end;
end;
はしかし、それはあなたがより高いレベルのOへのアクセス権を持っていたら、直接サブプロパティにだけアクセスすることをお勧めします例えばbject、:
uses
..., TypInfo;
var
Componente_cc: TControl;
procedure TfrmPrincipal.AlteraPropriedades;
var
PropInfo: PPropInfo;
Stroke: TStrokeBrush;
begin
PropInfo := GetPropInfo(Componente_cc, 'Stroke', [tkClass]);
if PropInfo <> nil then
begin
Stroke := GetObjectProp(Componente_cc, PropInfo, TStrokeBrush) as TStrokeBrush;
if Stroke <> nil then
Stroke.Color := ...; // <-- no RTTI needed!
end;
end;
または:
uses
..., System.Rtti;
var
Componente_cc: TControl;
procedure TfrmPrincipal.AlteraPropriedades;
var
Ctx: TRttiContext;
Prop: TRttiProperty;
Stroke: TStrokeBrush;
begin
Ctx := TRttiContext.Create;
Prop := Ctx.GetType(Componente_cc.ClassType).GetProperty('Stroke');
if (Prop <> nil) and (Prop.PropertyType.TypeKind = tkClass) {and (Prop.Visibility = mvPublished)} then
begin
Stroke := Prop.GetValue(Componente_cc).AsObject as TStrokeBrush;
if Stroke <> nil then
Stroke.Color := ...; // <-- no RTTI needed!
end;
end;
こんにちは@Remy、あなたは2010年以来、より堅牢なRTTIがあると言うとき、あなたの第二の例を参照しますか?プロパティに直接アクセスしますか? – Anderson
RTTIを使用しているのは、唯一の解決策だからです。私の問題は、問題のソフトウェアがIDEに似ていて、コントロールが追加され、プロパティが変更されたり、サイズが変更されたりするためです。フォームは実行時にはどのクラスでも構いません。すべてのタイプのコンポーネントを追加するための単一の関数、プロパティを取得する別の関数、プロパティを設定する別の関数を実行しようとしています。そのため、TControl型のオブジェクトを作成しました。クラス、問題はTControlではすべてのプロパティに直接アクセスできないため、RTTIを使用していました。 – Anderson
@Anderson:プロパティに直接アクセスすることはRTTIとはまったく関係がありません。これは通常のオブジェクト指向プログラミングです。 'PPropInfo'の使用は新しいものではなく、常に利用可能です。 'System.TypInfo'ユニットによって実装された古いスタイルのRTTIは、' System.Rtti'ユニットによって実装された拡張RTTI(http://docwiki.embarcadero.com/RADStudio/en/Working_with_RTTI_Index)に置き換えられました。 –