[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 196
  • Last Modified:

Child Controls not Showing in Custom Component

Greetings,

I am attempting to create a custom component that contains several other components.  I have tried deriving from TCustomControl, TWinControl and TCustomPanel.  I have tried using both InsertControl and setting the child's Parent property.  Nomatter what I try, the child controls will not show at either design time or run time.  I have consulted several examples and I do not appear to be doing anythign wrong.

Here is the code for the latest test with a single child control (this is just to see if it will display a scroll bar at least) :-

unit SignalDisplay;

interface

Uses
    Classes, Forms, Graphics, Controls, StdCtrls, ExtCtrls, GDIDisplay;

Type
    TSignalPlotType = (spLine, spBar);

    TSignalDisplay = Class (TCustomPanel)
    Private
             IDisplay : TGDIDisplay;
             IPlotType : TSignalPlotType;
             IScrollBar : TScrollBar;

    Protected

    Public
             Constructor Create (AOwner : TComponent); Virtual;
             Destructor Destroy; Virtual;

    End;

Procedure Register;

implementation

Constructor TSignalDisplay.Create (AOwner : TComponent);
Begin
     Inherited Create (AOwner);
     IScrollBar := TScrollBar.Create (Self);
     InsertControl (IScrollBar);
     With IScrollBar Do
     Begin
          Align := alBottom;
          Visible := True;
     End;
End;

Destructor TSignalDisplay.Destroy;
Begin
     RemoveControl (IScrollBar);
     IScrollBar.Free;
     Inherited Destroy;
End;

Procedure Register;
Begin
     RegisterComponents('Werewolf', [TSignalDisplay]);
End;

end.
0
LordWolfy
Asked:
LordWolfy
1 Solution
 
Slick812Commented:
I do beleive that for any control you will need to set the parent property to have that control be seen


IScrollBar := TScrollBar.Create (Self);
     With IScrollBar Do
     Begin
           Parent := Self; // set the parent
          Align := alBottom;
          Visible := True;
     End;


seems like this would help you
0
 
LordWolfyAuthor Commented:
Greetings,

No joy there.

I had already tried setting parent before (I believe doing that and using InsertControl acomplish the same thing).
But I tried it exactly as you suggested and it still didn't work.
0
 
BlackTigerXCommented:
how about the left and top properties... =o)

Constructor TSignalDisplay.Create (AOwner : TComponent);
Begin
     Inherited Create (AOwner);
     IScrollBar := TScrollBar.Create (Self);
     IScrollBar.Left:=1;
     IScrollBar.Parent:=Self;
     ....
End;
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LordWolfyAuthor Commented:

No that dosent work either.
0
 
BlackTigerXCommented:
and height and width...
0
 
LordWolfyAuthor Commented:
I tried those along with left and top - doesnt work
0
 
LordWolfyAuthor Commented:
Greetings,

I managed to find the problem on my own.  The constructor and destructor should have been followed by Override and not Virtual.
0
 
BlackTigerXCommented:
the problem might be when you are instantiating the control then... are you setting the parent?

procedure TForm1.Button1Click(Sender: TObject);
begin
  with TSignalDisplay.Create(Self) do
  begin
    Parent:=Self;
    Left:=1;
    Top:=1;
    Height:=100;
    Width:=200;
  end
end;
0
 
BlackTigerXCommented:
>>The constructor and destructor should have been followed by Override and not Virtual.

that wasn't the issue in this case, that was a different issue
0
 
LordWolfyAuthor Commented:
If you read throuth the original posts and replies you will see that I covered all points including setting of the parent.

Also the explanation for the override directive being the correct answer is that for some reason delphi insists on calling the default constructor and destructor unless specifically overridden.  Feel free to test this for yourself by implenenting the above code.  Try it with both virtual and override after the constructor and destructor and notice the difference.  Also note that I took out all the changes made in the course of this topic and reverted to the original (as above) before changing the directives to override.
0
 
BlackTigerXCommented:
you tested the parent on the component code, but you were missing the parent when instantiating your TSignalDisplay class

I tested your code and got it working after adding the parent, the virtual is still there and it does work, you can try your self:

the component code:

unit Unit2;

interface

Uses
    Classes, Forms, Graphics, Controls, StdCtrls, ExtCtrls;

Type
    TSignalPlotType = (spLine, spBar);

    TSignalDisplay = Class (TCustomPanel)
    private
      IPlotType : TSignalPlotType;
      IScrollBar : TScrollBar;
      aLabel:TLabel;
    protected
    public
      Constructor Create (AOwner : TComponent); Virtual;
      Destructor Destroy; Virtual;
    End;

Procedure Register;

implementation

Constructor TSignalDisplay.Create (AOwner : TComponent);
Begin
  Inherited Create (AOwner);

  aLabel:=TLabel.Create(Self);
  aLabel.Parent:=Self;
  aLabel.Caption:='hello';
  aLabel.Left:=1;
  aLabel.Top:=1;
  aLabel.Width:=100;
  aLabel.AutoSize:=True;

  IScrollBar := TScrollBar.Create (Self);
  IScrollBar.Parent:=Self;
  IScrollBar.Left:=1;
  IScrollBar.Height:=20;
  IScrollBar.Align:=alBottom;
End;

Destructor TSignalDisplay.Destroy;
Begin
  aLabel.Free;
  IScrollBar.Free;
  Inherited Destroy;
End;

Procedure Register;
Begin
  RegisterComponents('Werewolf', [TSignalDisplay]);
End;

end.
-----------------
the testing unit:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Panel1: TPanel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

  uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  with TSignalDisplay.Create(Self) do
  begin
    Parent:=Self;
    Left:=1;
    Top:=1;
    Height:=100;
    Width:=200;
  end
end;

end.
0
 
LordWolfyAuthor Commented:
Greetings,

Setting of Parent is not needed if using InsertControl since they do the same thing.  My WORKING code does not use the parent property.
0
 
BlackTigerXCommented:
>>My WORKING code does not use the parent property.
again, I'm not talking about the component code, that works fine, the problem was instantiating your component

CetusMOD, you can close the question
0
 
LordWolfyAuthor Commented:

Its a visual component.  It is instantiated by dropping it onto a form fromt eh component palette.  You should be able to see that from the code.
0
 
PAQ_ManCommented:
Question Closed, 200 points refunded.
PAQ_Man
Community Support Moderator
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now