Solved

Add OnCreate to TCustomPanel

Posted on 2002-05-13
10
478 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
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
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

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

746 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

11 Experts available now in Live!

Get 1:1 Help Now