お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"コントロールの複製"






任意のControlの複製を生成する方法を以下に示す。

フォーム、あるいはコンポーネントに以下のComponentsProcとCopyPasteメソッド
を追加する。

CopyPasteメソッドの引数に複製したいControlと複製されたControlの親となる
TWinControlを指定する。

CopyPasteメソッドを実行すると親に指定したTWinControl上に複製Controlが生成
される。

procedure TSomeCompo.ComponentsProc(Component:TComponent);
begin
 //空で良い
end;

procedure TSomeCompo.CopyPaste(Control:TControl;aParent:TWinControl);
var
  MemoryStream:TMemoryStream;
  Writer:TWriter;
  Reader:TReader;
  S:String;
begin
  //Nameの剥奪
  S:= Control.Name
  Control.Name:= '';
  
  //ストリーム化開始(Copy)
  MemoryStream:=TMemoryStream.Create;
  try
    Writer:=TWriter.Create(MemoryStream,4096);
    try
      Writer.RootAncestor := nil;
      Writer.Ancestor := nil;
      Writer.Root := Control.Owner;
      Writer.WriteSignature;
      Writer.WriteComponent(Control);
      Writer.WriteListEnd;
    finally
      Writer.Free;
    end;
    
  //複製開始(Paste)
    MemoryStream.Position:=0;
    Reader:=TReader.Create(MemoryStream,4096);
    try
      Reader.ReadComponents(aParent.Owner,aParent,ComponentsProc);
    finally
      Reader.Free;
    end;
  finally
    MemoryStream.Free;
  
  //Originalコントロールの名前の復帰
    Control.Name:= S;
  end;
end;

この方法の利点は、TStreamのWriteComponentやReadComponentを使うのと違い
複製Control受け入れのためのインスタンスを用意する必要がないということ
である。このため、あらゆる型のControlの複製に柔軟に対応できる。

しかし、この利点は複製されたControlのインスタンスにアクセスする際には
逆に欠点となっていた。ところが最近、Mes10のQ&Aから複製されたControlの
インスタンスを取得するには、Notificationあるいは、CM_ControlChange
メッセージを利用すればよいことが明らかになった。(私にとって (^^; )

つまり、親となるTWinControlに、以下のような細工を加えておくのである。

protected
  procedure CMControlChange(var Message:TCMControlChange);
                                           message CM_CONTROLCHANGE;
public
  ReplicaControl:TControl;
  
  
procedure TSomeParent.CMControlChange(var Message:TCMControlChange);
begin
  inherited;
  if not (csLoading in ComponentState) then
     ReplicaControl:=Message.Control;
end;

こうしておくと、最後にこの親コントロール上で生成された子コントロールの
インスタンスにReplicaControlを使ってアクセスできる。

ただし、CM_ControlChangeは子コントロールが親から除去されたときにも発生
するので、その点に注意する必要がある。



   ζξζ〜     六角〔〕 三房 ‰  Rokkaku Sanbou
   \__/         Let's  Do "U/I" User-Self!! 
     ̄  1997. 11. 8. Saturday, PM 10:02 [Sasaki, K.] @Tukuba

Original document by 六角三房        氏 ID:(CXE02604)


ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum