Ylös Edellinen Seuraava Otsikkosivu Hakemisto Sisällys

1. Omien komponenttien tekeminen

Luvun pääaiheet:

Lopuksi vielä pikainen katsaus omien komponenttien tekemiseen.

1.1 Miksi omia komponentteja

Visual Basicin vahvin puoli on erittäin helppo valmiiden komponenttien käyttäminen. Tämä ominaisuus on myös Delphissä. Visual Basicissa omien komponenttien tekeminen on todella työlästä ja vaatii Windowsin perus-API -ohjelmointia.

Delphissä omien komponenttien tekeminen on "lähes" samanlaista kuin Object Pascalin luokkien tekeminen ja voidaan siis tehdä ja testata Delphillä.

Hyvin tehtyjen ja testattujen komponenttien avulla ohjelmointi on helppoa ja koodin kirjoittamisen tarve vähenee radikaalisti. Oikeastaan aina kun tekee uuden luokan, kannattaa miettiä olisiko siitä uudelleen käytettäväksi komponentiksi.

1.2 Yksinkertainen TLaskuri

Seuraavassa tehdään ensin yksinkertaistettu autolaskuriin kelpaavasta komponentista.

	Kirjoittamisvinkki Delphi 4.0:
	    1) Lisää ensin rivi:  property Count : integer;
	    2) Paina Shift+Ctrl+C  (Complete Class at Cursor)
	    3) Täydennä syntynyt SetCount -metodi.
	    4) Kirjoita rivi: constructor Create(...
	    5) Paina Shift+Ctrl+C
	    6) Täydennä Create-metodi
	    7) Täydennä puuttuvat virtual -määritykset

	unit laskuri;
	
	interface
	
	uses SysUtils, Classes, Controls, Graphics,  StdCtrls;
	
	type
	  TLaskuri = class(TLabel)
	  private
	    FCount : integer;{ Ominaisuuksien attribuutit nimetään yleensä F-alkuisiksi}
	  protected
	    procedure SetCount(const Value: integer);  virtual;
	  public
	    constructor Create(AOwner:TComponent); override;
	    function Inc(i:integer) : integer;     virtual;
	  published  { Published declarations } { Yleensä vain ominaisuudet.           }
	    { Ominaisuuksiin ilmoitetaan miten niitä luetaan ja miten asetetetaan sekä }
	    { mahdollinen oletusarvo. Oletusarvo on ainoastaan ohje siitä, ettei       }
	    { arvoa talleteta resurssitiedostoon, jos arvo on sama kuin oletus.        }
	    { Luku/kirjoitusohje voi olla saman tyyppisen attribuutin nimi tai         }
	    { aliohjelma asettamiseen ja funktio lukemiseen                            }
	    property Count:integer read FCount write SetCount default 0;
	end;
	
	procedure Register;
	
	implementation
	
	
	constructor TLaskuri.Create(AOwner:TComponent);
	begin
	  inherited Create(AOwner);            { Muista tämä!!! Muuten käy huonosti!!!}
	  Count := 0;
	end;
	
	
	procedure TLaskuri.SetCount(const Value: integer);
	begin
	  FCount := Value;
	  inherited Caption := IntToStr(Count)+' '; { Välilyönti lop. on paremman näk. }
	end;
	
	
	function TLaskuri.Inc(i:integer) : integer;
	begin
	  Count := Count + i;
	  Result := Count;
	end;
	
	
	procedure Register;
	{ Komponentit pitää rekisteröidä komponenttisivulle }
	begin
	  RegisterComponents('Samples', [TLaskuri]);
	end;
	
	end.

1.3 Väärinkäytön poistaminen:

Komponentissamme on vielä pieni vika: voidaan tehdä esimerkiksi sijoitus:

	  lask.Caption := 10;

ja kun tämän jälkeen lisätään laskurin arvoa, ei seuraava arvo olekaan 11, vaan yksi suurempi kuin FCount-attribuuttiin on jäänyt edelliseltä kerralta.

Miten vika voidaan poistaa? Suositeltavin vaihtoehto olisikin periä luokka TCustomLabel. Ero TLabel-luokkaan on siinä, että TCustomLabelissa on kaikki samat ominaisuudet kuin TLabelissa, mutta protected-osassa, eli niitä ei voi ulkopuolinen käyttää. Tällöin em. sijoitus ei olisi mahdollista. Kuitenkin moni muukin TLabelin kiva ominaisuus jäisi suojatuksi. Ominaisuuksia voidaan siirtää kyllä julkaistulle puolelle kirjoittamalla:

	published  // ks mallia TLabel-komponentin lähdekoodista StdCtrl.pas
	    property Align;
	    property Alignment;
	    property Anchors;
	    property AutoSize;
	    property BiDiMode;
	//    property Caption;  // Tätä ei julkaista
	    property Color;
	. . .

Yleensä kaikista komponenteista on ensin TCustom... -versio joka on tarkoitettu perittäväksi.

Toinen mahdollisuus on tehdä uusi Caption-ominaisuus, joka korvaa TLabelin Caption-ominaisuuden:

Lisää

	published 
	. . .
	  property Caption:string read GetCaption write SetCaption stored false;

ja tee vastaavat metodit (käytä luokkatäydennintä):

	function TLaskuri.GetCaption: string;
	begin
	  Result := Trim(inherited Caption); { Varo rekursiota!!! }
	end;
	
	procedure TLaskuri.SetCaption(const Value: string);
	begin
	  Count := StrToIntDef(Trim(Value),0);
	end;

Huomaa inherited avainsanan käyttö edeltäjäluokan ominaisuuden käyttämiseksi.

1.4 Oletusarvojen muuttaminen

Jos haluamme laskurimme tulevan valmiiksi isommalla fontilla oikeaan reunaan, voimme tehdä vielä pieniä parannuksia:

Lisää valmiiden ominaisuuksien uudet oletusarvot:

	 published
	. . .
	    property Alignment        default taRightJustify;
	    property AutoSize         default False;
	    property Color            default clAqua;
	    property ParentColor      default false;
	

Tämä on vasta tieto siitä, että jos ominaisuuden arvo sattuu olemaan sama kuin oletus, niin arvoa ei tarvitse tilan säästämisen vuoksi tallettaa lomakkeelle. Varsinainen arvon asetus pitää tehdä itse:

	constructor TLaskuri.Create(AOwner:TComponent);
	begin
	  inherited Create(AOwner);            { Muista tämä!!! Muuten käy huonosti!!!}
	  Count := 0;                          { Defaulteissa luvatut arvot:          }
	  Alignment := taRightJustify;
	  Color := clAqua;
	  ParentColor := False;
	  Font.Height := -32;
	  Font.Style := [fsBold];
	  AutoSize := False;
	end;

1.5 Komponentin ikonin piirtäminen

Jotta komponentti olisi tunnistettavissa työkalupalkissa, sille kannattaa piirtää ikoni:

1.6 Komponentin lisääminen komponenttikirjastoon

Komponentti voidaan lisätä kirjastoon seuraavasti (Delphi 3.0-):

Tehtävä 1.1 Uusi uljas autolaskuri

Tee uusi Autolaskuri-ohjelma ja käytä siinä Laskuri-komponentteja.

Tehtävä 1.2 TLisaaButton

Tee uusi komponentti TLisaaButton, jolla on
ominaisuutena
Laskuri : TLaskuri - laskuri, jonka arvoa lisätään aina
kun nappia painetaan
Lisays : Integer - paljollako laskuria lisätään

Tehtävä 1.3 Autolaskuri vähällä koodaamisella

Tee autolaskuri em. komponenteilla niin, että tarvitsee kirjoittaa vain yksi rivi koodia: Nollaa-nappulalle

Tehtävä 1.4 TNollaa

Tee vielä komponentti TNollaa, joka nollaa kaikki samalla lomakkeella olevat laskurit (ks. ComponentCount ja Components).

Tehtävä 1.5 Autolaskuri koodaamatta

Tee autolaskuri kirjoittamatta riviäkään koodia. Jos lisätään uusi laskuri-lisää -pari, niin tarvitaanko vieläkään koodia?

Tehtävä 1.6 Uusi TNollaa

*Modifioi TNollaa -komponenttia siten, että sille voidaan antaa ominaisuutena kaikki komponentit, jotka halutaan nollata.

Tehtävä 1.7 Laskuri panelista

Peri TLaskuri panelista ja aseta oletuksena sopivat reunukset päälle.

Tehtävä 1.8 Laskuri TCustom???-komponentista

Peri TLaskuri TCustomLabelista tai TCustomPanelista ja pidä huoli ettei Caption-ominaisuutta voi käyttää
.

Tehtävä 1.9 LiikkuvaAuto-komponentti

Tee uusi komponentti LiikkuvaAuto, jolla on oma nopeus ja joka tutkii itse, milloin tulee seinä vastaan.


Ylös Edellinen Seuraava Otsikkosivu Hakemisto Sisällys