動的生成したコンポーネントに親を設定するには?

解決


asdf  2013-04-06 17:39:21  No: 44212  IP: 192.*.*.*

動的にコンポーネントを追加する関数を作成したいと考えています。引数にコンポーネントを持持たせて自由にコンポーネントを作成したいのですが、コンポーネントの親を設定しようとすると
「コンポーネント間の循環依存関係は作成できません」
というエラーが起きてしまいました。

○記述コード
procedure TForm1.AddC(c: TComponentClass);
begin
  with c.Create(Self) do begin
    Parent  := TabControl1;  //親コンポーネントを指定
  end;
end;

procedure TForm1.(関数);
begin
  AddC(TButton);
end;

しかし今回の関数とは関係なく、コンポーネントを直接指定すると親は設定できました。
with TButton.Create(Self) do begin
    Parent  := TabControl1;
end;

何故このような違いが起きるのかが分かりません。
どのようにしたら関数が作成できるか教えて頂けないでしょうか?

編集 削除
KHE00221  2013-04-06 20:16:23  No: 44213  IP: 192.*.*.*

TComponentClass に  Parent がないので

procedure TForm1.AddC(c: TComponentClass);
begin
  with c.Create(Self) do begin
    Parent  := TabControl1;  //親コンポーネントを指定
  end;
end;

のParent は Form1.Parent を指している

編集 削除
助監督  2013-04-06 21:21:47  No: 44214  IP: 192.*.*.*

すでにKHE00221さんから回答がありますが、一応。

>何故このような違いが起きるのか
TComponentClass.Create(Self)で作成されるオブジェクトは、TComponentとして扱われます。
そしてParentはTControlのプロパティです。
しかし継承順は TObject→TPersistent→TComponent→TControl ですので…
TComponent.Parentはありません。 

よってコンパイラはParentを with文で指定された c.Create(Self) の要素とは扱えず、
次に Self.Parent として解釈を試みます。
結果として Form1.Parent := TabControl1; となり、循環してしまいます。


>どのようにしたら関数が作成できるか
TComponentClass から TControlClass に変えればOKかと。

procedure TForm1.AddC(c: TControlClass);
begin
  with c.Create(Self) do begin
    Parent := TabControl1;  //親コンポーネントを指定
  end;
end;

編集 削除
asdf  2013-04-06 22:15:18  No: 44215  IP: 192.*.*.*

KHE00221様、助監督様、教えて頂きありがとうございました。無事解決できました。
どうして私の書いたコードで上手く行かなかったのかも理解できました。クラスの継承順を気にする必要があったのですね。
また不明な点があるときには質問させて頂きます。ありがとうございました。

編集 削除