【问题标题】:How to deep copy a Builder component, such as TPanel, TButton etc如何深度复制 Builder 组件,例如 TPanel、TButton 等
【发布时间】:2012-01-15 01:58:09
【问题描述】:

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

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

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

有人知道我应该怎么做吗?一段sn-p的代码如下:

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

【问题讨论】:

    标签: c++ c++builder


    【解决方案1】:

    大多数 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;
        }
    }
    

    【讨论】:

    • 嗨谢谢你的回答很有意义。但是,在运行此代码时,我收到“找不到类 TPanel”错误?我在某处读到我应该调用 RegisterClass 但这会导致编译错误?我正在使用 Borland C++ Builder 2007。我在尝试使用 InsertComponent 函数时也遇到了错误,除非这是我需要编写的函数?
    • 如果确实找不到TPanel,那么rkConfigComponentPanel.m_pkPanel 也无法在运行时实例化(假设它是在设计时放置在TForm 上的组件)。设计时组件在运行时自动注册,因此可以在 DFM 流式传输期间找到它们。 InsertComponent()TComponent 的一个方法。据推测,由于您最初将this 作为m_pkPanel 的所有者传递,因此CConfigComponentPanelTComponent 的后代。 TComponent.Create() 构造函数在内部调用 AOwner.InsertComponent(Self)
    • 如果您遇到编译器错误,请显示出来。它们意味着您的代码中有错误。
    • 嗨,我的组件是不是 dfm 的类的一部分。我认为这是导致我出现问题的原因。我认为我的设计将不得不改变以解决这个问题,因为它可能告诉我设计最初并不完全正确。我以不打算使用的方式使用 VCL。为了解决这个问题,我使用了指针而不是实例,这样我的复制构造函数就不会被调用,从而避免了对深度复制的需要。感谢大家的帮助,因为我学到了一些新东西。乔
    猜你喜欢
    • 2013-01-18
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    相关资源
    最近更新 更多