Delphi - Komponens fejlesztés haladóknak

10. rész

forráskód letöltése
Ha megfigyeljük a Delphi komponenseit, sok esetben találkozhatunk olyannal, amely tulajdonképpen több egymásba ágyazott komponens egyetlen komponensbe foglalva.

Ilyen például a TRadioGroup, ahol egy TGroupBox komponensen TRadioButton komponensek jönnek létre. Vagy ilyen a TDBNavigator, ahol egy TPanel-en vannak TSpeedButton nyomógombok.

Ehhez hasonlóan mi is készíthetünk ilyen komponenseket.

Mellékelt példában egy komponenst készítünk, amely nyolc darab nyomógombot tartalmaz egy háromszor hármas mátrixban elrendezve. Minden gomb tartalmaz egy kis nyilat, mely mutatja a megfelelő irányt. Az adott gombot lenyomva a megfelelő irányba görgethetjük mondjuk egy kép tartalmát. Ha megfigyeljük a Delphi komponenseit, sok esetben találkozhatunk olyannal, amely tulajdonképpen több egymásba ágyazott komponens egyetlen komponensbe foglalva.

Ilyen például a TRadioGroup, ahol egy TGroupBox komponensen TRadioButton komponensek jönnek létre. Vagy ilyen a TDBNavigator, ahol egy TPanel-en vannak TSpeedButton nyomógombok.

Ehhez hasonlóan mi is készíthetünk ilyen komponenseket.

Mellékelt példában egy komponenst készítünk, amely nyolc darab nyomógombot tartalmaz egy háromszor hármas mátrixban elrendezve. Minden gomb tartalmaz egy kis nyilat, mely mutatja a megfelelő irányt. Az adott gombot lenyomva a megfelelő irányba görgethetjük mondjuk egy kép tartalmát.


Mielőtt megnyitná a példaprogramot először telepítenie kell a Delphi-be a ScrollPanel.pas-ban található komponenst.

Nézzük, hogy is készül egy ilyen komponens.
A komponens őseként egy olyat kell választanunk, mely tartalmazhat más komponenseket. Általában a TWinControl-ból származó objektumok ilyenek.

Ennek az új komponensnek mindenképpen felül kell írnunk a constructor-át, mivel itt kell létrehoznunk azokat az objektumokat, melyeket ezen a komponensen szeretnénk elhelyezni. Jelen esetben nyolc darab TSpeedButton-t.

Ez a létrehozás úgy történik, hogy egy ciklussal végigmegyünk a 3 x 3 -as mátrix minden elemén. Mivel a komponens közepére nem kell nyomógomb, így ezt egy feltétel vizsgálattal kiszűrjük. Minden egyes eleménél egy lokális változóba létrehozunk egy TSpeedButton-t, majd ennek a Parent property-ét az újonnan létrehozandó komponensre állítjuk. Ettől kezdve ezek a TSpeedButton-ok ezen a komponensen fognak elhelyezkedni.

Ezután már csak az egyes nyomógombok property-ét kell beállítani. Ilyen például a pozíció (Top, Left). Ezeknek értékét az aktuális ciklusváltozó értékéből számítjuk ki.

Minden gombhoz betöltünk egy BMP-t, amely egy kis nyilat tartalmaz, mely a gombnak megfelelő irányba mutat. Ezeket a BMP-ket egy erőforrás állományba tároljuk, melyet fordításkor beépítünk a komponensbe. Így ahol ez a komponens felhasználásra kerül, ott rögtön az adott programba is bekerülnek ezek a képek, így bármikor felhasználhatók. Ennek az erőforrás állománynak az elkészítésére még visszatérünk.

Továbbá minden gomb OnClick eseményéhez ugyanazt az eseménykezelő eljárást rendeljük hozzá. Hogy majd a későbbiek folyamán mégis meg tudjuk különböztetni, hogy melyik gomb került lenyomásra az egyes gombok Tag property-nek a ciklusváltozót adjuk értékül, mely minden gombot egyedileg azonosít.

Végül az új komponens méretét is beállítjuk (Height, Width), amely egy TSpeedButton-nak a háromszorosa lesz.


Mikor majd használjuk ezt a komponenst, akkor nyilván a legfontosabb kérdés az lesz, hogy mikor melyik gomb került lenyomásra. Ezért ehhez most létrehozunk egy eseményt. Ebben az eseményben célszerű lenne visszaadni azt az értéket is, hogy melyik gomb került lenyomásra azon kívül, hogy melyik komponens is hozta létre az eseményt.

Mivel ilyen típusú esemény nem létezik a Delphi-ben, ezért nekünk kell előbb egy ilyet deklarálnunk.

Ezt a következő sorral meg is tehetjük:
TOnClickButton=procedure(Sender: TObject; ButtonIndex: integer) of object;

Majd ezt a típust felhasználva létrehozhatunk egy OnClickButton eseményt. Mikor a felhasználó kattint valamelyik TSpeedButton-on a nyolc közül, akkor meghívásra kerül a DoClick eljárás, mivel ezt rendeltük hozzá az összes gomb OnClick eseményéhez.

Ekkor hívhatjuk meg az új komponensünk OnClickButton eseménykezelőjét, feltéve hogy lett hozzárendelve eljárás. Hogy melyik gomb került lenyomásra, azt pedig a Tag property-ből tudjuk kiolvasni, mivel a nyomógombok létrehozásakor itt tároltuk el az azonosító számukat.


Ezzel tulajdonképpen kész is vagyunk. Már csak le kell fordítani és fel kell használni a komponenst.

Mellékelt példában arra használjuk a komponenst, hogy egy képet görgetünk vele tetszőleges irányba.


Nézzük most, hogy miként is kerülnek az egyes gombokra a BMP képek az erőforrás állományból.

Ehhez első lépésként szükségünk van az adott képekre, melyeket egy-egy BMP állományba lementünk (0.bmp-8.bmp).

Ezek után a Tools/Image Editor menüpont kiválasztásával elindíthatjuk az Image Editor programot. Ennek segítségével fogjuk létrehozni az erőforrás állományt, mely tartalmazza mind a nyolc képet.

Ehhez válasszuk a File/New/Resource File menüpontot. A megjelenő ablakban a jobb gomb lenyomásával és a New/Bitmap menüpont választásával hozzunk létre nyolc darab Bitmap erőforrást. Minden kép 16 x 16-os méretű legyen.

A már elkészített BMP állományokat megnyitva vágólapon átmásolhatjuk az egyes képeket.
Persze arra is van lehetőség, hogy itt rajzoljuk meg az egyes képeket, de erre a feladatra célszerűbb valami komolyabb rajzoló programot használni, ha van rá lehetőség.

Ezek után mentsük le ezt az állományt BMP.RES néven.

Ahhoz, hogy ez bekerüljön a lefordított komponensbe, csupán hivatkozni kell rá a forráskódban az alábbiak szerint: {$R BMP}, ahol a BMP a BMP.RES állomány neve kiterjesztés nélkül.

Komponens fejlesztés haladóknak cikksorozat