2011-01-17 6 views
1

私はVFI(ビジュアルフォーム継承)を使用しており、インスタンス化されたフォームのコンポーネントがフォームクラスまたはフォームスーパークラスに属しているかどうかを確認する必要があります。Delphi - ビジュアルフォーム継承 - コンポーネントベースクラス検出

私はlblCodigoがTFormCodigoとcpPanel/lblStatusに対してローカルであることを検出したいfrmCodigoのいずれの場合において

unit1 

    TFormStatus = class(TForm) 
    cpPanel: TPanel; 
    lblStatus: TLabel; 
    end; 

    unit 2 

    TFormCodigo = class(TFormStatus) 
    lblCodigo: TLabel; 
    end; 

    frmCodigo: TFormCodigo: 

コンポーネントを継承しています。

for i:=0 to Self.ComponentCount-1 do begin   
     if "InheritedComponent" (Self.Components[i]) then ... 
    end; 

RTTIをオブジェクトプロパティに使用すると、このようなことは可能ですが、コンポーネントが可能であるかどうかはわかりません。

ありがとうございました。

+1

を示している本当の問題は、次のとおりです。** **あなたが知りたいのはなぜ?私は、この質問の背後にある問題に対する「適切な」OO解決策があると確信しています。おそらく仮想メソッドです。 –

+0

@UlrichそのOPは、自己検査したいフレームワークのようなコードで動作している可能性があります。しかし、はい、私は疑問の背後にある動機づけを理解することに不思議に思います。 –

+0

@David:投稿されたコードは非常に「具体的」に見えます。 :-) –

答えて

1

私が正しく理解している場合は、TRttiMember.Parentが必要です。たとえば、Rob Loveのarticleを参照してください。 Delphi 2010以降が必要です。

実際これはexcellent series of articlesの一部です。これらの記事では、名前を知らなくてもフィールドやプロパティなどを取得する方法についても説明します。

+0

あなたが言うように、これは素晴らしいアーティチェンです。私はDelphi 2007を使用しています。私は、RTTI whithout出口でコンポーネントにアクセスしようとしました。私は構成ファイルに、 "継承されていない"コンポーネントのいくつかのプロパティの値を書きたいと思っています(DelphiはFRMファイルで行いますが、ローカルコンポーネントには 'object'、継承されたコンポーネントに対しては '継承')。 Delphiはオブジェクトインスペクタでこの継承を検出し、それぞれのクラス継承を持つプロパティのツリーを表示します。 – Vic

+0

Delphiはデバッグ中にLocal Variablesウィンドウでこの継承を検出し、それぞれのクラス継承を持つプロパティのツリーを表示します。 – Vic

0

たぶん

function TFormStatus.IsStatusComponent(AComponent: TComponent): Boolean; 
begin 
    Result := (AComponent = cpPanel) or (AComponent = lblStatus); 
end; 

のような "愚かな" 何かが、すでにあなたのニーズを満たし?

+0

いいえ。実行時に私は祖先フォームの構成要素を知らない。 – Vic

0

TFormCordigoでは、特定のフォームのリソースを読み込むたびに呼び出されるReadStateメソッドをオーバーライドできます。継承された後、ComponentCountには現在の階層のメンバまで作成されたコンポーネントの数が含まれているので、後で別の場所に保存できるコンポーネントの罫線のリストがあります。

次のコードは、このアプローチに

procedure TInhTestForm.Button3Click(Sender: TObject); 
var 
    i: integer; 
begin 
    inherited; 

    Memo1.Lines.Clear; 
    for i:=0 to ComponentCount-1 do 
    begin 
    Memo1.Lines.Add(format('%s inroduced in %s', [Components[i].Name, ComponentParent(i).ClassName])); 
    end; 
end; 

function TInhTestForm.ComponentParent(Index: integer): TClass; 
var 
    i, j: integer; 
begin 
    Result:=Nil; 
    for i:=Low(fComponentBorders) to High(fComponentBorders) do 
    begin 
    if Index <= fComponentBorders[i] - 1 then 
    begin 
     j:=i; 
     Result:=Self.ClassType; 
     while j < High(fComponentBorders) do 
     begin 
     Result:=Result.ClassParent; 
     Inc(j); 
     end; 
     break; 
    end; 
    end; 
end; 

procedure TInhTestForm.ReadState(Reader: TReader); 
begin 
    inherited; 
    SetLength(fComponentBorders, Length(fComponentBorders) + 1); 
    fComponentBorders[High(fComponentBorders)]:=ComponentCount; 
end; 
+0

素晴らしい!それは良いアイデアです! – Vic

+0

私は、フォームの新しいインスタンスを作成し、クラス - 親フォームの新しいインスタンスを作成し、コンポーネントのリストを比較するソリューションを見つけました。これはdefalutプロパティの値を比較するのにも役立ちます。 – Vic

+0

また、TWriterを使ってFRMを動的に書き直そうとしました。良い解決策ですが、私のニーズに非常に複雑です(コンポーネントが継承されているかどうかを検出するだけです) – Vic