Board index » cppbuilder » How do I copy a VCL instance?

How do I copy a VCL instance?

E.g. to copy Memo1, should I being doing this?

...
  TMemo* mymemo   =  new TMemo(Application);
  mymemo->Align      = Memo1->Align;
  mymemo->OnClick = Memo1->Memo1OnClick;
 ...etc

Robin

ps

mymemo->Assign(Memo1);    // gives the error "cannot assign a TMemo to a
TMemo"

 

Re:How do I copy a VCL instance?


Have a look at the Assign method.

WARNING:  mymemo->Align = Memo1->Align.  This statement means that
mymemo->Align will access the same memory as Memo1->Align.  Unexpected
behaviour may result if you change the Align property of Memo1 and not
realize that it will alter mymemo align property or vice-versa.

Problems will occur if you delete Memo1 and try to access align from mymemo.

Use Assign.

HTH,

Brent

Re:How do I copy a VCL instance?


I tried the Assign method already but it thows EConvertError "cannot convert
TMemo to TMemo" when it executes:-

TMemo* mymemo= new TMemo(Application);
 mymemo->Assign(Memo1);

Could this be because Assign is not over-ridden in TMemo's class so a "TMemo
type Assign" makes no sense because it only knows how to copy TPersistent
type members and not the extra TMemo type members?

Robin (Ancient student) Pain

ps my copy of BCB is V4 build 14.4

Quote
Brent <b.kni...@NOSPAM.mcauley.acu.edu.au> wrote in message

news:3b382a64$1_1@dnews...
Quote
> Have a look at the Assign method.

Re:How do I copy a VCL instance?


Quote
Robin Pain wrote:
> E.g. to copy Memo1, should I being doing this?

> ...
>   TMemo* mymemo   =  new TMemo(Application);
>   mymemo->Align      = Memo1->Align;
>   mymemo->OnClick = Memo1->Memo1OnClick;
>  ...etc
> mymemo->Assign(Memo1);    // gives the error "cannot
> assign a TMemo to a TMemo"

I am wondering why you might need to do this.  Assign, even
if it worked, would not duplicate the assignment of event
handlers.  It seems that putting the TMemo on a TFrame or
even a TForm would be sufficient.  It is possible to do this if it
is *really* necessary...

Re:How do I copy a VCL instance?


Hi Robin,
   For most components, you can punt the work to the VCL streaming
system.  Here's an example...

#include <memory>
TMemo* __fastcall CopyMemo(
    IN TMemo& MemoSrc,
    IN AnsiString NewName
    )
{
   TMemo* MemoDup = NULL;
   const AnsiString SavedName(MemoSrc.Name);
   MemoSrc.Name = "";
   try
   {
      // save the Memo to a stream
      std::auto_ptr<TMemoryStream> ms(new TMemoryStream());
      ms->WriteComponent(&MemoSrc);
      ms->Seek(0, soFromBeginning);

      // register the Memo's class
      TComponentClass classes[1] = {MemoSrc.ClassType()};
      RegisterClasses(classes, 0);

      // read the Memo from stream into a new instance
      MemoDup = new TMemo(MemoSrc.Owner);
      MemoDup->Visible = false;      
      MemoDup->Parent = MemoSrc.Parent;
      ms->ReadComponent(MemoDup);
      MemoDup->Name = NewName;      
   }
   catch (...)
   {
      // restore the original name
      MemoSrc.Name = SavedName;
      throw;
   }
   // restore the original name
   MemoSrc.Name = SavedName;

   // return the copy
   return MemoDup;

Quote
}

void __fastcall TForm1::CopyMemoButtonClick(TObject *Sender)
{
   TMemo* Memo2 = CopyMemo(*Memo1, "Memo2");
   if (Memo2)
   {
      Memo2->SetBounds(
         Memo1->Left, Memo1->Top + Memo1->Height,
         Memo2->Width, Memo2->Height
         );
      Memo2->Show();
   }

Quote
}

Note that this code won't copy the event handlers; you'll have to do
those manually.

Best of luck!
--
Damon C. (TeamB)
- BCBCAQ <http://bcbcaq.freeservers.com>
- Graphics API Black Book <http://graphicsBB.itgo.com>

Re:How do I copy a VCL instance?


Wow! Awesome, this is what Java's serializable must be? Thanks very much
Damon, I had no idea this existed... TMemoryStream... "IN"... this terrific
example is very helpful. Thanks very much, if any other newcommers are
reading this, ya just gotta get into containers!

Robin

Damon Chandler (TeamB) <dm...@cornell.edu> wrote in message
news:3B396454.E3A84957@cornell.edu...

Quote
> Hi Robin,
>    For most components, you can punt the work to the VCL streaming
> system.  Here's an example...

> #include <memory>
> TMemo* __fastcall CopyMemo(
>     IN TMemo& MemoSrc,
>     IN AnsiString NewName
>     )
> {
>    TMemo* MemoDup = NULL;
>    const AnsiString SavedName(MemoSrc.Name);
>    MemoSrc.Name = "";
>    try
>    {
>       // save the Memo to a stream
>       std::auto_ptr<TMemoryStream> ms(new TMemoryStream());
>       ms->WriteComponent(&MemoSrc);
>       ms->Seek(0, soFromBeginning);

>       // register the Memo's class
>       TComponentClass classes[1] = {MemoSrc.ClassType()};
>       RegisterClasses(classes, 0);

>       // read the Memo from stream into a new instance
>       MemoDup = new TMemo(MemoSrc.Owner);
>       MemoDup->Visible = false;
>       MemoDup->Parent = MemoSrc.Parent;
>       ms->ReadComponent(MemoDup);
>       MemoDup->Name = NewName;
>    }
>    catch (...)
>    {
>       // restore the original name
>       MemoSrc.Name = SavedName;
>       throw;
>    }
>    // restore the original name
>    MemoSrc.Name = SavedName;

>    // return the copy
>    return MemoDup;
> }

> void __fastcall TForm1::CopyMemoButtonClick(TObject *Sender)
> {
>    TMemo* Memo2 = CopyMemo(*Memo1, "Memo2");
>    if (Memo2)
>    {
>       Memo2->SetBounds(
>          Memo1->Left, Memo1->Top + Memo1->Height,
>          Memo2->Width, Memo2->Height
>          );
>       Memo2->Show();
>    }
> }

> Note that this code won't copy the event handlers; you'll have to do
> those manually.

> Best of luck!
> --
> Damon C. (TeamB)
> - BCBCAQ <http://bcbcaq.freeservers.com>
> - Graphics API Black Book <http://graphicsBB.itgo.com>

Other Threads