如何深度复制Builder组件,如TPanel,TButton等

时间:2011-12-07 14:54:30

标签: c++ c++builder

有人知道如何深度复制构建器组件吗?

我的印象是我可以使用Assign函数,因为它们没有可用的复制构造函数?

我正在使用Assign,但它不喜欢它的TPanel(适用于Graphics :: TBitmap)。我得到的错误是“无法将TPanel分配给TPanel”?

有人有任何想法我应该这样做吗?一段代码如下:

CConfigComponentPanel::CConfigComponentPanel( const CConfigComponentPanel& rkConfigComponentPanel ):
CConfigComponent( rkConfigComponentPanel ),
m_pkPanel( new TPanel(this) )
{
    m_pkPanel->Assign( rkConfigComponentPanel.m_pkPanel );
}

1 个答案:

答案 0 :(得分:4)

大多数VCL类根本不实现Assign()AssignTo()方法。通常,只有非可视实用程序类才会执行(TStringListTFontTGraphic后代等。深度复制组件(尤其是可视组件)的唯一方法是使用其RTTI循环其属性,将其值从一个组件实例一次一个地复制到另一个组件实例,如果存在子控件,则递归复制。为了帮助您,使用TStream::WriteComponent()TStream::ReadComponent()方法将组件及其子组件保存到临时内存中DFM并从中读回。这样,RTL就可以为您处理RTTI访问。例如:

CConfigComponentPanel::CConfigComponentPanel( const CConfigComponentPanel& rkConfigComponentPanel )
    : CConfigComponent( rkConfigComponentPanel ), m_pkPanel( new TPanel(this) ) 
{ 
    TMemoryStream *Strm = new TMemoryStream;
    try
    {
        Strm->WriteComponent( rkConfigComponentPanel.m_pkPanel );
        Strm->Position = 0;
        Strm->ReadComponent( m_pkPanel );
    }
    __finally
    {
        delete Strm;
    }
} 

或者:

CConfigComponentPanel::CConfigComponentPanel( const CConfigComponentPanel& rkConfigComponentPanel )
    : CConfigComponent( rkConfigComponentPanel ), m_pkPanel( NULL ) 
{ 
    TMemoryStream *Strm = new TMemoryStream;
    try
    {
        Strm->WriteComponent( rkConfigComponentPanel.m_pkPanel );
        Strm->Position = 0;
        m_pkPanel = (TPanel*) Strm->ReadComponent( NULL );
        InsertComponent( m_pkPanel );
    }
    __finally
    {
        delete Strm;
    }
}