Как глубоко копировать компонент Builder, такой как TPanel, TButton и т. Д. - PullRequest
1 голос
/ 07 декабря 2011

Кто-нибудь знает, как глубоко скопировать компонент компоновщика?

У меня сложилось впечатление, что я могу использовать функцию 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 Ответ

4 голосов
/ 08 декабря 2011

Большинство классов VCL не реализуют методы Assign() или AssignTo() вообще.Обычно это делают только невизуальные служебные классы (TStringList, TFont, TGraphic потомки и т. Д.).Единственный способ глубокого копирования компонента, особенно визуального, - это использовать его 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;
    }
}
...