Solved

Add OnCreate to TCustomPanel

Posted on 2002-05-13
10
481 Views
Last Modified: 2010-04-04
Hi,

i noticed that tpanel has no oncreate event and thougth that it would be great if i had an oncreate event with TPanel so i wrote one, but it won't work. please tell me what is wrong?

unit PanelTest;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, ExtCtrls;

type
  TPanelTest = class(TPanel)
  private
    { Private declarations }
    FOnCreate: TNotifyEvent;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
  published
    { Published declarations }
    property OnCreate: TNotifyEvent read FOnCreate write FOnCreate;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('XNet', [TPanelTest]);
end;

{ TPanelTest }

constructor TPanelTest.Create(AOwner: TComponent);
begin
  inherited;
  if Assigned(FOnCreate) then
    OnCreate(Self);
end;

end.
0
Comment
Question by:rtieland
  • 6
  • 3
10 Comments
 
LVL 7

Expert Comment

by:God_Ares
ID: 7005705
logical..

procedure x(...);
begin
 ...
end;

var a:Tmypanel

begin
  a := tmypanel.create(self);
  a.onCreate := x;
end;

the procedure is simpely not yet bound the the component. So FonCreate will be nil.


it will be probaply wetter if yoyu override the paint method and use a new variable.

procedure paint
begin
  inherited;
  if firsttime then
  Begin
    if assigned(oncreate) then oncreate(self);
    firsttime := 1=0;
  end;
end;
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 7005718
procedure paint
begin
 if firsttime then
 Begin
   if assigned(oncreate) then oncreate(self);
   firsttime := 1=0;
 end;
 inherited;
end;

better do this. or else onpaint comes before oncreate.
0
 
LVL 1

Author Comment

by:rtieland
ID: 7005899
God_Ares i think you do not fully understand my problem (probably because of my bad english)

if i register the component in the IDE and put the component on a form and create a procedure in the object inspectors event tab with the property OnCreate. then when i run the project the value of FOnCreate is nil and it should be set to the procedure wich i assigned to it with the Object Inspector.

here is the form (unit and dfm) using the component:

Unit:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    PanelTest1: TPanelTest;
    procedure PanelTest1Create(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.PanelTest1Create(Sender: TObject);
begin
  PanelTest1.Caption := 'Hi';
end;

end.

DFM:

object Form1: TForm1
  Left = 192
  Top = 107
  Width = 696
  Height = 480
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object PanelTest1: TPanelTest
    Left = 144
    Top = 80
    Width = 185
    Height = 41
    Caption = 'PanelTest1'
    TabOrder = 0
    OnCreate = PanelTest1Create
  end
end
0
 
LVL 8

Expert Comment

by:TOndrej
ID: 7005949
Of course FOnCreate will always be nil in the constructor.

When the components are streamed from the .dfm they are created first (you need an instance to work with ;-), then assigned properties from the stream (this is a very simplified description).

If you look at what TForm or TDataModule do: they call OnCreate from their overriden AfterConstruction method.

HTH
TOndrej
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 7006024
yeah i understood

your component will be created then the on??? will be bound. so when creating oncreate equals nil. therefore

 if Assigned(FOnCreate) then
   OnCreate(Self);

will fail.


0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 7

Expert Comment

by:God_Ares
ID: 7006060
AfterConstruction is not an option onCreate is still nil
0
 
LVL 8

Accepted Solution

by:
TOndrej earned 50 total points
ID: 7006150
Right. Thanks for correcting me, God_Ares.
The difference is that data modules and forms are root components for streaming.

For non-root components like TCustomPanel descendants, I suggest you override Loaded method (which is called after the component has been created and loaded from the stream).

Something like this:

type
  TCustomTestPanel = class(TCustomPanel)
  private
    FOnCreate: TNotifyEvent;
  protected
    procedure DoCreate; virtual;
    procedure Loaded; override;

    property OnCreate: TNotifyEvent read FOnCreate write FOnCreate;
  end;

procedure TCustomTestPanel.DoCreate;
begin
  if Assigned(FOnCreate) then
    FOnCreate(Self);
end;

procedure TCustomTestPanel.Loaded;
begin
  inherited Loaded;
  DoCreate;
end;

HTH
TOndrej
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 7006174
yep that's it.
0
 
LVL 7

Expert Comment

by:God_Ares
ID: 7006217
so what are root and non-root components?

root = Tcustom form may hold other components but can't be owned by other components?
0
 
LVL 8

Expert Comment

by:TOndrej
ID: 7006307
Root components are those which are used as Root for streaming (have a look at TReader.Root).
Each .dfm resource has one Root.
Root is created from the stream, creating and initializing the child components, and then fixup is done (for class reference properties).
Most typically, Root is also Owner of all components; but in some cases a non-root component may also own its subcomponents.

> may hold other components but can't be owned by other
> components?

At design time and for streaming purposes, correct.
Root is the top level and cannot be owned by another component.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…
Hi friends,  in this video  I'll show you how new windows 10 user can learn the using of windows 10. Thank you.

912 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now