0
votes

//I do not know how to ask the question better...//

I registred new class of my own (TDisplay). Inside of this class is one object (TRectangle - also of my own), which is created in the constructor of TCustomDisplay - predecestor of TDisplay.

When I put TDisplay on the form, I can edit all published properties of both my objects (TDisplay, TRectangle) as usual, but only TDisplay is set up according to the object inspector. TRectangle remains in its default values (left 0, Top 0 right 30, bottom 20), in spite of it, that these properties are set to left 0, Top 0 right 100, bottom 100.

What should I check to make it run correctly?

thanx

P.S When the properties defined in object inspector are actually loaded into an object?

Here is the sample code ("short one"). It is not "clean" so please, be tolerant...

TRectangle = class(TComponent)
  private
    FOnAdjustContent: TNotifyEvent;
    FLeft, FRight, FBottom, FTop:Integer;
    FoutLeft, FoutRight, FoutBottom, FoutTop:integer;
    FinLeft, FinRight, FinBottom, FinTop:integer;
    FAligning:TAligning;
    FAdjustContent:TAdjustContent;
    FAnchors:TAnchors;
    FList:Tlist;
    FRectangleContainer:TRectangleContainer;
    FParentRectangle:TRectangle;
    FdLeft, FdTop, FdBottom, FdRight: integer;
 //   function FindParent(AName:string):TRectangle;


  public    
    constructor Create(AOwner:TComponent);override;
    destructor Destroy; override;
    procedure Assign(Source : TPersistent); override;
  published
    property AdjustContent:TAdjustContent read FAdjustContent write SetAdjustContent;
    property Aligning:TAligning read FAligning write SetAlign;
    property Anchors:TAnchors read FAnchors write SetAnchors;
    .
    .
    .   
  end; 



TTextObject = class (TRectangle)
  public
      procedure   Assign(Source : TPersistent); override;
  published
      property AlignmentInCell:integer read FAlignmentInCell write FAlignmentInCell;
      property Brush:TBrush read FBrush write FBrush;
      property CanMove:Boolean read FCanMove write FCanmove;
      .
      .
      .
  end;





TCustomDisplay = class (TCustomControl)
  private
     FRootTextObject:TTextObject;
     procedure SetRootTextObject(Value:TTextObject);
  protected
  public
     constructor Create(AOwner:TComponent); override;
     destructor  Destroy; override;
     procedure Assign(Source:TPersistent); override;
  published
     property RootTextObject:TTextObject read FRootTextObject write SetRootTextObject;
  end;



  TDesignDisplay = class (TCustomDisplay)
    protected
     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
     procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    public
     procedure Paint; override; 
    end;

  TDisplay = class (TCustomDisplay)
     private

        function  GetFirstMovable: TTextObject;
     protected
        procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
        procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
        procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
     public
        procedure Paint; override;
     end;


procedure Register;
begin
  RegisterComponents('My Palette', [TDisplay, TDesignDisplay]);
end;



constructor TCustomDisplay.Create(AOwner:TComponent);
  var i:integer;
  begin
  inherited;

  FRootTextObject:=TTextObject.Create(Self);
//  ShowMessage(FRootTextObject.Name);
//  FRootTextObject.Name:='Root';
  FRootTextObject.OnAdjustContent:=DoAdjustContent;

//  FRootTextObject.Right:=Width;
//  FRootTextObject.Bottom:=Height;
  FRootTextObject.CanMove:=False;
  TabStop:=True;
  end;



procedure TCustomDisplay.SetRootTextObject(Value:TTextObject);
begin
  FRootTextObject.Assign(Value);
end;




procedure TRectangle.Assign(Source: TPersistent);
var ARectangle:TRectangle;
begin
  if Source is TRectangle then
    begin
   ARectangle:=Source as TRectangle;

 //  Name:=ARectangle.Name;
  // FRect:=Rectangle.Rect;
   FLeft:=ARectangle.Left;
   FTop:=ARectangle.Top;
   FRight:=ARectangle.Right;
   FBottom:=ARectangle.Bottom;
   FoutLeft:=ARectangle.outLeft;
   FoutTop:=ARectangle.outTop;
   FoutRight:=ARectangle.outRight;
   FoutBottom:=ARectangle.outBottom;
   FinLeft:=ARectangle.inLeft;
   FinTop:=ARectangle.inTop;
   FinRight:=ARectangle.inRight;
   FinBottom:=ARectangle.inBottom;
   end
   else
    inherited;
end;



procedure TTextObject.Assign(Source : TPersistent);
var ATextObject:TTextObject;
begin
      inherited;
      if Source is TTextObject then
        begin
        ATextObject:=Source as TTextObject;

        AlignmentInCell:=ATextObject.AlignmentInCell;
        AttachedWP:=ATextObject.AttachedWP;
        Brush.Assign(ATextObject.Brush);
        Caption:=ATextObject.Caption;
        Font.Assign(ATextObject.Font);
        Painting.Assign(ATextObject.Painting);
        Pen.Assign(ATextObject.Pen);
        RichString:=ATextObject.RichString;
        StateDrawing:=ATextObject.StateDrawing;
        TabState:=ATextObject.TabState;
        TextFormat:=ATextObject.TextFormat;
        Thickness:=ATextObject.Thickness;
        Transparent:=ATextObject.Transparent;
        Value:=ATextObject.Value;
        WPname:=ATextObject.WPname;
        end;         
end;
1

1 Answers

7
votes

Make sure TRectangle is derived from TPersistent class or one of its descendant classes. Also make sure you implemented Assign method for TRectangle, and all the published properties of TRectangle are assigned inside Assign method.

NOTE: If your class is derived from TComponent, and is used as a child component inside another component, you should call SetSubComponent(True) when the object is created.

The code should look something like this:

Interface section:

  type    
    TRectangle = class(TComponent)
      private
        FTop,
        FBottom,
        FLeft,
        FRight   : Integer;
      public
        procedure Assign(Source: TPersistent); override;
      published
        property Bottom: Integer read FBottom write FBottom;
        property Left: Integer read FLeft write FLeft;
        property Right: Integer read FRight write FRight;
        property Top: Integer read FTop write FTop;
      end;

      TDisplay = class(TComponent)
      private
        FRectangle : TRectangle;
        procedure SetRectangle(Value: TRectangle);
      public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
      published
        property Rectangle: TRectangle read FRectangle write SetRectangle;
      end;

Implementation section:

{ TRectangle }

procedure TRectangle.Assign(Source: TPersistent);
begin
  if Source is TRectangle then
  begin
    FBottom := TRectangle(Source).Bottom;
    FLeft := TRectangle(Source).Left;
    FRight := TRectangle(Source).Right;
    FTop := TRectangle(Source).Top;
  end
  else
    inherited;
end;

{ TDisplay }

constructor TDisplay.Create(AOwner: TComponent);
begin
  inherited;
  FRectangle := TRectangle.Create(Self);
  FRectangle.Parent := Self;
  FRectangle.SetSubComponent(True);
end;

destructor TDisplay.Destroy;
begin
  inherited;
end;

procedure TDisplay.SetRectangle(Value: TRectangle);
begin
  FRectangle.Assign(Value);
end;