//Lisätty demo 5, tehtävä 1 mukaiset muutokset "vapaasti tulkittuna": //- Property AcceptChange: Boolean, jonka arvo tarkistetaan SetCount-metodissa // ennen muutosten sallimista. Oletuksena True. //- Tehtävässä vaadittu OnBeforeChange-event. Parametrina ProposedChange, eli // ehdotettu muutettu arvo, joka voidaan esim. hyväksyä tai hylätä // tapahtumankäsittelijässä ennen muutoksen tekemistä laskurin arvoon. unit laskuri; { Tehdään malliksi uusi komponentti TLaskuri, joka on kuten TLabel, mutta siinä pidetään kokonaislukuarvoa oikeassa reunassa, sinisellä pohjalla kentän leveys säilyttäen (oletuksena) ja siinä on lisäksi lisäys-metodi. Caption-ominaisuuden muuttaminen kelpuuttaa vain kokonaisluvut ja Caption on aina synkronissa Count-arvon kanssa. Vesa Lappalainen 26.8.1996 Muutokset 15.9.1997/vl + tarkistettu toiminta myös Delphi 3.0:ssa ja kirjoittu vastaava komponenttikirjaston "käyttöohje" Muutokset 11.10.1998/vl + tarkistettu toiminta myös Delphi 4.0:ssa ja kirjoittu vastaava komponenttikirjaston "käyttöohje". Value vaihdettu Count, koska luokkatäydennin käyttää Value:ta lokaalina parametrinä Muutokset 27.08.2001/vl + muutettu toimimaan CLX-kirjaston kanssa (määrittele vakio CLX) "Kirjastoa" voidaan testata ennen varsinaiseen komponenttikirjastoon lisäämistä seuraavasti: 1) Tee uusi projekti, lisää uses-osaan laskuri 2) Formin private osaan laita esim: lask : TLaskuri 3) Formin alustukseen kirjoitat: lask := TLaskuri.Create(self); lask.Parent := self; lask.SetBounds(20,20,50,lask.Height); 4) Lisää vaikkapa nappula, jonka painamisen koodiksi kirjoitat: lask.Inc(1); Komponentti voidaan lisätä kirjastoon seuraavasti (>=Delphi 3.0): 1) Kopioi laskuri.dcr (tai tee uusi: Tools/Image Editor) samaan paikkaan kuin laskuri.pas (tänne on tehty komponenttisivulle tuleva bittikartta TLASKURI, 24x24, Huom! nimi isolla Pitää olla näköjään oma .dcr eri Delphi versioille!). 2) Valitse Component/Install Component 3) a) Jos haluamasi kirjasto on jo olemassa, valitse "Into Existing package" ja sitten Yes b) Jos kirjastoa ei ole, valitse "Into New Package", kirjoita kirjaston nimi (esim. lask) ja kuvaus ja OK 4) Jos kirjastoa (Package) pitää korjailla, valitse esim. Component/Install Packages ja valitse kirjasto ja Edit. Korjausten jälkeen paina Compile ja tarvittaessa Install. Voit myös avata tiedoston lask.dpk. 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 Komponentti voidaan lisätä kirjastoon seuraavasti (Delphi 1.0 ja 2.0): 1) Käännä tämä tiedosto (vaikka jonkin projekti osana), esim. edellisen testin käännös riittää 2) Kopioi laskuri.dcu sinne kirjastoon, jossa sinulla on komponentit (ks. vaikka Components/Install/Search Path) 3) Kopioi laskuri.dcr samaan paikkaan (tänne on tehty komponenttisivulle tuleva bittikartta TLASKURI, 24x24, Huom! nimi isolla Pitää olla näköjään oma .dcr Delphi 1.0:lle ja Delphi 2.0:lle!). 4) Valitse Components/Install/Add ja kirjoita Laskuri ja OK OK (Delphi 1.0:ssa Options/Install Components/....) 5) Jos jatkossa havaitset komponentissa, riittää korjausten jälkeen Rebuild Library Tehtäviä (komponentit voi lisätä tähän samaan tiedostoon): 1) 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 2) Tee autolaskuri em. komponenteilla niin, että tarvitsee kirjoittaa vain yksi rivi koodia: Nollaa-nappulalle 3) Tee vielä komponentti TNollaa, joka nollaa kaikki samalla lomakkeella olevat laskurit (ks. ComponentCount ja Components). 4) Tee autolaskuri kirjoittamatta riviäkään koodia. Jos lisätään uusi laskuri-lisää -pari, niin taritaanko vieläkään koodia? 5)*Modifioi TNollaa- komponettia siten, että sille voidaan antaa ominaisuutena kaikki komponentit, jotka halutaan nollata. 6) Peri TLaskuri panelista ja aseta oletuksena sopivat reunukset päälle. } interface uses Classes, {$ifdef CLX} QControls, QGraphics, QStdCtrls, {$else} // VCL Controls, Graphics, StdCtrls, {$endif} SysUtils; type TLaskuri = class; TLaskuriEvent = procedure (sender:TLaskuri; diff:integer) of object; TLaskuriEvent2 = procedure (sender:TLaskuri; ProposedCount: integer) of object; TLaskuri = class(TLabel) private FAcceptChange: Boolean; FCount : integer; FOnChange: TLaskuriEvent; FOnBeforeChange: TLaskuriEvent2; function GetCaption: string; procedure SetCaption(const Value: string); function GetAcceptChange: boolean; procedure SetAcceptChange(const Accept: boolean); 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; property Caption:string read GetCaption write SetCaption stored false; property AcceptChange:boolean read GetAcceptChange write SetAcceptChange default True; { Seuraavat ominaisuudet isältä, ainoastaan oletusarvot erilaiset } property Alignment default taRightJustify; property AutoSize default False; property Color default clAqua; property ParentColor default false; { Kaikki muut isän ominaisuudet tulee sellaisenaan } property OnChange : TLaskuriEvent read FOnChange write FOnChange; property OnBeforeChange : TLaskuriEvent2 read FOnBeforeChange write FOnBeforeChange; end; procedure Register; implementation {$IFDEF VER80} { Delphi 1.0:sta puuttuu trim } uses strtrim; {$ENDIF} 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; AcceptChange := True; end; procedure TLaskuri.SetCount(const Value: integer); var diff : integer; begin if ( Assigned(OnBeforeChange) ) then OnBeforeChange(self, Value); if ( AcceptChange ) then begin diff := Value - Count; FCount := Value; inherited Caption := IntToStr(Count)+' '; { Välilyönti lop. on paremman näk. } if ( Assigned(OnChange) ) then OnChange(self,diff); end; end; function TLaskuri.Inc(i:integer) : integer; begin Count := Count + i; Result := Count; end; 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; function TLaskuri.GetAcceptChange: boolean; begin Result := FAcceptChange; end; procedure TLaskuri.SetAcceptChange(const Accept: boolean); begin FAcceptChange := Accept; end; procedure Register; { Komponentit pitää rekisteröidä komponenttisivulle } begin RegisterComponents('GKO', [TLaskuri]); end; end.