Wow... kakave je razlika kad pisem u dva poslepodne i u dva ujutro :)
Gde smo ono stali. Ovako... kada kreiramo komponentu treba da znamo u napred sta ona sve treba da radi. Nas digitalni sat kao sto smo vec rekli treba samo da ispisuje trenutno vreme. Znaci potpuno isto kao kad bi na formu postavili jedan label i jedan timer i za OnTimer napisemo
Code:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Label1.Caption := TimeToStr(Time);
end;
I to je to. Nasa komponenta ce to da radi sama od sebe. Vrlo nam je bitno da korisnik ne moze da menja Caption, zar ne? Zbog toga nasa klasa nasledjuje klasu TCustomLabel. Sve klase u Delphi-u koje pocinj sa TCustom...(Label, List, ComboBox...) su iste kao i klase bez Custom samo sto sakrivaju vecinu property-a. Tako i TCustomLabel sakriva svasta i izmedju ostalog i property Caption. Da napomenem-kada neka klasa nasledjuje drugu ne moze da sakrije published property-e (one koje se vide u Object Inspector-u) i cato nam je bitno da klasa koju nalsedjujemo nema published Caption. Ala sam se raspricao ni oko cega :) Da krenemo dalje. Dakle nasa komponenta treba da prikaze sve property-e kao i TLabel osim Caption-a i to cemo sad da uradimo
Code:
type
TESDigitalClock = class(TCustomLabel)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
published
{ Published declarations }
property Align;
property Alignment;
property Anchors;
property AutoSize;
property BiDiMode;
property Color nodefault;
property Constraints;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property FocusControl;
property Font;
property ParentBiDiMode;
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowAccelChar;
property ShowHint;
property Transparent;
property Layout;
property Visible;
property WordWrap;
property OnClick;
property OnContextPopup;
property OnDblClick;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnMouseEnter;
property OnMouseLeave;
property OnStartDock;
property OnStartDrag;
end;
Kada hocemo da promenimo vidljivost (private, protected, public, published) nekog property-a dovoljno je samo da napisemo property ImeProperty i to postavimo u odgovarajuci blok. Tako smo mi sad stavili sve ove property-e u published blok i sada kad kompajliramo nasu kontrolu i postavimo je na formu ponasace se potpuno isto kao TLabel, ali bez Caption-a.
Sada nam ostaje da jos nateramo komponentu da ispisuje vreme :) Videli smo kako to mozemo da uradimo sa obicnim TLabel-om i TTimer-om. I ovde cemo uraditi nesto slicno. Dodacemo novu promenljivu u nasoj klasi tipa TTimer (morate ubaciti u uses i ExtCtrls).
Code:
TESDigitalClock = class(TCustomLabel)
private
{ Private declarations }
FTimer: TTimer;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
{ Published declarations }
.
.
.
end;
Primecujete da smo dodali i konstuktor i destruktor. To nam je potrebno da prilikom kreiranja nase kontrole mozemo da kreiramo i FTimer, a prilikom brisanja nase kontrole iz memorije da izbrisemo i FTimer (ovaj korak u ovom slucaju nije potreban, ali nece smetati ako i njega uradimo).
Code:
constructor TESDigitalClock.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FTimer := TTimer.Create(Self);
end;
destructor TESDigitalClock.Destroy;
begin
FTimer.Free;
inherited;
end;
Ko nije radio sa klasama i nasledjivanjem, inherited poziva funkciju iz klase od koje smo nasledili funkcije i sve ostalu (u nasem slucaju TCustomLabel). Kada se menjaju virtualne funkcije uglavnom uvek treba pozvati i inherited ImeFunkcije.
Tako... sada nam treba jos samo jedan korak... da podesimo sta ce FTimer da radi na OnTimer event. Dodacemo jos samo jednu proceduricu i nasa klasa ce raditi.
Code:
TESDigitalClock = class(TCustomLabel)
private
{ Private declarations }
FTimer: TTimer;
procedure UpdateCaption(Sender: TObject);
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
.
.
.
end;
procedure TESDigitalClock.UpdateCaption(Sender: TObject);
begin
Caption := TimeToStr(Time);
end;
constructor TESDigitalClock.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
UpdateCaption(Self)
FTimer := TTimer.Create(Self);
FTimer.OnTimer := UpdateCaption;
end;
Sada jos samo ostaje da kompajliramo komponentu i da je ubacimo na formu. Prikazivace se vreme i u design time i u run time.
Sledeci put cemo dodati nove property-e (za kontrolu da li da se vreme updatuje, koliko cesto da se updatuje, za uzimanje trenutnog vremena u String i TDateTime formatu, OnUpdate event tako da znamo kada je Caption promenjen i naravno jednu lepu slicicu za Component Palette).
Imate i gotov kod ako vas mrzi da kuckate.
Srecna vam nova godina. Lepo se provedite :)
P.S.
Hvala -zombie- :)
Uvek zaboravim da spomenem nesto... hvala sto si me podsetio :)
[Ovu poruku je menjao Srki_82 dana 04.01.2005. u 23:34 GMT+1]