t e m p o r a l 
 d o o r w a y 

A Basic Streamable Aggregate

 

This is a somewhat more complex aggregate component, which streams its internal component. This is most suitable for situations where you use a component editor to alter the properties of the internal subcomponents, without exposing them to the object inspector. This is a descendant of the most basic aggregate example.

.h

//---------------------------------------------------------------------------

#ifndef StreamableAggregatePanelH
#define StreamableAggregatePanelH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include "AggregatePanel.h"
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class PACKAGE TStreamableAggregatePanel : public TAggregatePanel
{
   /*
      This component class is a descendant of TAggregatePanel. The children are
      created each time, and their characteristics are streamed when saved
      at design time. Prior to the children being streamed in, the constructor
      children are deleted and the streamed instances replace them.

      The children can only be changed by editing the .dfm, or by having the
      aggregate component surface published properties that change the values
      of child component properties.

      The children are both owned and parented by this component.
   */

   private:

   protected:

      // These functions override those supplied by TComponent to interface with
      // streaming.

      DYNAMIC void __fastcall GetChildren(Classes::TGetChildProc Proc, Classes::TComponent* Root);
      DYNAMIC TComponent* __fastcall GetChildOwner(void);
      void __fastcall ReadState(Classes::TReader* Reader);
      void __fastcall Loaded(void);

   public:

      __fastcall TStreamableAggregatePanel(TComponent* Owner);

   __published:
};
//---------------------------------------------------------------------------
#endif

.cpp

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "StreamableAggregatePanel.h"
#pragma link "AggregatePanel"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(TStreamableAggregatePanel *)
{
   new TStreamableAggregatePanel(NULL);
}
//---------------------------------------------------------------------------
__fastcall TStreamableAggregatePanel::TStreamableAggregatePanel(TComponent* Owner)
   : TAggregatePanel(Owner)
{
   myChildButton->Name = "ChildButton"; // Make sure the component has a name, so it can be referenced later
}
//---------------------------------------------------------------------------
void __fastcall TStreamableAggregatePanel::GetChildren(Classes::TGetChildProc Proc, Classes::TComponent* Root)
{
   // Stream this component child controls...

   for (int Index = 0; Index < ControlCount; Index++)
   {
      Proc(Controls[Index]);
   };
}
//---------------------------------------------------------------------------
TComponent* __fastcall TStreamableAggregatePanel::GetChildOwner(void)
{
   return this; // This component is the owner of all its children
}
//---------------------------------------------------------------------------
void __fastcall TStreamableAggregatePanel::ReadState(Classes::TReader* Reader)
{
   DestroyComponents(); // Get rid of constructor created components since we are streaming them in; this deletes the owned components

   TComponentClass StreamUsedClasses[1] =
   {
      __classid(TButton)
   };

   RegisterClasses(StreamUsedClasses,0); // Index is high position not count
   TAggregatePanel::ReadState(Reader);
}
//---------------------------------------------------------------------------
void __fastcall TStreamableAggregatePanel::Loaded(void)
{
   for (int Index = 0; Index < ControlCount; Index++)
   {
      if (Controls[Index]->Name == "ChildButton") myChildButton = (TButton *) Controls[Index];
   };

   // Reassign any event handlers used internally if no handler set by the user

   if (myChildButton->OnClick == NULL) myChildButton->OnClick = ClickChildButton;
}
//---------------------------------------------------------------------------
namespace Streamableaggregatepanel
{
   void __fastcall PACKAGE Register()
   {
      TComponentClass classes[1] = {__classid(TStreamableAggregatePanel)};
      RegisterComponents("MSC Test", classes, 0);
   }
}
//---------------------------------------------------------------------------


Copyright © 2004 by Mark Cashman (unless otherwise indicated), All Rights Reserved