1aries.ektf.hu/~serial/delphi_/dok/szakdolgozat.doc · Web viewA hallgatóknak meg kell ismerniük...
Transcript of 1aries.ektf.hu/~serial/delphi_/dok/szakdolgozat.doc · Web viewA hallgatóknak meg kell ismerniük...
VESZPRÉMI EGYETEM
Matematikai és Számítástecnikai Tanszék
D I P L O M A D O L G O Z A T
BEVEZETÉS A DELPHI PROGRAMOZÁSI NYELVBE
Írta:Király Roland
Témavezető:Kiss Krisztián
Veszprém2005
Előszó
A dolgozat célja
A dolgozatom célja az, hogy megismertessem az olvasóval a vizuális
fejlesztő eszközök egyik legjobban használható darabját, a Delphi programozói
rendszert. A témát nem merítettem ki teljes mértékben, csak a lényeges
területeit érintettem.
A szakdolgozathoz tartozik egy web oldal, ahol kiegészítés található az
itt leírtakhoz. Ezek felhasználásával az olvasó magasabb szintre fejlesztheti
programozói tudását. A fejezetek végén, s néhol a fejezetekben is linkként
video anyagokat helyeztem el. A filmek bemutatják az adott fejezetben tárgyalt
Delphi komponensek használatát úgy, mintha az olvasó gépén készíteném el a
programokat. A szakdolgozat gerincét a nyomtatott szöveg alkotja, de az
animációk és a weboldal használata teszi teljessé a téma feldolgozását.
1. ábra A dolgozathoz tartozó weboldal (http://aries.ektf.hu/~serial/delphi_)
Ezzel segítséget próbálok adni azoknak a hallgatóknak s a tanároknak,
akik szeretnék ezt a nyelvet elsajátítani. Az egyes részeket és a hozzájuk
tartozó példákat úgy állítottam össze, hogy lehetővé tegyem az egyéni és a
2
csoportban történő tanulást. A gyakorlati és elméleti részeket kiegészítettem
módszertani egységekkel is, hogy az oktatók munkáját segítsem. Ezen
szakdolgozat tartalma közel sem elegendő ahhoz, hogy az olvasója „profi
programozóvá” váljon, de arra elég, hogy megismertesse vele a Delphi-t, és
alapot adjon a továbbhaladáshoz.
Megpróbáltam a témát áttekinthető egységekre bontani. A célom az
volt, hogy a Delphi legtöbb egységét legalább alapjaiban bemutassam.
Remélem, munkám mindenkinek hasznára válik!
3
TartalomjegyzékELŐSZÓ.......................................................................................................................................................2
A DOLGOZAT CÉLJA...................................................................................................................................2TARTALOMJEGYZÉK...................................................................................................................................4BEVEZETÉS................................................................................................................................................5
ÍRJUNK PROGRAMOT!...........................................................................................................................9
AZ OOP ALAPJAI....................................................................................................................................12
REKORD VAGY OBJEKTUM?.....................................................................................................................12MEGOLDÁS OBJEKTUMMAL.....................................................................................................................13AZ OOP SZABÁLYAI................................................................................................................................15A PRIVATE ÉS PUBLIC KULCSSZAVAK.....................................................................................................17A CONSTRUCTOR ÉS A DESTRUCTOR.......................................................................................................18
A TOBJECT ÉS TULAJDONSÁGAI.....................................................................................................19
KIVÉTELKEZELÉS: TRY EXCEPT ÉS FINALLY............................................................................21
A VCL ÉS MŰKÖDÉSE...........................................................................................................................25
KONVERTEREK.........................................................................................................................................25
A FORM ÉS TULAJDONSÁGAI............................................................................................................26
A FORM....................................................................................................................................................26
STANDARD KOMPONENSEK PALETTÁJA.....................................................................................32
TMENU....................................................................................................................................................33TBUTTON ÉS TLABEL...............................................................................................................................35TEDIT.......................................................................................................................................................36TLISTBOX................................................................................................................................................37DIALOG BOXOK........................................................................................................................................38TMEMO....................................................................................................................................................39RICHEDIT.................................................................................................................................................40TPANEL....................................................................................................................................................42
KEVÉSBÉ ISMERT KOMPONENSEK.................................................................................................44
TSTRINGLIST...........................................................................................................................................44TLIST.......................................................................................................................................................46
INIFÁJLOK KEZELÉSE.........................................................................................................................46
DLL-EK HASZNÁLATA.........................................................................................................................49
A DLL KÉSZÍTÉS SZABÁLYAI:.................................................................................................................49
A DELPHI GRAFIKÁJA.........................................................................................................................51
KÉPEK MEGJELENÍTÉSE............................................................................................................................52
ADATBÁZIS KEZELÉSI ALAPOK.......................................................................................................55
NYOMTATÁS DELPHI PROGRAMOKBÓL......................................................................................57
INTERNETES ÉS HÁLÓZATI ALKALMAZÁSOK...........................................................................59
A SZÁMÍTÓGÉP HARDVERÉNEK PROGRAMOZÁSA..................................................................61
DELPHI A GYAKORLATBAN..............................................................................................................64
TIPPEK, TRÜKKÖK DELPHI-BEN...............................................................................................................64
A SZÖVEGBEN SZEREPLŐ ANIMÁCIÓK GYŰJTEMÉNYE........................................................66
Végszó.........................................................................................................................................................67
4
5
Bevezetés
Az operációs rendszerek, és azon belül is a grafikus felület (GUI)
fejlődésével egyre inkább fontossá válik a vizuális fejlesztő rendszerek
használata. A leginkább elterjedt Operációs rendszer a Windows, s az azon
futó programok szinte mindegyike 32 bites (WIN32), és fejlett grafikus
külsővel rendelkezik. A mindennapi életben és így az oktatásban is, fontos
szerepet kapnak az ilyen alkalmazások készítésére használt eszközök, nyelvek.
A hallgatóknak meg kell ismerniük legalább egy ilyen eszközt, hogy
azután tetszésük szerint elsajátíthassák más, hasonló eszközök használatát,
vagy egyéb vizuális felületű, felhasználói programokat tudjanak készíteni.
A Delphi egyszerű kezelhetősége révén alkalmas erre a feladatra, s
mellette szól az is, hogy a legtöbb intézményben a Turbo Pascal nyelvvel
ismerkednek meg mélyebben a hallgatók. A Delphi a Pascal nyelvi alapjaira
épül, kiegészítve azt az Objektum Orientált Programozással.
Használata könnyen elsajátítható, s hamar komoly eredményeket lehet
elérni vele a programozás bármely területén. Jó ez azért, mert motivációt ad,
érdekessé teszi a munkát. Szükségesnek tartom továbbá azért is, mert a
számítástechnikát tanuló diákok nagy része előbb-utóbb szembe kerül azzal a
problémával, hogy Windows alatt működő programot kell írnia, s ha ezt a
régebbi, 16 bites eszközök valamelyikével teszi, nem feltétlenül ér el sikereket.
A Delphi teljes mértékben kompatíbilis a Windows-szal, grafikája
kiforrott és az Objektum Orientált Programozás ismeretével nagyon jól
használható eszköz.
A Delphi tanítása során olyan technikákat sajátíthatunk el, melyek a
későbbiekben fontossá válnak az operációs rendszerek megismerésénél, az
adatbázisok kezelésében, s a számítástechnika szinte minden területén. Ezt
viszont nem lehet elkezdeni az objektumok használatának ismerete nélkül,
mivel a rendszer teljes egészében erre épül. Igaz, hogy a régebbi programozási
technikák nagy része is használható, de a sikerhez semmi esetre sem elegendő.
Ügyelni kell arra, hogy a grafikus felület, az előre definiált
komponensek ne eredményezzék a tényleges programírás háttérbe szorítását.
6
Mivel a Delphi rendszer nagyon kényelmes, rengeteg alkalmazást el
lehet készíteni úgy, hogy kódot szinte nem is írunk, s ez kezdőknél legtöbbször
azt a képzetet kelti, hogy nem is kell többet tanulniuk, hiszen aki ilyen jó és
látványos programokat készít, az elsajátított mindent, amit a rendszerről tudni
lehet.
A helyes út az, ha kezdetben a hangsúly a kódon van, s nem a külsőn, és
ha okató úgy ítéli, hogy a hallgató megfelelő tudásanyagot sajátított el, át lehet
térni a felület esztétikus kialakítására.
Fontos, hogy tanítsuk meg a diákokat a komponensek működésére,
ismertessük meg velük az egyes elemek felépítését, s haladó szinten
elengedhetetlen az is, hogy mindenki megtanuljon saját komponenst készíteni.
Mivel a Delphi méreteit tekintve hatalmas, nem lehet mindent
megtanítani, de azt a szintet el lehet érni, hogy a diákok tovább tudják képezni
magukat.
Felmerülhet a kérdés, hogy melyik az az életkor, amikor a Delphi
oktatását el lehet kezdeni. Tapasztalataim alapján úgy ítélem, hogy a tizenéves
gyerekek már nagyon hamar alkalmassá válnak az ilyen és hasonló tantárgyak
megértésére. A Delphi tanítását véleményem szerint már a hetedik, nyolcadik
osztályban is el lehet kezdeni, s a kilencedik, tizedik osztály számára már nem
okozhat különösebb problémát.
Mindezek ellenére ne felejtsük el, hogy gyakran a hasonló korú diákok
sem mindig állnak azonos szinten a befogadóképesség terén. Felszereltségüket
tekintve lényeges különbség lehet az egyes iskolák között is. Mindig az adott
körülmények határozzák meg, hogy mikor kell elkezdeni, illetve egyáltalán el
kell-e kezdeni a Delphi oktatását, vagy a gyakorlatban már bevált nyelvek
valamelyikét fogják használni a programozás tanítására.
Tény, hogy programozni meg kell tanítani a gyerekeket, s a kor
követelményeinek nem megfelelő programozási nyelveket sok esetben jó új
nyelvekre cserélni.
Kérdés lehet az is, hogy a Delphi-ben milyen mélységig tanítsuk az
egyes elemek használatát. Ezt is eldöntheti az iskola pedagógiai programja,
esetleg a szülők igényei, s nem utolsó sorban az oktatási intézményben dolgozó
tanárok felkészültsége.
7
Nem szabad úgy elkezdeni az ismeretek átadását, hogy a tanár is akkor
tanulja a nyelvet, mikor oktatja (ami gyakori probléma…). Ha ugyanis csak
egy-két anyaggal jár a diákok előtt, bizonyosan nem tudja majd megválaszolni
a diákok által feltett kérdéseket.
Az iskolák többsége a Pascal alapokon nyugvó nyelveket helyezi
előtérbe, de vannak iskolák, ahol a C nyelv valamely implementációját
oktatják, mely utóbbi helyeken sem biztos, hogy a Delphi a legjobb választás,
de meggondolandó a váltás.
Ha a hetedik vagy nyolcadik évfolyamon tanítjuk a Delphi-t, próbáljuk
meg a hangsúlyt a vizuális elemekre helyezni, s ügyeljünk arra is, hogy a túl
bonyolult programok azt eredményezhetik, hogy a diák elveszti az
érdeklődését, vagy rossz esetben megutálja a programozást. Ne tanítsunk
Delphi-t hetedik osztály alatt, mert véleményem szerint a kívánt eredményt
nem érjük el! Egy hatodik osztályos tanulónak ugyanis nincs szüksége ilyen
magas szintű tudásra, és az alsóbb évfolyamoknál amúgy is fontosabb, hogy a
Word, az Excel, s más felhasználói programok ismeretét sajátítsák el. Nekik
tanítsunk más, egyszerűbb nyelveket. Nagyon jól használható a Logo vagy
valamely „robot” nyelv, s kicsiknél azt hiszem nincs is másra szükség
(fiatalabb gyerekeknél elég nagy feladat az is, hogy megbarátkozzanak a
számítógéppel, és az alapvető használat fogásait elsajátítsák).
Napjainkban dinamikusan fejlődő terület az Internet programozása,
hálózatot igénylő, használó szoftverek írása. A Delphi nyelv lehetőséget ad az
Internetet használó programok készítésére is, ellentétben a Turbo Pascal és
más régebbi nyelvekkel. Igaz, hogy internetes programok írására alkalmasabb
lehet a Java, C#, PHP stb. nyelvek, de azok lehetőségei korlátozottak az eddig
alkalmazott programozási nyelvek megtanítására. Fontos kérdés az
algoritmusok oktatása is. Úgy gondolom, a Delphi nem a legjobb eszköz a
programozási alaptételek megismerésére, mert pontosan azok lényegéről vonja
el a figyelmet. Algoritmusok gyakorlati alkalmazására jobb a Turbo Pascal,
vagy a QBasic, mert itt lényegében az alapalgoritmusokat tudjuk
programnyelvre fordítani, s nem kell az objektumok, vagy a komponensek
tömegén keresztül a lényegre összpontosítani a diákok figyelmét.
Ahogy fejlődik a technika, s vele a szoftverek, egyre több helyen látom
a kezdeményezést a fejlettebb programozási nyelvek bevezetésére, és sokszor
8
tapasztalom, hogy nem mindenhol tudják eldönteni, melyik nyelv is lenne a
megfelelő. Nem akarok senkit rábeszélni a Delphi-re, de az általam ismert
nyelvek között ez a legalkalmasabb az alsó és középfokú oktatásban. A C++
Builder nagyon bonyolult, a MS Visual C++, vagy .NET eszközökről nem is
beszélve, a Java pedig szinte csak a böngészőkben futtatható programok írására
alkalmas. Vannak más vizuális nyelvek is, de azok vagy nehezen
hozzáférhetőek, vagy nincsenek olyan mértékben elterjedve, hogy az oktatásba
érdemes lenne őket bevonni. A lényeg az, hogy mindenki jól gondolja meg,
melyik az az eszköz, ami számára, s főként a diákjai számára megfelelő. Ne
felejtsük el a tankönyvek kérdését sem. Nagyon nehéz olyan könyvet találni,
amely a magasabb szintű nyelveket a diákok számára érthető, befogadható
módon magyarázza el. Mostanában számos szaknyelven írott könyv jelenik
meg a Delphi-ről. Sajnos ezek sem a hagyományos értelemben vett
tankönyvek, hanem inkébb referenciák, de némelyikük jól használható oktatási
célokra is, pl. Marco Cantú: Delphi 1-5. (C, vagy Java nyelvhez nem találtam
ilyeneket.)
A módszertan gyakorlati megvalósítása során lényeges, hogy átfogó
képet adjunk a diákoknak az eszköz használatáról, foglaljuk csoportokba az
egyes részeket, s ezekből adjunk át annyit, amennyi az önálló munkához,
tanuláshoz elegendő. Így a könyvek nagy része emészthető lesz a kisebbek
számára is. Fontosnak tartom a nyelvi elemek megismertetését, s ezután
következhet a komponens paletta első néhány csoportja, majd a nem vizuális
elemek és a grafika, esetleg az adatbázisok kezelése. Mindenképpen térjünk ki
a fájlkezelésre, érintsük az operációs rendszer elemeinek a programozását, és
végül nem baj, ha a hallgatók megismerik az Internetes programozás néhány
fogását.
A Delphi oktatása és a tanulása érdekes feladat, nehezen válik
unalmassá (az oktató modszerei ezt nagyban befolyásolhatják…), és a gyors,
könnyen megszerezhető eredmények miatt a kevésbé jó képességű hallgatókat
is be tudjuk vonni a munkába.
Nem tartom hatásos módszernek azt, ha mindent át akarunk adni a
hallgatóságnak, főleg nem jó ez, ha a Delphi-t csak néhány félév keretében
tanulják, mert ezt a hatalmas tudásanyagot nem lehet ilyen rövid időn belül
megérteni, megtanulni, majd használatát készség szintre emelni. Nincs értelme
9
terhelni őket a rengeteg száraz leírással, a számtalan komponens
mindegyikének megismertetésével.
Helyezzük a hangsúlyt inkább a gyakorlásra, az önálló kreatív munkára,
mert így könnyedén, nagyobb erőfeszítések nélkül el tudják sajátítatni a Delphi
használatát. Adjunk feladatokat az órán, és adjunk ki otthoni munkát is, elvégre
programozni csak úgy lehet megtanulni, ha programokat írunk. A
későbbiekben ki-ki a saját belátása szerint haladhat tovább abba az irányba,
ami számára szimpatikus, vagy a szakjához szükséges.
Írjunk programot!
Vágjunk is bele! Kezdetnek megteszi egy egyszerű szövegkiíró
program, s ezt úgynevezett CONSOLE APPLICATION alkalmazással fogjuk
elkészíteni a konzol alapvető I/O eszközeivel Igaz, ez a módszer nem
megszokott a Delphi fejlesztői környezetében, de a jobb megértés miatt és
azért, hogy lássunk átmenetet a Turbo Pascal és a Delphi vizuális felülete
között, kezdjük ezzel!
Nyissuk meg a File menü New parancsával azt a párbeszéd panelt,
amelyen a lehetséges applikációk közül választhatunk! Válasszuk a Console
Application feliratú ikont, s mikor az Ok gombra kattintunk, megjelenik az új
projekt. Választásunk eredményeképp egy egyszerű szerkesztőablakot kapunk,
amelybe begépelhetjük programunkat.
10
2. ábra - A Delphi New Items párbeszédablaka
A Console Application ablak nem tartalmaz Form-ot, nincs külön
vizuális felület. Sokkal inkább hasonlít a Turbo Pascal-hoz, de ez ne tévesszen
meg minket! Az alkalmazás teljes értékű projekt, annak minden
tulajdonságával együtt, amit kiterjesztése is mutat: *.dpr. A Delphi programok
több fájlból épülnek fel, melyek összességét Projekt-nek nevezzük. Az
állományokból fordítás után egy exe állományt készít a fordító, ami már
önállóan, Kompiler nélkül is működőképes. (Ez az állomány régebbi verziójú
DOS alatt nem futtatható. Erről mindenképp tájékoztatni kell a diákokat!)
Nézzük meg a forráskódot, amit a Delphi generál a számunkra! A Uses
sor után a formmal rendelkező projektekkel ellentétben itt csak a SysUtils nevű
Unit van deklarálva, ami nekünk elegendő is a munkához.
A Begin után gépeljük be a következő sorokat:
Writeln(’Első Delphi program’);Readln;
A programot az F9 billentyű lenyomásával futtathatjuk. Ilyenkor a
Delphi lefordítja a projektet, és létrehozza annak exe állományát. (Az ékezetes
betűk, főként Widows XP rendszerben nem mindeig jelennek meg korrekt
módon. E miatt ne akadjunk meg, később orvosoljuk a hibát.)
11
3. ábra - Az első projekt futásának kimenete
Mint láthatjuk az alkalmazásunk hagyományos consol (CRT) ablakban
működik, hasonlóképp, mintha a Pascal nyelv egy korábbi implementációjában
írtuk volna, de ez nem jelenti azt, hogy nem bővíthetjük. (Egyébként az
alkalmazás WIN32-es, tehát teljes értékű Windows program… Unit-ok
hozzáadásával akár többablakos, windows-os alkalmazást is készíthetünk
belőle.)
Miután a programunk lefutott, visszakapjuk a szerkesztő ablakot. Az
exe állomány létrejött, minden futtatás után újrafordítódik követve a
forráskódban történt változásokat.
A Delphi-vel dolgozni első ránézésre nem könnyű és legtöbbször nem
is használunk konzolos alkalmazást. A bonyolultabb programoknál a helyzet
közel sem ilyen egyszerű, s mielőtt elkezdenénk a komolyabb munkát,
mindenképpen meg kell tanulnunk a Delphi IDE működésének alapjait,
alapvető formáit, valamint ezek mellett tisztában kell lennünk az Objektum
Orientált Programozás alapjaival. Igaz, hogy az OOP nélkül is lehet
programokat készíteni, de a Delphi objektum orientált alapokra épült, így ha
meg akarjuk tanulni a hatékony használatát, akkor e tudás nélkülözhetetlen!
A Delphi oktatás előtt feltétlenül meg kell ismertetni a diákokkal az
OOP-t. Jó megoldás lehet, ha egy egész félévet áldozunk az elsajátítására. A
tanításhoz Turbo Pascalt, vagy a Borland Pascal valamely verzióját
12
használjuk, hogy ne zavarjunk meg senkit a Delphi összetett kezelői
felületével!
13
Az OOP alapjai
Rekord vagy objektum?
Az Objektum Orientált Programozás eltér a hagyományos,
strukturált programozástól, hatékonyabb annál, de több ismeretet is követel a
programozótól (esetünkben a diákoktól), mint az előbbi.
Alapja az Objektum, mely adatszerkezet hasonlít a Record-ra, s
megérteni is legjobban a rekorddal való összehasonlítás során lehet (a record
adatszerkezet a Pascal nyelv alapjainak elsajátításakor már előkerült).
Nézzük meg egy rekord felépítését! Legyen ez a Record egy szöveg
kiírását segítő adatszerkezet!
TypeSzoveg=record
X,Y:integer;S:string;
End;
Az X,Y mezők a szöveg helyét határozzák meg a képernyőn, az S
String magát a szöveget. Mint láthatjuk a Rekord-nak van neve, típusa, és
vannak mezői, melyek összességükben egy adatstruktúrát alkotnak. Ahhoz
viszont, hogy a rekordban tárolt szöveg a képernyőre kerüljön, mindenképpen
deklarálnunk kell a rekord egy példányát, értéket kell adnunk a rekord
mezőinek, mely egy újabb rutin, majd készítenünk kell egy kiíró eljárást. A
Turbo Pascal nyelvi változat a következő képpen néz ki:
Var szov:szoveg;
Procedure ertek(var szov0:szoveg);Begin With szov0 do X:=10; Y:=10; S:=’Masodik Delphi program’; End;End;
14
Procedure kiir(szov0:szoveg);Begin Gotoxy(szov0.x,szov0.y); Writeln(szov0.szoveg);End;
Gafikus felület használatánál a program kódja az előzőnél is
bonyolultabb lesz.
Jobb megoldás lenne ennél, ha a rekordhoz nem kellene külön megírni
az eljárásokat, hanem az adatszerkezet tartalmazná azokat. Mint tudjuk, ez a
rekordnál nem lehetséges, mivel köt minket a nyelv szintaktikája. Hogy ez a
probléma megoldható legyen Objektum-ot kell használnunk, melybe írhatunk
eljárásokat, megoldhatjuk benne a kezdőértékek beállítását és még számos
dolgot, de ezeket hagyjuk későbbre!
A probléma megoldása tehát az Objektum, amelynek lehetnek a
mezőin kívül metódusai is.
Megoldás objektummalType Szoveg=object X,Y:integer; S:string; Procedure init(X0,Y0,C0:integer;S0:string); Procedure kiir;End;
Procedure szoveg.init(X0,Y0,C0:integer;S0:string);Begin X:=X0; Y:=Y0; C:=C0; S:=S0;End;
Procedure szoveg.kiir;Begin GotoXY(X,Y); Writeln(S);End;
Ez így már kerek egész! Az objektum magában foglalja a kiíráshoz
szükséges adatokat, a kezdőérték beállítását, valamint a kiíró utasítást is. Előny
az is, hogy a változókat elfedtük a külvilág elől, mivel a kezdőérték beállítását
nem közvetlenül, hanem az init eljárás segítségével közvetett úton oldottuk
15
meg. Ez hasznos lehet a későbbiekben, amikor bonyolultabb objektumokat
készítünk, mert az adatokat meg tudjuk védeni a hibás értékadásoktól (erre a
technikára az OOP nyelvek lehetőséget biztosítanak a Private, Public és
Protected kulcsszavakkal), s ellenőrizni tudjuk, hogy mikor és hogyan kapnak
értéket. Az OOP-ban fontos szabály, hogy az adatokhoz a programozó
biztosítja a hozzáférést, tehát azokat a külső rutinok csak így, közvetett úton
érhetik el. Ezt mi is tegyük meg! Írjunk az objektumhoz függvényeket, amik
lekérdezik a mezők értékét!
Function getX:integer; Begin GetX:=X; End;
Function getY:integer; Begin GetY:=Y; End;
Function getS:string; Begin GetS:=S; End;
Van megoldás arra is, hogy ne kelljen saját metódusokat definiálni az
értékadásra és a változók értékének a visszaadására. A Property kulcsszó után a
következő deklarációval megoldhatjuk ezt:
Property x_erteke:integer; read X write X;
A deklaráció és az objektum létrejötte után az X változóra
hivatkozhatunk a következő módon:
ObjektumPeldany.x_erteke:=10; WriteLn(ObjektumPeldany.x_erteke);
A Property sajnos Class típus esetén működik, objektumnál nem
minden esetben.
16
Az objektum deklarációban is fel kell venni a három függvény nevét,
majd ha ezt megtettük, az adatszerkezet a következőképpen fog kinézni:
Type Szoveg=Object X,Y:integer; S:string; Function getX:integer; Function getY:integer; Function getS:integer; Procedure init(X0,Y0,C0:integer;S0:string); Procedure kiir; End;
Vegyük észre, hogy az objektum mezőire nem úgy hivatkoztunk az
eljárásokban, mint ahogy a rekordoknál tettük! Ennek az oka az, hogy az
objektum metódusai mindig az objektum mezőire vonatkoznak, és a
hagyományos felfogással szemben itt nem az eljárásokhoz készítünk
változókat, hanem a változókhoz rendeljük hozzá az eljárásokat. Ez a látásmód
eltér az eddigiektől, de ha megszokjuk és megtanítjuk az alkalmazását,
lényegesen megkönnyíti munkánkat. Ennek szintaktikai okai és alapjai vannak,
de erre a későbbiekben térek ki.
Mielőtt tovább mennénk, foglaljuk össze az eddig tanult szabályokat és
egészítsük ki továbbiakkal!
Az OOP szabályai
Az objektum a rekorddal ellentétben tartalmaz eljárásokat is (metódus)!
Az objektumnak kezdőértéket kell kapnia (inicializálás)!
Gondoskodni kell a mezők felszabadításáról (Pointerek esetén fontos);
Az objektum mezői a metódusain keresztül kapnak értéket!
A mezők értékét közvetett úton lehet olvasni, függvények (esetleg
property-k) segítségével! (adatrejtés)
Az objektumnak deklarálni kell egy példányát, csak ezután használható!
Az objektum metódusai mindig az objektum mezőire vonatkoznak és azokra fejtik ki hatásukat!
17
A szabályok után következzenek az elvek!
Egységbezárás Öröklődés Sokalakúság
Ez a három fogalom kulcsfontosságú az OOP alkalmazásában. Ezek az
elvek képzik az alapját az objektum orientáltságnak, s ezek az elvek teszik azt
hatékonyabbá a hagyományos struktúrát programozásnál. Amennyiben a
diákok nem látják ezt be, hívjuk fel rá a figyelmüket! Tudniuk kell, miért
tanulják ezt a módszert és később milyen előnyeik származnak ebből.
Nézzük meg, mit jelentenek a fent említett alapelvek!
Egységbezárás (encapsulation)
Az adatok, eljárások és függvények egységet alkotnak, egy
adatszerkezet tartalmazza őket Ez a legfontosabb jellemzője az OOP-nak. A
hagyományos nyelvekben az adatok másodlagos szerepet kapnak az
eljárásokkal szemben, itt viszont az adatokhoz rendeljük az eljárásokat.
Öröklődés (inheritance)
Az öröklődés lehetővé teszi, hogy a már meglévő objektumokból új, az
ős-objektum adatait tartalmazó, de saját mezőkkel, eljárásokkal, függvényekkel
rendelkező objektumokat hozzunk létre.
Sokalakúság (polymorphism)
A származtatás során lehetőség van az új objektum tulajdonságainak
megváltoztatására, az ős-objektum metódusainak felül-definiálásával. A
származtatott objektum a hierarchia tagjaként ugyanazzal a metódusnévvel,
paraméterekkel, de más metódus-törzzsel rendelkezik, s ez által másképp
18
működik az ugyanolyan nevű eljárása. (Lehetőség van ezek mellet az overload
típusú, vagy a változó paraméter-számú metódusok készítésére is.)
Ezen három alapelv helyes alkalmazásával jól átlátható, hogy könnyen
használható, és főként könnyedén alakítható programokat készíthetünk. Első
ránézésre kissé bonyolultnak tűnik a dolog, de a használat során rájövünk,
hogy ez a fajta technika hosszú távon sokkal hatékonyabb!
A Private és Public kulcsszavak
Mint említettem, az objektumok készítésénél ügyelnünk kell arra, hogy
az adatok rejtve maradjanak és azokhoz csak a metódusokkal férhessünk
hozzá.
Erre a szintaktika is lehetőséget biztosít a private és a public
kulcsszavak bevezetésével. Nézzünk erre egy példát! Készítsünk egy
objektumot, mely egy kört rajzol ki a képernyőre!
Kor=object Private X,Y:integer; R:integer; C:integer; Public Constructor init(X0,Y0,R0,C0:integer);virtual; Function GetX:integer; Function GetY:integer; Procedure rajzol; Destructor done;End;
Mint láthatjuk a deklarációban szerepel két új kulcsszó. A private rész
után szereplő változók, eljárások a „külvilág” (a főprogram) számára
láthatatlanok, vagyis azokat csak az objektum metódusai érhetik el, míg a
public kulcsszó utáni változók, eljárások láthatóak, vagyis meghívhatjuk őket a
fő programból.
(A Private, Public és Protected kulcsszavak egy programon belül sajnos
nem fejtik ki hatásukat. Amennyiben az Objektum, vagy Osztály (Class) külön
Unit-ban szerepel, a kulcsszavak működnek.)
19
A Constructor és a destructor
További két új szóval találkozunk az objektum deklarációban: ezek a
Constructor és a Destructor. A szabályok közt szerepelt az is, hogy az
objektum mezőinek kezdő értéket kell kapniuk, ez a Constructor feladata;
majd a használat után az erőforrásokat fel kell szabadítani, és erről
gondoskodik a Destructor. Az ilyen módon deklarált eljárások minden esetben
(garantáltan) lefutnak (ezt ne vegyük ténynek… Igenis vannak olyan esetek,
amikor nekünk kell meghívni a konstruktort), s különösképp szükségesek a
Pointer típusú változók használata esetén, mivel ha a pointereket nem töröljük
a memóriából, azok ott maradhatnak a program futása közben, és utána is. A
konstruktor eljárás neve az Object Pascal-ban általában Init, a Delphi-ben
Create, a destruktor neve a Pascal-ban Done, a Delphi-ben Destroy vagy
Free.
Nézzünk egy példát az öröklődésre! Származtassunk a kör objektumból
egy új objektumot, mely a kirajzolt kört mozgatni is tudja! Ehhez szükségünk
van további eljárásokra, ezeket hozzá kell adnunk az objektumhoz, de az
öröklődés tulajdonságai miatt a régieket nem kell újraírnunk.
Kor_uj=object (kor) Private UjX,UjY:integer; TC:integer; Public Constructor init;virtual; Procedure Mozgat(H1,H2:integer); Destructor Done;End;
Procedure Mozgat(H1,H2:integer);Begin TC:=BgColor; Rajzol; X:=H1; Y:=H2; Rajzol;End;
Ezzel a megoldással nem kellett ismét megírni a metódusokat, hanem a
régieket használtuk úgy, hogy az objektumot egy, már meglévőből hoztuk
létre. Ilyen módon létrehozhatunk több egymásból származtatott objektum
20
szintet is (az öröklés mélysége nincs meghatározva, viszont egy bizonyos szint
után könnyen elveszíthetjük a fonalat…). A programok továbbfejlesztésénél ez
nagyon kényelmes megoldás, mivel nem kell a meglévő Objektumok helyett
újakat írni. Az eddig említett néhány szabály elegendő ahhoz, hogy
belekezdjünk a Delphi megismerésébe, de ne haladjunk tovább, míg ezeket az
elveket minden diák meg nem értette!
Az Objektum Orientált Programozás ismerete nélkülözhetetlen a
Delphi oktatásában, ezért amikor tanuljuk, vagy tanítjuk a Delphi-t, érdemes rá
időt fordítani. Ismerete nélkül a továbbhaladás nagyon nehézkes, némely
részeknél szinte lehetetlen.
Fordítsunk tehát figyelmet az Objektumok részletes megismerésére, az
Objektum Hierarchia, az öröklődés, és a különböző kulcsszavak
tanulmányozására, hogy ezzel későbbi munkánkat megkönnyítsük!
(A Delphi rendszerben használható a fent említett Object kulcsszó, de a
Delphi programok az ún. Osztály vagy másnéven Class kulcsszóval deklarált
adatszerkeetet támogatják. A Class lényegesen több beépített metódust és
lehetőséget tartalmaz, mint az Object.)
A TObject és tulajdonságai
Delphi- ben az objektumok kezelése eltér az eddig tárgyaltaktól, de
lényeges különbség nincs. Változott a szintaxis, bővült a rendszer, de a
filozófia azonos maradt.
A Delphi az objektumokat osztálynak nevezi (Class), az osztályokat
pedig új kulcsszavakkal bővítették ki.
A Delphi környezet egyik legfontosabb eleme a TObject, amely
minden objektum őse. Az összes objektum ebből az elemből van származtatva,
lehetővé téve azt, hogy bármely Delphi komponenst helyettesítsünk vele,
vagyis kompatibilis azokkal. (Persze, mint azt megszokhattuk, a
számítástechnikában itt is vanak kivételek…)
Az eseménykezelőknek általában van egy Sender nevű változója, mely
TObject típusú, ezzel hivatkozunk az eseményt kiváltó objektumra. Hogy ezt a
technikát alkalmazni tudjuk, meg kell ismerkednünk az As és az Is
operátorokkal!
21
Az As (futási időben kiértékelt típuskonverzió operátor) működése:
Procedure TForm1.Button1Click(Sender: TObject);Begin (Sender as TButton).Caption:=’lenyomva’;End;
Az eljárás némi magyarázatra szorul. A Sender:TObject változóval
azonosítottuk azt a TButton-t, amely aktivizálta az eseménykezelőt (Sender as
TButton). Mellette van az a mező, amelyre hivatkozni szeretnénk. A Sender-
nek nincs Caption mezője, ezért írtuk, hogy (Sender as TButton).caption, ami
már az eseményt kiváltó nyomógomb Caption mezőjére utal. A nyomógomb
eseménykezelője a lenyomás után a gomb feliratát „lenyomva” feliratúra
állítja. Ez így önmagában nem túlságosan hasznos, de a megértéshez elegendő.
Az As operátor használata akkor válik fontossá, ha az eseménykezelőt több
nyomógomb esetén is használni szeretnénk. A Button1 OnClick eseményét
megadhatjuk több, másik nyomógombnak is, és ilyenkor a lenyomás után a
Sender változóban tárolódik az, hogy melyik nyomógomb váltotta ki az
eseményt, és annak a felirata fog megváltozni.
A másik operátor az Is, ami típusellenőrzésre való, valamint arra, hogy
a nem homogén elemek (objektumok) közül kiválasszuk, hogy milyen típus
váltotta ki az eseményt.
Nézzünk erre is egy példát! Ha azt szeretnénk, hogy ne csak
nyomógombok használhassák az eseménykezelőnket, az Is operátorral
megvalósíthatunk egy univerzális metódust, amely működik akár panelek, vagy
egyéb más objektumok esetén is.
Procedure TForm1.Button1Click(Sender: TObject);Begin
If Sender Is TButton Then (Sender as TButton).Caption:=’lenyomva’ Else (Sender as TPanel).caption:=’panel aktiválva’; End;
22
Így az eseménykezelő működni fog panelek és nyomógombok esetén is.
A jó ebben az, hogy nem kell minden objektum számára külön eseménykezelőt
készíteni. Különösen eredményesen alkalmazható ez a technika bonyolultabb
programoknál.
A kód egyértelművé, s mindenek előtt rövidebbé válik, s a
későbbiekben a javítás, optimalizálás során jelentősen megkönnyíti a
programozó dolgát.
Kivételkezelés: Try Except és Finally
A kivételkezelés új, nagyon hasznos programozási szerkezet, amely a
Delphi fejlesztői környezet sajátja és a Turbo Pascal korábbi
implementációiban nem szerepel. Lehetőséget biztosít a futás közbeni
hibakezelésre. Azért is fontos, mert a programozás órákon nagy hangsúlyt
helyezünk az úgynevezett „bolondbiztos programokra”. A kivételkezeléssel ez
könnyen megvalósítható. (Szakzsargon : bolondbiztos programnak azt az
alkalmazást nevezzük, amelyhez odaültetve a „Rosszindulatú Felhasználót”, az
nem tud hibás működést előidézni…)
Nézzük meg hogyan működnek a kivétel kezelő blokok!
Try <utasítások, eljárások, függvények, melyek futás közben hibát okozhatnak.>Except <[hiba okának megálapítása]> <hibakezelő eljárások>End;
Ha a Try részben meghívott eljárások hibás futást eredményeznek, a
program nem áll le, hanem az except részhez ugrik, majd végrehajtja az ott
leírt utasításokat, amiket általában a hiba kezelésére, vagy hibaüzenetek
megjelenítésére hoz létre a programozó. (A Delphi fejlesztői környezetből
futtatva a programot a Windows hibakezelő rutinjai is megjelennek, de az exe
állomány futtatásánál már csak a saját hibakezelés fut…)
Miután ezek lefutottak, a program folytatja működését. A másik
szerkezet hasonlóképpen működik. A különbség az, hogy a Try után, a Finally
23
részben leírt utasítások mindenképpen végrehajtódnak, függetlenül a Try
részben történő hibáktól.
Try <eljárások, függvények, melyek futás közben hibát okozhatnak.>Finally <eljárások, melyek minden esetben lefutnak>End;
A Finally részben szoktuk elhelyezni az olyan utasításokat, melyeknek
mindenképpen végre kell hajtódniuk, még akkor is, ha a Try részben hiba
keletkezik. Gondolok itt a pointer típusú változók felszabadítására, vagy
esetlegesen nyitva maradt fájlok lezárására. Ha jobban belegondolunk,
számtalanszor előfordul, hogy a programjaink a merevlemezre írnak, fájlokat
nyitnak meg, és használják az operációs rendszer különböző részeit.
Amennyiben a futó program hibával leáll, nincs, ami gondoskodna ezen
erőforrások felszabadításáról. Sokszor a kezdő programozók nem is jönnek rá a
hiba forrására, s ez hatványozottan jelentkezik a diákoknál.
Nézzünk meg egy konkrét példát!
Function osztas (n1,n2:integer):real; Var hanyados:real; Begin Try hanyados:=n1/n2; osztas:=hanyados; Except showmessage (’nullával való osztás’); hanyados:=0; End; End;
A függvény két egész szám hányadosát adja vissza. Amennyiben a
második szám, az n2 értéke 0, a Try részben hiba keletkezik, s a vezérlés az
Except részre ugrik, ahol a ShowMessage nevű eljárás kiírja a felhasználónak
a hiba okát: nullával való osztás. (Ezt a későbbiekben még kibővítjük, mert így
a program bármely hibánál azt írja ki: Nullával való osztás. Egyébként a
nullával való osztás nem minden esetben okoz hibákat…)
Ez egy tipikus példa a kivétel kezelésére, de a programok többsége nem
oldható meg ilyen egyszerűen. A Try részben lényegesen több utasítás, eljárás,
24
függvény szerepelhet, és a program futása során meg kell győződnünk arról,
hogy melyik okozta a hibát és a megfelelő hibakezelő eljárást kell meghívni. A
Delphi erre is lehetőséget biztosít. Az Except részben elhelyezhetünk a hiba
lekérdezésére szolgáló részeket. A fenti eljárást a következőképpen lehetne
javítani:
Except On EDivByZero Do Begin showmessage (’nullával való osztás’); hanyados:=0; End; End;
Ez a fajta megközelítés már alkalmas lenne több hiba egyidejű
kezelésére is. A Finally blokk működésére is nézzünk egy példát! Mint
említettem, az itt leírt utasítások mindenképpen végrehajtódnak, ezért nem csak
a hibák kezelésére alkalmasak, hanem az erőforrások felszabadítására is.
A példaprogram megnyit egy fájlt, tartalmát egy ListBoxba (a ListBox-
ra és használatára később sort kerítünk) tölti. Ha a betöltés folyamán hiba
keletkezik, a Finally részben lévő eljárás bezárja a fájlt. Amennyiben a
program nem okozott hibát, a Finally rész akkor is meghívódik, tehát biztosak
lehetünk abban, hogy a fájlunk nem marad nyitva.
Procedure beolvas (f:textfile); Var S : string; Begin Try Assignfile (f, ’szoveg.txt’ ); While not EOF (f) do Begin Readln (f, s); Listbox1.items.add (s); End; Finally Closefile (f); End;End;
(Természetesen gyakorlott Delphi programozók a fenti metódust kb. két
sorból megoldanák. ) A kivételkezelés elsajátítása elengedhetetlen ahhoz,
25
hogy hatékony Delphi programokat írjunk, mivel a hibakezelés nélkül futó
programok hiba esetén leállnak, az operációs rendszer veszi át a vezérlést és ír
hibaüzeneteket a képernyőre.
A SysUtils nevű Unit-ban vannak definiálva a kivételkezelést támogató
rutinok. A következő felsorolásban kiemeltem a legfontosabbakat.
EOutOfMemory: akkor lép fel, ha az alkalmazáshoz nincs elég
memória.
EDivByZero: egész számok nullával való osztásakor lép életbe.
EMathError: akkor lép fel, ha a lebegőpontos műveletekben hiba van.
EGPFault: akkor lép fel, ha, érvénytelen memóriacímre hivatkozunk.
EConvertError: konverziós függvények hibáját jelzi (pl InToStr();)
EInvalidCast: az as operátor két oldalán nem azonos típusú objektum
van
Az itt felsoroltakon kívül még számos rutin létezik, de számunkra ezek voltak a legfontosabbak.
26
A VCL és működése
A Visual Component Library, vagy Vizuális Komponens Könyvtár
teszi igazán hatékony eszközzé a Delphi-t. Ez a library (nem a klaszikus
értelemben vett könyvtár ) tartalmazza a vizuális elemeket, az előre definiált
Form-okat, gombokat, paneleket és minden, a Windows Operációs Rendszer
alatt használt grafikus elemet.
Vegyük sorra a legfontosabb elemeit. Ez a felsorolás nem teljes, mert a
Delphi komponensek száma nagyon nagy, a rendszer pedig folyamatosan
bővül az egyes verziók megjelenésével, ezért csak egyes részekkel
ismerkedünk meg. Ha ezeknél többet szeretnénk megtanítani, a különböző
Delphi-ről írt könyvek nagy segítséget nyújtanak a tananyag összeállításánál.
Konverterek
A Delphi rengeteg lehetőséggel rendelkezik az adatok konvertálására.
Szinte minden egyszerű adattípus átalakítására van külön metódusa, s ezek
használata is jelentős könnyebbséget mutat a Turbo Pascal metódusaihoz
képest. Ezek a konverterek nem a VCL részei, de nélkülük a VCL elemeinek a
használata nagyon nehéz.
A legtöbbször használt konvertáló eljárás az Function
IntToStr(n:integer):string; egész típusú adatokat alakít át szöveg típussá.
Függvényként hívjuk meg, majd visszatérési értékét átadhatjuk bármely szöveg
(a Delhi–ben a szöveg nem minden esetben String típus, csak azzal
kompatibilis) típusú mezőnek. Nézzünk egy példát a használatára!
Var S:string; N:integer;Begin N:=10; S:=IntToStr(’128’); S:=IntToStr(n);End;
27
Az IntToStr párja az StrToInt, ami a szöveg vagy karakter típusú
adatot alakítja át egész típussá. Használni ugyanúgy kell, mint az előzőt.
Var n:integer;
S:=’128’;N:=StrToInt(’128’);N:=StrToInt(s);
Létezik ezeken kívül néhány konverter, ami számunkra fontos lehet.
Ezek az IntToHex, mely integer típusú adatot alakít hexadecimálissá, ennek a
párja a HexToInt, de van eljárás a valós és a logikai típusú adatok átalakítására
is.
A színek konvertálása már nem ilyen egyszerű. Gondolok itt a
böngészőkben használt Color típusokra, melyek a három alapszínt
hexadecimális formában tárolják (pl.: #FFEE00), és ha ezt átalakítjuk a
Windows-ban, vagy a Delphi-ben használt színekre, nem mindig jutunk
korrekt eredményhez.
A Form és tulajdonságai
A Form az egyik legfontosabb Delphi építőelem, amely szinte minden
Delphi-ben írt alkalmazás része.
Tanításánál ne hagyjuk ki a forráskód megismerését sem, mert így a
működés megértése egyszerűbb lesz! Vizsgáljuk meg a Form alapvető
tulajdonságait, felépítését, metódusait!
A Form
Amikor egy új projektbe kezdünk, meghatározzuk annak formáját is. A
Windows rendszerben szinte minden futó program ablakmodellel rendelkezik.
A Delphi-ben ezt a modellt Form-nak nevezzük, s mikor elindítjuk az új
Projektet, annak forráskódjába beépül a Form kódja is. Amennyiben a Form-
28
ra helyezünk egy komponenst, annak kódja is belekerül a Form deklarációjába,
szerves részévé válik.
Ezt a folyamatot már láthattuk az objektumok örököltetésénél. A Form
a szülője lesz a ráhelyezett komponensnek, ami örökli a Form
tulajdonságainak nagy részét.
4. ábra - A delphi From
Nézzük meg a Form –mal rendelkező Unit forráskódját!
Unit Unit1;InterfaceUses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;Type TForm1 = class(TForm) Private { Private declarations } Public { Public declarations } End;Var Form1: TForm1;
Implementation
{$R *.DFM}End.
29
Ez a forrás nem teljes, a Form-nak csak kis részét tartalmazza, de a
programjaink forráskódjában elegendő. Készíthetünk több Form –mal is
rendelkező programokat.
Mint láthatjuk, a Unit elején deklarált típusban már szerepel a TFrom
nevű osztály, s ha a Form-ra helyezünk egy TButton komponenst, annak
kódja is automatikusan beépül az osztály deklarációjába.
Type TForm1 = class(TForm) Button1: TButton; Private { Private declarations } Public { Public declarations } End;
Ez igen hatékonnyá teszi a Delphi-vel való munkát, mert az egyes
elemeket nem kell nekünk megírni, hanem csak egyszerűen egérrel a Form-ra
húzni és azok megjelennek a forráskódban.
Persze ez nem jelenti azt, hogy csak ilyen módon építhetünk
objektumokat. Lehet akár futási időben is létrehozni és elhelyezni
komponenseket a programba.
Próbáljuk az előbbi nyomógombot a program működése közben a
Form-ra helyezni! Az eljárás forráskódja a következőképpen alakul:
Procedure TForm1.Letrehoz;Var T:TButton;Begin Try T:=TButton.Create(Form1); With t do Tegin height:=40; width:=100; left:=100; top:=100; parent:=form1; visible:=true; End; Except
30
ShowMessage('Hiba létrehozáskor'); End;End;
Az eljárást helyezzük el egy másik nyomógomb OnClick metódusába.
Mikor lenyomjuk a gombot, a T változó, ami TButton típus, létrejön. A
Create (konstruktor) eljárás létrehozza a nyomógombot és kirakja a Form-ra.
Beállítottuk a szélességét, a magasságát, és azt, hogy a Form melyik részén
helyezkedjen el, majd megadtuk a szülőjét (ez az a komponens, amire
helyezzük, jelen esetben a Form), megmondtuk, hogy legyen látható. Ilyen
módon bármelyik komponenst létre lehet hozni.
Ha több, hasonló komponenst szeretnék készíteni, tegyük őket egy
tömbbe, majd egy ciklus segítségével hozzuk létre az elemeket. A Form-nak
vannak előre definiált metódusai, tulajdonságai, melyeket a rá helyezett
komponensek örökölnek. A legfontosabbakat nézzük meg mi is!
OnCreate (); Ez az eljárás akkor fut, amikor a Form létrejön. Ide
érdemes helyezni a változók inicializálását. Ebből a metódusból
származik a többi Create metódus is, amikkel az egyes elemeket
létrehozhatjuk.
OnShow (); Közvetlenül a Create metódus után hajtódik végre. A
Form külső jellemzői állítódnak be itt. Ez végzi a megjelenítést.
OnPaint (); A Form kirajzolását végzi.
OnRePaint (); Újrarajzolja a form felületét.
OnCanResize(); A Form átméretezésénél hívódik meg.
A Form-nak a metódusai mellett tulajdonságai is vannak. Ezek közül is
kiemeltem néhányat:
Height, Width, Left, Top, Right Bottom: a Form méreteit leíró
változók.
FormStyle: A képernyőn megjelenő ablak (Form) típusa.
Font: a Form-on alkalmazott betűtípus. (Öröklődik a ráhelyezett
komponensek betűtípusára is, amennyiben azokat nem állítjuk be).
31
Color: a Form színét határozza meg.
Caption: A Form felirata (nem keverendő a nevével)
Visible: Nagyon fontos tulajdonság. Megmondja, hogy a Form látható
vagy sem.
Ezeken kívül még rengeteg más tulajdonsága is van a Form-nak, de
egyelőre elégedjünk meg ennyivel.
Nem tartozik szorosan a Form-hoz, de annak használatához szükséges
a Screen osztály. Ennek ClientHeight és a ClientWidth tulajdonságaival
lekérdezhetjük a képernyő, vagyis a Windows Desktop méreteit. (Ebben a
méretben a Start menü nincs benne.)
A Screen objektum be van építve a programjainkban, ezért egyszerűen
csak hivatkoznunk kell rá (nem kell deklarálni):
A következő programrészlet a Form szélességét és magasságát a screen
objektum, vagyis a képernyő méreteihez igazítja.
Form1.Height:=Screen.ClientHeight;Form1.Width:=Screen.ClientWidth;
A Form méretét hozzá tudjuk igazítani a mindenkori képernyő
felbontásához. Ez olyan esetekben hasznos, ha a programunkat más
számítógépen is szeretnénk futtatni, ahol a monitor mérete vagy a videokártya
más, s ezáltal a felbontás sem azonos. Ilyenkor érdemes gördítősávokat
hozzáadni a Form-hoz. Ezt a következő módon tehetjük meg:
Form.AutoScroll;
Van ennél egy jobb megoldás is. Állítsuk be a Form1.Scaled;
tulajdonságot. Így a Delphi futás közben lekérdezi a felbontást és ahhoz
arányítja a program méreteit. Ezt az Application.Screen objektum PixelPer
Inch tulajdonságának segítségével teszi, de ilyenkor a Form1.AutoScroll
tulajdonságot FALSE-ra kell állítani. (Érdemes True Type fontokat használni,
hogy az arányítás sikeresen működjön.)
Az alkalmazás fő Form-ját el is tudjuk rejteni úgy, hogy az futás
közben ne jelenjen meg a képernyőn.
Application.ShowMainForm:= false;
32
A Projektekben deklarált ablaktípust meg is tudjuk változtatni. Olyan
Form-ot hozunk létre, amilyet akarunk, csak annak forráskódjába kell kicsit
belenyúlni. Nézzünk egy példát színátmenetes Form létrehozására! (Forrás:
Delphi Cafe)
Procedure TForm1.FormPaint(Sender: TObject);Var x,GradientDistance,GradientWidth : Integer; tmpColor: TColor; NewRed,NewGreen,NewBlue: Integer; EndRed,EndGreen,EndBlue: Integer;Begin If EndColor = clBlack then Exit; tmpColor := EndColor; GradientDistance := Height; // a színátmenet hossza GradientWidth := Width; // szélessége EndRed := GetRValue(EndColor); EndBlue := GetBValue(EndColor); EndGreen := GetGValue(EndColor); For x := 1 to GradientDistance do // az átmenet kiszámítása Begin NewRed := (x*EndRed) div GradientDistance; NewBlue := (x*EndBlue) div GradientDistance; NewGreen := (x*EndGreen) div GradientDistance; tmpColor := RGB(NewRed,NewGreen,NewBlue); Canvas.Pen.Color := tmpColor; //új színek megadása Canvas.MoveTo(0,x); Canvas.LineTo(GradientWidth,x); End;End;
Procedure TForm1.FormCreate(Sender: TObject); Begin EndColor := clBlack; End;End.
A Form-ok használata természetesen nem kötelező. Készíthetünk saját
Form-ot, írhatunk ablak nélküli programokat is.
Az oktatás során vegyük sorra a Delphi gyakorta használt
komponenseit! (A lényegesebbekre részletesen is ki fogok térni.) Magyarázzuk
el a vizuális elemek működését a diákoknak nagyon részletesen, írassunk velük
programokat, hogy a használatukat készség szintre emeljük, mert így a
komolyabb részek tanításánál könnyebb lesz a dolgunk! Minden komponensnél
térjünk ki a lényegesebb metódusokra, s a többihez adjuk meg a megfelelő
súgó oldalakat, vagy javasoljunk könyveket, amiből tovább lehet haladni a
bonyolultabb komponensek irányába!
33
Standard komponensek palettája
5. ábra - A Standard komponens paletta
A Standard tartalmazza a leggyakoribb komponenseket, melyek szinte
minden programban megtalálhatóak.
Mivel ezekből a komponensekből épül fel a legtöbb Delphi-ben
készített program, ismeretük fontos ahhoz, hogy legalább alapszintű
alkalmazásokat tudjunk készíteni.
A leggyakoribb műveleteket valósíthatjuk meg segítségükkel, amik a
Windows használatakor előfordulhatnak: szöveg bevitele, nyomógomb,
hosszabb szövegek kiíratása képernyőre, legördülő listák, jelölő-választó
gombok, menü, gördítősáv. Ilyen funkciók nélkül egy komolyabb Windows
alatt futó program szinte elképzelhetetlen.
A Standard lapon található komponensek a Borland Pascal
rendszerben már szerepeltek, de nem voltak kigyűjtve. Használni csak akkor
tudtuk őket, ha előtte a forráskódban felvettük a komponenseket tartalmazó
Unit-ot, deklaráltuk a mezőket, s hosszas értékadásokat követően a Create
eljárással létrehoztuk őket. Ezt a Delphi-ben is megtehetjük, de lényegesen
egyszerűbb, ha a Komponens Palettáról egyszerűen csak az egérrel a Form-ra
húzzuk azt az elemet, amit használni szeretnénk.
A következő táblázat tartalmazza a Standard komponensek ikonját,
nevét valamint egy rövid leírást.
A komponenseket részletesen is elmagyarázom, majd példákon
keresztül bemutatom azok működését. A táblázat használható referenciaként a
programozás során és segít a kezdők számára felismerni a komponensek
ikonjait. (Az elektronikus változatban a linkek megnyitják az adott
komponenshez tartozó video anyagot. )
34
MainMenu: A Form fő és legördülő menüje 2 3 4 5 6
PopupMenu: Felbukkanó menü, melyet az egér jobb gombja aktivál
Label: Feliratokat tartalmazó címke
Edit: Egysoros szöveg beolvasására alkalmas szövegdoboz
Memo: Többsoros szöveg megjelenítésére alkalmas szövegdoboz
Button: Nyomógomb különböző műveletek végrehajtására. Megállít vagy elindít egy folyamatot.
CheckBox: Ki és bekapcsolható jelölőnégyzet. On/Off funkciók megvalósítására.
RadioButton: Csoporthoz tartozó választó gomb
ListBox: Egy vagy több elem kiválasztását teszi lehetővé a listából
ComboBox: Listadoboz, melyhez új elemeket adhatunk, vagy kiválaszthatunk az elemek közül
ScrollBar: Gördítő sávok megvalósítására szolgáló komponens
GroupBox: Összetartozó elemek csoportosítására szolgál
RadioGroup: A RadioButtonokat foglalja csoportba
Panel: A komponenseket tudjuk csoportosítani vele
TMenu
A Form Legördülő menüje a TMenu komponens. Használatához elég,
ha a Komponens Palettáról a Form-ra húzzuk az egérrel. A menürendszer
létrehozásához kattintsunk kettőt a komponensre, így egy szerkesztőpanelhez
jutunk, amely megmutatja, hogyan fog kinézni a menü.
Kattintsunk az üres Item-ek egyikére, majd az Object Inspector-ban, a
Caption mezőbe írjuk be a menü nevét! Az Enter lenyomása után a Menü
35
Paneljén megjelenik a menü-elem neve. Erre kettőt kattintva az
eseménykezelőt lehet programozni.
6. ábra - A Main Menu komponens létrehozása, menüpontok szerkesztése
Procedure TForm1.Megnyit1Click(Sender: TObject);Begin //Ide kerülnek a menü által elindítandó eseményekEnd;
A panel bezárása után a menürendszer létrejön a Form-on. A Lebegő
(PopUp) menüket is hasonló módon használhatjuk, de meg kell mondanunk,
hogy melyik komponenshez szeretnénk hozzárendelni őket.
Form1.PopUpMenu:=PopUpMenu1;
A PopUp menüt a többi komponenshez hasonlóan az Object Inspector-
ban is hozzáadhatjuk a kívánt komponenshez.
Ha ezt megtettük, akkor a program futtatása közben a Form-on a jobb
egérgomb aktiválja a lebegő menüt úgy, mint ahogy azt a Windows-ban
megszokhattuk, de a PopUp típusú menüknél azt is definiálni kell, hogy a
menü melyik komponens „jobb kattintásánál aktivizálódjon”.
36
Tbutton és Tlabel
Az egyik legalapvetőbb elem a Tbutton (nyomógomb), amely szinte
minden Windows alkalmazásban megtalálható. A gomb lenyomása valamilyen
eseményt indít el. A Tbutton komponens szintén a Standard lapon található.
Tegyünk a Form-ra egy TButton-t és egy Tlabel típusú komponenst,
kattintsunk a Button1-re duplán, majd a megjelenő OnClick eseménybe írjuk a
következőket!
Label1.caption:=’Gomb lenyomva’;
Az Object Inspector-ban keressük meg a Button1 Caption mezőjét, s
írjuk ide azt, hogy „Nyomógomb”. Ha nem fér el a szöveg a gomb felületén,
fogjuk meg az egérrel, húzzuk megfelelő méretűre, vagy az Object Inspector-
ban a With és Height mezőkbe írjuk be a kívánt méretet!
A Tlabel komponens rövid szöveges információ megjelenítésére
alkalmas elem. A Label.Caption mező tartalmazza a szöveget, és példánkban
a gomb lenyomásakor ide ír az eseménykezelő. (A Caption mezője a String
típussal kompatibilis…)
Futtassuk a programot az F9 billentyű lenyomásával, majd próbáljuk ki
munkánk eredményét! (A TButton helyett használhatunk más nyomógomb
típust is, pl.:BitBtn, SpeedButton.)
A nyomógomboknak van más típusa is, mely megtalálható a
komponens palettán: a SpeedButton, ami a Word gyorsbillentyűire hasonlít,
és a BitBtn, amely felületén a szöveg mellett képeket is megjeleníthetünk.
Ezek működése azonos a Button működésével, de a SpeedButtonnak van egy
különleges tulajdonsága: a Flat.
Ez a tulajdonság határozza meg, hogy a gomb beleolvad-e abba az
elembe, amire raktuk (SpeedButton1.Flat:=TRUE;), vagy kiemelkedik annak
felületéből (SpeedButton1.Flat:=FALSE).
37
TEdit
A Tedit komponens szöveg kiírására vagy bevitelére alkalmas. A
Form-ra helyezve rövid szövegeket fogad, melyek a Text nevű mezőjében
tárolódnak. Az értékadást nem csak begépeléssel valósíthatjuk meg: lehetőség
van arra is, hogy a forráskódban adjuk meg a Text tartalmát.
Edit1.Text:=’szoveg’;
Természetesen a bevitt szöveget fel is tudjuk dolgozni, átalakítani, vagy
különböző műveleteket végezni vele, mert a Text mező úgy viselkedik, mint
egy egyszerű String típusú változó.
Ügyelni kell arra, hogy a Név megváltoztatása nem azonos a Text mező
átírásával. A komponens neve a Name mezőben található (ezzel hivatkozunk rá
a forráskódban), a Text mező viszont csak az Edit-be írt szöveget tartalmazza.
(Ezt a hibát más komponenseknél sem szabad elkövetni!)
Nézzünk meg egy egyszerű példát a használatára! A feladat az, hogy az
Edit-be írt számot szorozzuk meg kettővel, majd az eredményt írjuk vissza
úgy, hogy az eredeti szám ne maradjon meg. Tegyünk a Form-ra egy Edit
komponenst és egy Button-t! A Button eseménykezelőjébe írjuk a
következőket:
Procedure TForm1.Button1Click(Sender: TObject);Var n:integer;Begin Try n:=StrToInt(Edit1.Text); n:=n*2; Edit1.Text:=IntToStr(n); Except ShowMessage('Rossz adat'); End;End;
38
Az Text mező tartalmát konvertáljuk numerikus értékké, majd
megszorozzuk kettővel. Az eredményt a visszakonvertálás után az eredeti
helyére, az Edit Text mezőjébe rakjuk. Az Edit másik változata a MaskEdit,
ami a Password-ok beolvasására alkalmas.
TListBox
A Delphi-ben vannak különféle lista típusú elemek, amelyek
legtöbbször String típusú adatok megjelenítésére, tárolására alkalmasak, de a
szöveg mellett más típusok tárolására is találunk megfelelőt. A legismertebbek
a Tlist, a TstringList, és a ListBox, melyek közül az első kettő nem része a
VCL-nek, mivel nem vizuális elemek, így ezeket később ismerjük majd meg.
A TListBox a TStringList-hez hasonlít a leginkább. A lényegi
különbség az, hogy az előző nem vizuális komponens, a Tlistbox viszont az,
ezért megtalálható a Componet Paletta elemei közt.
Ez a komponens stringek tárolására alkalmas, és meg is tudja jeleníteni
őket. Az elemeit Item-nek nevezzük, a használat során is így hivatkozunk
rájuk.
Lista.items[i]:=’szoveg’;
A komponens tartalmazza azokat a metódusokat, melyeket a
Tstringlist-nél láthatunk majd, s ezeken kívül még számos más metódust is,
melyek a lista típusú komponensekre jellemzőek.
A használata olyan esetekben indokolt, amikor a felhasználó számára
nagyobb mennyiségű stringet, szövegrészt, vagy valamely lista elemeit kell
megjeleníteni.
A felhasználó a lista elemei közül válogathat az egérrel vagy a
billentyűzet segítségével, és kijelölhet elemeket további felhasználásra
A lista sorainak betűtípusa külön nem változtatható, csak az összes
elem egyszerre. Igaz, hogy van lehetőség a sorok egyedi stílussal való
rajzolására, de ehhez nekünk kell minden sort kirajzoltatni, s a sormagasságot
is ennek megfelelően kell változtatni.
39
A feladat az, hogy egy tetszőleges szöveges fájl tartalmát olvassuk be
egy Listbox-ba. A Standard komponensek közül válasszuk ki a Listbox-ot,
majd helyezzük azt a Form-ra! Tegyünk mellé egy OpenDialog 2
komponenst! Rakjunk mellé egy nyomógombot (TButton), majd a
nyomógomb eseménykezelőjébe írjuk a következőket:
If OpenDialog1.Execute then Begin try Listbox1.items.LoadFromFile(Opendialog1.Filename); Except Showmessage(’Hiba a file megnyitása közben’); End;End;
Nézzük meg hogyan működik a program! A gomb lenyomása után
megnyílik egy párbeszédpanel, ahol kiválaszthatjuk a beolvasni kívánt fájlt.
Miután jóváhagytuk a megnyitást, az OpenDialog komponens
Filename tulajdonsága tartalmazni fogja a fájl nevét és elérési útját. Ezt adjuk
át a Listbox LoadFromFile metódusának, ami megnyitja azt és beolvassa. A
megnyitást Try Except End; blokkba helyeztem, hogy a megnyitás során
fellépő hibák ne eredményezzék a program leállását.
Mielőtt tovább mennénk, nézzük meg hogyan működnek a Dialog
típusú komponensek!
Dialog boxok
7. ábra - Dalogs fül komponensei
A Dilog Boxok megkönnyítik a Windows-szal való kapcsolattartást és
a fájlok kezelését a Delphi programokból. Az ilyen típusú komponensekre
tekinthetünk úgy, mintha önálló programok lennének, amiket saját
programjainkból indítunk el. Ismerjük meg ezeket példákon keresztül, mert így
a magyarázat is könnyebb és kevésbé terjedelmes!
40
A komponens paletta Dialog „füléről” helyezzünk a Form-ra egy
Opendialog komponenst! Az Object Inspector-ban az InitialDir
tulajdonságban adjunk meg egy erre a célra létrehozott könyvtárat, amiből a
fájlokat szeretnénk megnyitni. Ilyen esetekben a fájl kiválasztó ablak erre a
könyvtárra fog mutatni. Ezután határozzuk meg, milyen típusú fájlokat
szeretnénk látni a könyvtárban. (A többi a program számára „láthatatlan
marad”.) Ezt szintén az Object Inspector-ban tehetjük meg, a Filter
tulajdonság beállításával. Állítsuk a filtert *.txt- re, így csak a txt kiterjesztésű
fájlokat fogja mutatni! Ezután nincs más dolgunk, mint megírni a komponenst
aktivizáló metódust.
Az Opendialog-nak van két fontos tulajdonsága. Az egyik a FileName,
melyben a fájl neve és elérési útja tárolódik, a másik az Execute, amivel a
DialogBox-ot aktivizáljuk.
If OpenDialog1.Execute then S:=OpenDialog1.FileName;End;
Amennyiben ezt az eljárást egy nyomógomb OnClick eseményébe
helyezzük, a nyomógomb lenyomása után egy fájl kiválasztó ablakot kapunk, s
ha annak Megnyit gombját lenyomjuk, a változó tartalma a kiválasztott fájl
neve és elérési útja lesz. A Dialog Boxok jól használhatóak ListBox, Timage
és más, külső fájlokat használó komponensekbe való adatbetöltéshez.
TMemo
A ListBox-hoz nagyon hasonló komponens a TMemo, amely
hasonlóan funkcionál, mint egy egyszerű jegyzettömb: a sorai változtathatóak
egyesével is, és tartozik hozzá egy lebegő menü, melyben a szövegre
vonatkozó blokkműveletek vannak definiálva, de a programozás szempontjából
szinte megegyezik a ListBox-szal.
Az adatok betöltése, mentése, rendezése úgy működik, mint a ListBox-
ban, csak az elemekre való hivatkozásban mutat némi eltérést. Az elemeit nem
41
Item-nek nevezzük, hanem Lines-nek. Tehát a hivatkozás a következőképpen
alakul:
Memo1.Lines[i]:=’szoveg’;
Nézzük meg, hogyan lehet használni a Memo komponenst!
Procedure TForm1.Button1Click(Sender: TObject);Begin Memo1.Lines.LoadFromFile('C:\AUTOEXEC.BAT'); Writeln('Az autoxezec.bat 6.sora ', Memo1.Lines[5]);End;
Az eljárás a Memo-ba tölti az AUTOEXEC.BAT fájl sorait, majd a
hatodik sorhoz megjegyzést fűz. A hatodik sor a 0+5, mivel az elemek nullától
vannak indexelve Count-1-ig. A Memo komponensnek van egy beépített
PopUp menüje, amelyben a Kivágás, Másolás, Törlés, Beillesztés menük el
vannak készítve, így különösebb erőfesztés nélkül használhatjuk rajtuk
keresztül a Windows vágólapját.
RichEdit
A RichEdit komponens hasonlít leginkább egy valódi
szövegszerkesztőre. Működése hasonló a ListBox-hoz és a Memo-hoz.
Különlegessége az, hogy egy soron belül is lehet változtatni a Font stílusát,
méretét, színét, stb. Futás közben az elemek egérrel való kijelölése után
lehetőség van a kijelölt rész azonosítására.
Egy TButton OnClick eseményéhez rendelhetjük a font
megváltoztatásának metódusát. Szükségünk van még egy FontDialog-ra.
Tegyünk a Form-ra egy Tbuttont, egy FontDialogo-ot és egy RichEdit
komponenst!
A megismert módon töltsük egy szöveges állomány tartalmát a
Richedit-be! Az eljárás a következőképpen alakul:
42
Procedure Tform1.Button1Click(Sender:TObject); Begin If RichEdit1.SelLength > 0 then Begin FontDialog1.Font.Assign(RichEdit1.DefAttributes); If FontDialog1.Execute then RichEdit1.SelAttributes.Assign(FontDialog1.Font); End Else Showmessage(’Nincs kijelölt Font’); End;
Futtassuk a programot, jelöljünk ki egy részt a szövegből, majd
nyomjuk le a gombot, melyhez a Font kiválasztását rendeltük! Miután
kiválasztottuk a font típusát, a Dialog lezárása után a RichEdit-ben a kijelölt
rész betűtípusa megváltozik.
Megfigyelhetjük, hogy a Font tulajdonságainak beállítására nem a :=
formulát használtuk, mert ha igen, akkor a Fondialog fontját és a RichEdit
fontját egyenlővé tesszük, vagyis bármelyiket megváltoztatjuk, a másik is
megváltozik. Ezért kell az Assign eljárást használni, mert így csak a típus fog
megegyezni, nem pedig a tényleges objektumok (a RichEdit Font
tuladonságához rendeli a FontDialog-ban kiválasztott font stílusát, méretét,
stb…). (Erre találhatunk utalást az Objektum Hivatkozási Modelleknél vagy a
Help-ben.)
Magyarázatra szorul még a RichEdit1.SelLength > 0 rész. Itt azt
vizsgáljuk, hogy lett-e kijelölve szövegrész. Amennyiben igen, a SelLength
tulajdonság értéke nagyobb 0-nál, ellenkező esetben 0.
Az else ág tartalmaz egy függvényhívást. A ShowMessage();
függvénnyel szöveges információt jeleníthetünk meg a képernyőn egy kis
ablakban, amihez tartozik még egy Ok feliratú gomb, mely bezárja az ablakot.
Ez a függvény jól használható hibaüzenetek megjelenítésére. (Van erre
egy jobb megoldás, ami a program méretét jelentősen csökkentheti:
használhatunk MessagBox-ot is, így a Messages Unit kihagyható.)
43
Tpanel
A panelekkel a programjaink külsejét tehetjük esztétikusabbá, de
alkalmasak különböző elemek csoportba foglalására, vagy a képernyő részekre
osztására is. Három fajtát találhatunk a Komponens Paletta Standard lapján.
GroupBox, RadioGroupPanel.
A GroupBox és a RadioGroup csoportosításra használható, a Panel
inkább a program ablakának felosztására, az elemek elrendezésére. A Panelek
tetszőlegesen méretezhetőek, alakíthatóak.
A Form-ra érdemes legalább egyet rakni, az Align tulajdonságát
alClient-re állítani. Így a többi komponens nem a Form-on foglal helyet,
hanem a panelen, s ha változtatni kívánjuk az elemek tulajdonságát, elég csak a
Panel tulajdonságait megváltoztatni, a Panel a „szülője” az összes ráhelyezett
komponensnek, így azok némely tulajdonsága is változni fog.
Próbáljuk ki, hogyan változnak a Panel-en lévő komponensek
tulajdonságai, ha a Panel tulajdonságait megváltoztatjuk! Tegyünk a Form-ra
egy Panelt, majd arra egy másik Panelt! Az elsőnek a Font-ját állítsuk
félkövérre, a Font színét pedig zöldre. Ha bezárjuk a font-beállító ablakot,
mindkét Panel betűtípusa megváltozik, mert a második Panelé örökli a szülője
(Owner) tulajdonságait. Ez minden komponens esetében így működik, ha
viszont a második Panel tulajdonságait változtatjuk meg, az Owner-Panel
tulajdonságai nem változnak, mivel a tulajdonságok öröklése a „szülőtől” a
„leszármazottai” felé működik, visszafelé viszont hatástalan.
A RadioGroup is igen hasznos komponens, mivel a programban
használható RadiButton-ok minden esetben egy csoportot alkotnak, s közülük
csak egy választható ki. Ha több csoportot szeretnénk képezni belőlük, az
egyes csoportokat RadiGroup-ra kell helyeznünk, így a csoportokon belül
érvényesül az a szabály, hogy csak egyet választhatunk. A komponens Caption
mezőjében nevet is adhatunk az egyes csoportoknak. Tegyünk a Form-ra két
44
RadioGroup komponenst. Az Object Inspector-ban a Strings tulajdonságban
vegyünk fel két RadioButtont (csak a nevet kell beírnunk és az elemek
automatikusan létrejönnek):
8. ábra - A RadioGroup elemeinek szerkesztése
Futtassuk a programot! Láthatjuk, hogy így a két csoport elemei külön-
külön is aktivizálhatóak, mert nem egy, hanem két csoportban szerepelnek a
Form-on.
9. ábra - A RadioGroup elemei
45
A GroupBox is hasonló funkciókat lát el. Segítségével csoportosíthatunk
különböző elemeket, de itt inkább az esztétikai szempontok játszanak nagyobb
szerepet. (Figyelem! Amennyiben a RadioGroupra csak ráhúzzuk az egérrel a
RadioButton-okat, azok nem lesznek részei a csoportnak, attól függetlenül
működnek…)
Kevésbé ismert komponensek
TStringList
Vannak a Delphi rendszerben olyan elemek, melyek nem közismertek,
de nagyon fontosak és megkönnyítik a munkát. Nem vizuálisak, vagyis
nincsenek rajta a Komponens Palettán, talán ezért nem is olyan közismertek.
Ide tartozik a TstringList, a Tlist, az IniFile kezelés, s még van jó néhány,
melyekre a későbbiekben ki fogok térni.
Kezdjük is el! Elsőként a TstringList-tel szeretnék foglalkozni, mert a
Text típusú fájlok használatánál elengedhetetlen az ismerete. Ez a komponens
tekinthető egy dinamikus listának, melyben String típusú elemek tárolódnak.
A különböző műveletek elvégzése a listán igen egyszerű, mert az
elemei indexelve vannak, s a listán végezhető műveletek is előre definiáltak.
A TstringList-et legjobban egy tömb példáján keresztül lehet
megérteni. Tekintsünk úgy rá, mintha egy stringeket tartalmazó tömböt
deklaráltunk volna, s a tömbhöz lennének előre megírt eljárásaink!
Két nagyon fontos eljárás a LoadFromFile és a SaveToFile Ezek
segítségével lehet a listába betölteni egy fájl tartalmát, majd később kimenteni
azt a fájlba.
Működése nagyon egyszerű, csak arra kell ügyelni, hogy a műveletet
lehetőség szerint vagy egy Try except end; vagy egy Try finally end;
blokkba tegyük, mert ha az elérési út nem létezik, a programunk I/O hibával le
fog állni.
A betöltés és a mentés művelete a következőképpen alakul:
46
Var T:TStringList;…Try T.LoadFromFile (’c:\szoveg.ttxt’);Except ShowMessage(’I/O hiba’);End;
A szöveg kimentése hasonlóan történik:
T.SaveToFile (’c:\szoveg.txt’);
Az Except utáni részben történhetnek meg az esetleges hibajavítások.
Miután megvagyunk a betöltéssel, a lista elemei úgy viselkednek, ahogy azt a
tömböknél megszokhattuk. Az elemekre több módon lehet hivatkozni. Abban
az esetben, ha írni szeretnénk valamely elemet, elég csak annyit mondanunk a
rendszernek, hogy T[i]:=’szoveg’;. Ezáltal az i-edik elem tartalma a ‘szoveg’
lesz (a T.Add(S:string); hivatkozás is használható).
Az elemek indexelésének van egy fontos szabálya! A Lista 0-tól
Count-1-ig van indexelve. Ez azt jelenti, hogy az első elem a 0, az utolsó elem
az elemszám-1. Ha egy ciklussal végig akarjuk járni őket, akkor a következőt
kell tennünk:
For i:=1 to T.Count-1 doBegin T[i] // Az aktuális elem feldolgozásaEnd;
Az elemeket lehet rendezni a T. Sort nevű eljárás segítségével, vagy a
T.AutoSort nevű tulajdonság TRUE értékre állításával (ebben az esetben a
komponens kicsit lassabban működik, mivel minden értékadás után rendezi az
elemeket…), és a lista tartalmát lehet törölni a T.Clear eljárással.
A komponens működése nem bonyolult, a használatát működés közben
lehet leginkább elsajátítani.
47
TList
A TStringList-hez nagyon hasonló szerkezetű komponens a TList. Ez
is egy lista adatszerkezet, de ennek elemei Pointerek (mutatók), (valójában
Object típusúak, így minden típus megadható – persze itt is vannak kivételek…)
melyekkel bármilyen komponensre vagy változóra hivatkozhatunk.
Tárolhatunk benne különböző adatokat, rekordokat, tömböket, akár más
komponenseket is.
Használata nagyon rugalmas, de a kezelése nem túl egyszerű, mivel az
elemeit közvetlenül nem írhatjuk. Mielőtt változtatni szeretnénk egy elem
tartalmán, ki kell azt venni egy struktúrájában megegyező változóba, s annak a
mezőit kell változtatni, majd ezt a változót kell visszatenni a listába.
A bonyolultsága ellenére igen jól használható komponens, bátran
merem ajánlani mind kezdő, mind pedig haladó programozók számára.
Inifájlok kezelése
Fontosnak tartom megemlíteni, hogy a Delphi rendszer lehetőséget ad
az Ini fájlok kezelésére. Az IniFiles Unit definiálja a kezelésükhöz szükséges
eljárásokat.
Nézzük meg egy példán keresztül, hogyan kell használni őket!
Uses IniFiles;Var T:TiniFile;…Procedure Tform1.CreateIniFile(Name:string);Begin T:=Tinifile.Create(’Name’);End;
48
Ezzel létre is hoztuk az üres fájlt, melybe azután bármikor írhatunk
adatokat. A használat után le kell zárni (T.Free;), de ezt jó esetben a rendszer
megteszi helyettünk.
A fájlba való írás a következő metódusok egyikével történik aszerint,
hogy milyen típusú adatot kívánunk írni az adott szekcióba.
T.WriteInteger(’szekció’,’változónév’,10);T.WriteString(’ ’szekció’,’változónév’,’szöveg’);T.WriteBool(’ ’szekció’,’változónév’,TRUE);
A legtöbb egyszerű típushoz van megfelelő eljárás, de a különböző
típusoknak inkább a beolvasásnál van jelentősége, mert a file Text típusként
van tárolva a háttértárakon és a megfelelő beolvasó eljárás konvertálja azt a
kívánt típussá.
Mint látható, az eljárásoknak több paramétere is van. Ez az Ini fájlok
szerkezetéből adódik. Az ilyen típusú fájlok szekciókra vannak osztva, egy
szekción belül találhatóak az adatok nevei és a tényleges tartalmuk. Nézzünk
egy példát!
[kepek] kep1=’c:\pictures\felho.bmp’ x=640 y=480
[szoveg] file=’c:\felho.txt’ elemszam=128
Amennyiben a fájlból ki szeretnénk olvasni a kép adatait, a következőt kell
tennünk:
Var kep:string; x,y:integer;Begin Kep:=T.ReadString(‘kepek’,’kep1’,’c:\pictures\default.bmp’); x:=T.ReadString(‘kepek’,’x’,0); y:=T.ReadString(‘kepek’,’y’,0);End;
49
Az eljárások harmadik paramétere egy default érték arra az esetre, ha
az olvasás művelete nem sikerülne. (Az Inifájlokban használt változó neveknek
nem kell megegyeznie a programban használt névvel egyik paraméter esetében
sem.) Ilyenkor az itt megadott érték kerül a változóba. Hogy miért van erre
szükség, arra könnyű rájönni. A program vár egy értéket, amivel a
későbbiekben dolgozni szeretne, s ha nem kapja meg, akkor hibásan fog
működni. Ezt elkerülendő alkalmazzuk a Default értéket.
Az Ini fájlok szerepe nagyon fontos olyan programoknál, ahol a kezdeti
értékeket el kell tárolni, vagy éppen a program paramétereit a felhasználó
állítja be és a következő indításnál ezen beállításokkal kell működtetni a
programot.
Az Ini fájlok kezelését nem fontos kivételkezelő blokkba tenni, de nem
árthat, ha a programunk védett a hibákkal szemben.
A használat után meg kell mondani a rendszernek, hogy zárja be a fájlt,
amit a következő eljárás segítségével meg is tehetünk: T.Free;. Ez az utasítás
lezárja, és a program számára láthatatlanná teszi a fájlt.
A következő eljárás bemutatja a fent említett komponensek használatát
egy egyszerű példán keresztül. Egy Inifájlból beolvassuk egy textfájl nevét (az
elérési útjával együtt), majd megnyitjuk a fájlt és beolvassuk egy TstringList-
be a tartalmát.
Procedure pelda;Var T:TstingList; I:TIniFile; S:string;Begin Try I:=TinIfile.Create(’c:\dat.ini’); T:=TstringList.Create; S:=TinIfile.readstring(’fileok’,’szovegfile1’,’c:\default.txt’); T.LoadFromFile(s); Except //Hibakezelés End; //A fájl tartalmának feldolgozása T.free; I.free;End;
50
DLL-ek használata
A Dinamikusan Szerkesztett Könyvtárak (DLL) használata számos
előnnyel jár. Különböző programok használhatják ugyanazt a DLL-t, s így az
alkalmazások memóriaigénye nagymértékben csökken. Kódjuk csak egyszer
töltődik be a memóriába, de a függvényeiket bármely program szabadon
használhatja.
A DLL-eket cserélni lehet, csak arra kell ügyelni, hogy a függvények,
eljárások fejlécei megegyezzenek. Bizonyos szabályok betartása mellett az sem
lényeges, hogy a DLL milyen programozási nyelvben készült.
A Delphi programok tudják használni a C vagy a C++ nyelven írt DLL-
eket, és fordítva is működik a dolog.
A DLL készítés szabályai
Egy DLL függvény akkor használható más programokban, ha szerepel
a DLL Export listájában. A függvényeket a Delphi-ben StdCall-ként is
deklarálni kell, ha azokat egy másik fejlesztői eszközben szeretnénk használni,
vagy a Delphi-ben akarunk más eszközökkel készített DLL-t használni. Ezzel
állítjuk be, hogy a szabvány Win32 paraméterátadást használja a program.
Meglévő DLL-ek használata: az Interface részben deklarálni kell a
függvényeket.
Function Dll_fuggveny_1(parameterek:tipus):fuggvenytipus; StdCall;
Function Dll_fuggveny_2(parameterek:tipus):fuggvenytipus; StdCall;
Az Implementation részben a kifejtett kód helyett a DLL-ben lévő
külső definícióra hivatkozunk.
Function Dll_fuggveny_1; StdCall; external ’Dll_fuggveny_1’;
Function Dll_fuggveny_2; StdCall; external ’Dll_fuggveny_2’;
Hozzunk létre saját DLL-t Delphi-ben!
51
A File menü New parancsánál ne a Project, hanem a DLL ikonját
válasszuk. Így létrejön egy egyszerű forrásfájl, amibe már csak a megfelelő
eljárásokat kell beleírnunk.
10. ábra - DLL file felépítése
Írjunk egy függvényt, mely konkatenál két stringet, majd az eredményt
visszaadja!
Function Concat_(s1,s2:string):string; StdCall;Begin Concat_:=s1+s2;End;
A DLL-be fel kell venni egy Export nevű részt, ami a kapcsolattartásért
felelős.
Export Concat_;BeginEnd;
A Begin és az End közé nem is kell semmit írnunk.
A DLL meghívása a Delphi programban a következőképpen alakul:
Interface Function Concat_(s1,s2:string):string; StdCall; External ’Projekt2.dll’;
52
Ezután a függvényt már úgy használhatjuk, mintha az a programunkban lenne
deklarálva és kifejtve.
Procedure TForm1.Button1Click(Sender: TObject);Var S:string;Begin S:=ConCat(’szoveg_1’,’szoveg_2’);End;
Ez a példa így önmagában nem túlságosan hasznos, de arra mindenképp
elegendő, hogy bemutassa a DLL-ek működését. Ha komolyabb programokat
írunk, vagy felhasználók számára készítünk alkalmazásokat, akkor előbb-utóbb
szembekerülünk azzal, hogy programunk elavul, egyes részeit cserélni kell. A
DLL-ek használatával elég csak a megfelelő DLL fájlt lecserélni, és a program
forráskódjához hozzá sem kell nyúlnunk. (A DLL fájlokat egyszere több
program is használhatja.)
A DLL-ek tanításánál ügyelni kell arra, hogy magyarázzuk el a
diákoknak, miért jó a DLL-eket használni, de vigyázzunk, hogy ne vigyék
túlzásba a fájltipus alkalmazását. Sok esetben elegendő egy Unit megírása is.
A Delphi grafikája
A Windows-ban a grafikus megjelenítést egy alprogram rendszer végzi,
a GDI. (Graphics Device Interface). A grafikus perifériákat az
eszközvezérlőkön keresztül éri el.
A grafikus elemek a Delphi-ben három módon készíthetők el.
Szerkesztési időben beillesztjük a képet, grafikus objektumot.
Grafikus vezérlők használatával, programozással.
Létrehozhatunk ábrákat futási időben, rajzoló eljárásokkal.
A legfontosabb grafikus objektumok a Timage (kép), és a TBitMap.
(Ide sorolhatjuk szinte az összes komponenst a komponens palettáról, mivel
mindegyikük grafikus felülettel rendelkezik, amit a rendszer rajzol a
képernyőre.)
53
Képek megjelenítése
11. ábra - Az Additional fül komponensei
A Delphi grafikája számos lehetőséggel rendelkezik, melyek
alkalmassá teszik arra, hogy a kornak megfelelő grafikus programokat
készítsünk. Lehetőség van képek betöltésére, grafikus vezérlők
programozására, de akár OpenGL, vagy Direct3D alkalmazásokat is
készíthetünk vele. A grafika elsajátításához gyakorlatra van szükség, ezért
kezdjük mi is egy példával!
Tegyük a Form-ra az Additional lapon található Image komponenst,
és a Dialogs lapról egy OpenDialog-ot! Az Image komponens valójában egy
rajzvászon (az Image egyik része a Canvas, vagyis a rajzvászon…), melyre
rajzolhatunk, képeket tölthetünk be a megfelelő metódusok segítségével, vagy
szöveget írhatunk rá. A Picture tulajdonsága határozza meg, hogy mi az, ami
látható a képen.
A következő kódsor betölt egy képet az Image-be, majd annak Strech
tulajdonságát TRUE-ra állítja, hogy a betöltött kép teljes méretében lefedje a
rajzvásznat (Canvas):
Procedure Betölt;Begin Try If OpenDialog1.Execute then Begin Image1.Picture.LoadFromFile(OpenDialog1.FileName); Image1.Strech:=True; End; Except ShowMessage(’I/O hiba’); End;End;
Rajzolás a Canvas segítségével. A Canvas-ra rajzolhatunk, írhatunk,
vagy különböző grafikus objektumokat rendelhetünk hozzá. A Canvas
képpontokra van osztva, hasonlóan, mint a Turbo Pascal grafikus módjában a
54
képernyő. Az egyes pixelek színét a Pixels (TColor) tulajdonsággal állíthatjuk
be.
A TPen tulajdonsággal állíthatjuk be a vonalhúzás tulajdonságait. A
Pen maga is egy objektum. Legfontosabb jellemzői a Color tulajdonság, a
Mode, mellyel a vonalhúzás mintázatát állíthatjuk, és a Style, ami a húzott
vonal típusát állítja be.
A húzott vonal vastagságát a Width tulajdonság definiálja. A Pen
objektumnak saját metódusai vannak a tulajdonságok beállítására vagy
lekérdezésére (SetColor, GetColor, SetStyle, GetStyle, SetWidth, GetWidth,
SetMode.) Az Aktuális toll pozíciót a PenPos tulajdonság adja vissza.
A Windows modulban definiáltak egy TPoint típusú objektumot, mely
egy képpont tulajdonságát írja le. (Ez használható pl.: a Polygon-ok
kirajzoltatására).
A rajzvászon kifestésére is van lehetőség. A színezést a Brush
objektum végzi. A TBrush-nak is van Color, Style, Mode tulajdonsága, de
ezek mellett BitMap kirajzolására is alkalmas. Fontos metódusa a Canvas-nak
az Assign, amivel képeket rendelhetünk a vászonhoz, és a Draw eljárás,
mellyel festeni tudunk előre definiált képeket.
Amennyiben nem töltünk képet az Image-be, annak szélességét meg
kell határoznunk. Ezt a Width és a Height (magasság) tulajdonságokkal
tehetjük meg, vagy egy, a rendszer által definiált rekorddal, a TRect-tel
állíthatjuk be a kívánt méretet.
A Canvas-ra írni a TextOut eljárással kell, melynek bemenő
paraméterei között szintén szerepelhet a TRect típus. A Turbo Pascal
rendszerben megszokott eljárásokat is használhatjuk. (Line(),
Rectangle(),Circle(), LineTo(), stb. eljárások változtak, de a Delphi rendszer
help-je mindegyiket példákon keresztül elmagyarázza.)
Nézzünk néhány példát a fentiekre!
Hogyan lehet a Canvas-ra rajzolni egy Ellipszist? Rakjunk a Form-ra egy
Timage és egy TButton komponenst. A Button OnClick eseményébe írjuk a
következőket:
Procedure TForm1.Button1Click(Sender: TObject);Begin With Image1 do
55
Begin Canvas.Brush.Color := clRed; //a rajzoló szín vörös Canvas.Brush.Style := bsDiagCross; //ferde kockás vonalazással rajzolunk Canvas.Ellipse(0, 0, Image1.Width, Image1.Height); End;End;
A következő eljárás azt szemlélteti, hogyan lehet használni a Canvas Pixels
tulajdonságát.
Procedure TForm1.Button1Click(Sender: TObject);Var W: Word;Begin For W := 10 to 200 do Canvas.Pixels[W, 10] := clRed;End;
A Következő eljárás létrehoz egy BitMap komponenst, majd direkt
módon a ScanLine eljárás segítségével beolvassa a BitMap tartalmát a
Form.Canvas-ra.
Procedure TForm1.Button1Click(Sender: TObject);Var x,y : Integer; BitMap : TBitMap; P : PByteArray; //A SysUtils-ban deklarált dinamikus memória tömbBegin BitMap := TBitMap.create; Try BitMap.LoadFromFile('..\Images\Splash\256color\factory.bmp'); For y := 0 to BitMap.height -1 do Begin P := BitMap.ScanLine[y]; for x := 0 to BitMap.width -1 do P[x] := y; End; Canvas.draw(0,0,BitMap); Finally BitMap.free; End;End;
A Delphi grafikáját kihagyva használhatjuk a Windows grafikus
elemeit is, vagy akár a grafikus kártyák által nyújtott lehetőségeket is
kihasználhatjuk (OpenGl, Direct3D). (A 3D kártyákkal ebben a dolgozatban
56
nem szeretnék foglalkozni, de az Interneten hozzáférhetővé tettem
forráskódokat, magyarázatokat.) Nézzünk meg egy példát a WinApi
használatára! A példa a GetDC(0) Windows API függvény által visszaadott
DC-t használva a WinAPI rajzoló funkciókkal a Windows asztalra rajzol egy
ferde fekete vonalat. (Saját vonalhúzó eljárásokat is definiálhatunk… majd
ezeket úgy használhatjuk a programjainkban, mint a Delphi Line() metódusát.)
procedure TForm1.Button1Click(Sender: TObject);var dc : hdc;Begin dc := GetDc(0); MoveToEx(Dc, 0, 0, nil); LineTo(Dc, 300, 300); ReleaseDc(0, Dc);End;
DC (Device Context) - Kapcsolat egy Windows alkalmazás, egy
eszközmeghajtó (driver) és egy kimeneti eszköz (pl. képernyő) között.
Function GetDC(Wnd: HWnd): HDC;
- visszaadja egy megadott ablak kliensterületére vonatkozó DC kezelőjét.
Function ReleaseDC(Wnd: HWnd; DC: HDC): Integer;
- felszabadítja az adott DC-t, hogy azt más alkalmazások is
használhassák.
Function MoveToEx(DC: HDC; nX, nY: Integer; Point: PPoint): Bool;
- az aktuális pozíciót az x és y paraméterekben megadott pontra helyezi.
Function LineTo(DC: HDC; X, Y: Integer): Bool;
- az aktuális pozíciótól a megadott pontig egy vonalat húz és az aktuális
pozíciót paraméterben megadott koordinátákra állítja.
Adatbázis kezelési alapok
Az adatbázisok kezelése Delphi programokból könnyen tanítható,
egyszerűen elsajátítható, mivel léteznek vizuális komponensek a táblákhoz
való hozzáféréshez és a megjelenítéshez. A fejezetben egy példán keresztül
57
mutatom be, hogyan lehet a Delphi demo adatbázisának tábláihoz hozzáférni,
és a Form-on megjeleníteni az adatokat.
Kérjünk a NewItem varázslóban egy új, üres Application-t! Tegyünk a
megjelenő Form felületére a DataAces fülről egy DataSource1 komponenst,
majd a BDE fülről egy Table1, és a DataControlls fülről egy DBGrid1 és egy
DBNavigator1 komponenst! Ezek az elemek szükségesek az adatbázis kezelő
alkalmazásunkhoz.
A DataSource1 az erőforrásokat kezeli, és ez a komponens fogja össze
a többit. A Table1 komponensből olvashatjuk ki az adatokat vagy írhatunk a
táblába, tehát a programunkban ezt a komponenst úgy tekinthetjük, mintha az
adatbázis táblát közvetlenül kezelnénk. A DBGrid1 jeleníti meg az
adatrekordokat, és a DBNavigator1 segítségével adhajuk ki az adatbázis
műveleteket.
A Table1 komponens tulajdonságai között állítsuk be a DatabaseName
résznél azt az adatbázist, amit használni szeretnénk. Ez most legyen a Delphi
által felkínált adatbázisok közül a DBDEMOS!
Következő lépésként keressük meg a TableName tulajdonságot, és
válasszuk ki a biolife nevű táblát. Méghozzá azért, mert ez fel van töltve
adatokkal, így megkönnyíti a munkánkat. (Saját adatbázisokat, táblákat és a
hozzájuk tartozó ALIAS-okat a Tools menüben található DatabaseDesktop
segédprogrammal készíthetünk.)
Ha mindezekkel végeztünk, a Table1 Active tulajdonságát állítsuk
TRUE-ra!
Keressük meg a Form-on a DataSource1 komponenst, majd a DataSet
tulajdonságánál állítsuk be a Table1 komponenst.
A DBGrid1 és a DBNavigator1 komponensek esetén csak a
DataSource tulajdonságot kell beállítani úgy, hogy az mindkét komponens
esetén a DataSource1-re mutasson.
58
12. ábra - Adatbázis kezelő modul
Nyomjuk le az F9 billentyűt, majd a futó projekben próbáljuk ki az
alkalmazást! Láthatjuk, hogy az adatbázis táblát könnyedén írhatjuk,
olvashatjuk.
Az adatbázisok kezelése természetesen nem ilyen egyszerű.
Bonyolultabb programok esetén a vizuális felület nemhogy megkönnyíti,
hanem inkább megnehezíti a dolgunkat azzal, hogy az alacsony szintű
adatbázis műveleteket elfedi előlünk. A példa viszont mindenképpen jó arra,
hogy megtanuljuk az adatbázis kezelő programok készítésének alapvető
lépéseit, s ismét képet kapjunk a vizuális felület előnyeiről és hátrányairól. (A
video anyagok között van egy, mely az adatbázis kezeléssel foglalkozik és
bemutatja a fenti program készítésének lépéseit)
Nyomtatás Delphi programokból
A TPrinter, előre definiált objektum segítségével tetszőleges
nyomtatóra tudunk nyomtatni. Ez a komponens nincs rajta a komponens
palettán, de használatához nem kell mást tenni, csak meghívni a megfelelő
metódusait.
A TPrinter osztálynak van egy Canvas tulajdonsága, mely ugyanúgy
kezelhető, mint a grafikus objektumok esetében. A Font tulajdonságot
beállíthatjuk, s az eszköz-leírót a Handle tulajdonsággal kérdezhetjük le. A
papírméretről a PageHeight és a PageWidth tulajdonság szolgáltat
információt.
59
A nyomtatást a BeginDoc és az EndDoc függvényekkel
kezdeményezhetjük és bármikor új oldalt lehet kérni a NewPage függvénnyel.
Nyomtassuk ki egy bmp kép tartalmát. Ezt a következő módon tehetjük meg:
Procedure TForm1.Button1Click(Sender: TObject);Var Bmp: TBitmap;Begin Bmp := TBitmap.Create; Try If OpenDialog1.Execute then Bmp.LoadFromFile('OpenDialog1.FileName'); With Printer do Begin BeginDoc; Canvas.Draw((PageWidth - Bmp.Width) div 2, (PageHeight - Bmp.Height) div 2, Bmp); EndDoc; End; Finally Bmp.Free; End;End;
A nyomtatás megszakítására is van lehetőség:
Procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);Beginif (Key=VK_ESCAPE) and Printer.Printing then Begin Printer.Abort; MessageDlg('Printing aborted', mtInformation, [mbOK],0); End;End;
Miután lenyomtuk az Esc billentyűt, és a nyomtatás folyamatban volt, a
Printer.Abort; függvény megszakítja azt, majd egy MessageBox segítségével
közli ezt a felhasználóval. Így, vagy hasonló módon bármilyen nyomtatási
funkciót meg tudunk valósítani.
A nyomtatás menetének megtanítása a diákokkal segíthet a hardver
megismerésében is.
A programok magyarázata közben ki lehet térni az egyes hardver
elemek bemutatására. El lehet magyarázni a nyomtató működését, a
60
számítógép és a nyomtató közti kapcsolattartás módjait, és a folyamatot, ami a
nyomtatás gomb leütése és a nyomtatott szöveg között van.
Internetes és hálózati alkalmazások
13. ábra - Az Internet fül komponensei
A hálózati programozás egyre inkább előtérbe kerül a széleskörű
otthoni Internet felhasználás terjedésével. Az iskolákban mára már szinte
mindenhol van Internet hozzáférés, s egyre inkább szükség van az olcsó, de jól
használható programokra, valamint az ilyen programok készítőire.
A Delphi rendelkezik hálózati programozásra alkalmas
komponensekkel. Használhatjuk a Delphi programjainkban az Internet
Explorert, vagy más böngészőt, készíthetünk Client Server programokat, de
akár saját böngészőt is írhatunk.
Táblázatba foglaltam a legfontosabbakat (nem teljes, de jól használható
referenciaként a programozás során).
Az Internetes programozás manapság még nem sok iskola
tananyagában szerepel, de a fejlődés előbb-utóbb magával hozza e tudás
szükségességét, ezen kívül érdekes téma lehet az órákon.
A Delphi oktatása során érdemes legalább alapjaiban megtanítani az
alapvető elemeket. Jó, ha hálózati ismeretekkel már rendelkeznek a diákok, de
ez nem feltétlenül szükséges.
Ha nincs előzetes tudásuk, a programok írása közben kell elmagyarázni
a hálózati ismeretanyagot.
Ezzel a tecnikával érdekesebbé tehetjük mindkét anyag tanítását. Ha a
diákok az egyik tantárgyat kedvelik, az motiválhatja őket a munkára, s így a
másik tárgy megismerését is lehetőségnek és nem kötelességnek érezhetik.
Azt a tanár feladata eldönteni, hogy mennyit ad át ebből a programozási
fajtából, ám legtöbbször az idő és a tananyag mérete is befolyásolja azt, hogy
mit lehet, és mit kell megtanítani. Semmiképp ne helyezzük csak az Internetre
61
a hangsúlyt, de legyen benne a tananyagban! Az a tapasztalatom, hogy a
diákok szeretik tanulni ezt a részt, érdekli őket az Internet, annak lehetőségei.
ClientSocket: Kapcsolatot épít a kiszolgáló (szerver) számítógéppel
ServerSocket: Válaszol az ügyfél számítógép (kliens) kéréseire.
WebDispacher: Az adatmodulokat Web adatmodullá alakítja.
PageProducer: A HTML sablont alakítja HTML stringgé.
NMDayTime: Időszervertől dátumot, időt fogad.
NMEcho: Az Internet Visszhang Szervernek küld üzenetet és fogad.
NMFinger: A Finger szerverről kér felhasználói információkat.
NMFtp: File Transfer Protokolhoz ad hozzáférést.
NMHTTP: Böngészés nélküli http hozzáférést biztosít.
NMMsg: ASCII szöveget küld a TCP/IP protokol segítségével.
NMPOP3: A postát a POP3 protokol segítségével éri el.
NMSMTP: A postázóhoz fér hozzá az SMTP protokol segítségével.
NMGeneralServer: Többszálú Internet szerverek fejlesztését teszi lehetővé.
A fenti komponensek használata nélkül is tudunk Internetes, vagy
hálózati programokat készíteni. Generálhatunk HTML oldalakat, elindíthatjuk
a böngésző programot.
Ha meg akarjuk tudni, csatlakoztatva van-e a gépünk az Internethez,
használhatjuk a TCP komponenst. Amennyiben a visszaadott IP cím 0.0.0.0, a
gép nem csatlakozik, minden más esetben igen.
Procedure TForm1.Button1Click(Sender: TObject);Begin
62
If TCP1.LocalIp = '0.0.0.0' then ShowMessage('Nincs kapcsolat!');End;
Létrehozhatunk Internetes linket és meg is nyithatjuk. (Használnunk
kell a ShellApi unitot.) Tegyünk a Form-ra egy TLabel komponenst! Állítsuk
a Font.Style tulajdonságát FsUnderline-ra a Cursort pedig HandPoint-ra! Az
OnClick eseménybe írjuk a következőket:
ShellExecute(Handle,'open', 'http://www.yahoo.com' ,'','', SW_SHOWMAXIMIZED);
E-mail címre is hivatkozhatunk:
ShellExecute(Handle,'open', 'mailto:[email protected]' ,'','', SW_SHOWNORMAL);
A számítógép hardverének programozása
Az ebben a részben szereplő eljárások, függvények nem tartoznak
szorosan a témánkhoz, de hasznosak lehetnek.
A Delphi rendszer alkalmas a hardver elemek programozására is.
Hozzáférést biztosít a háttértárakhoz, a perifériákhoz, a processzorhoz.
Nézzük meg, hogyan lehet a Floppy lemezt formázni egy egyszerű rutin
segítségével!
A Shell32.dll fájlban van API függvény, mely a dokumentációkban
nem szerepel, az Interneten viszont lehet találni utalásokat (én is így jutottam
hozzá). Ez megnyitja az a:\ meghajtót formázó ablakot. Ezt fogjuk használni.
Implementation{$R *.DFM}Const SHFMT_ID_DEFAULT = $FFFF; SHFMT_OPT_QUICKFORMAT = $0000; SHFMT_OPT_FULL = $0001; SHFMT_OPT_SYSONLY = $0002; // Hiba kódok SHFMT_ERROR = $FFFFFFFF; SHFMT_CANCEL = $FFFFFFFE; SHFMT_NOFORMAT = $FFFFFFFD;
63
Function SHFormatDrive(Handle:HWND; Drive, ID, Options:Word): LongInt; StdCall; External 'shell32.dll' Name 'SHFormatDrive'
Procedure TForm1.btnFormatDiskClick(Sender : TObject);Var retCode: LongInt;Begin retCode:= SHFormatDrive(Handle, 0, SHFMT_ID_DEFAULT, SHFMT_OPT_QUICKFORMAT); If retCode < 0 then ShowMessage('A formázás nem sikerült');End;
Megjeleníthetjük a processzor aktuális sebességét az alábbi rutin
segítségével: A forrást a Computer Solutions-ban találtam (a
dokumentációban erre sem találtam hivatkozást).
Function TForm1.GetCpuSpeed: Extended;Var t: DWORD; mhi, mlo, nhi, nlo: DWORD; t0, t1, chi, clo, shr32: Comp;Begin shr32 := 65536; shr32 := shr32 * 65536; t := GetTickCount; While t = GetTickCount do Begin End; asm DB 0FH DB 031H mov mhi,edx mov mlo,eax end;
While GetTickCount < (t + 1000) do Begin End; asm DB 0FH DB 031H mov nhi,edx mov nlo,eax End; chi := mhi; if mhi < 0 then chi := chi + shr32; clo := mlo; if mlo < 0 then clo := clo + shr32; t0 := chi * shr32 + clo;
64
chi := nhi; if nhi < 0 then chi := chi + shr32; clo := nlo; if nlo < 0 then clo := clo + shr32; t1 := chi * shr32 + clo; Result := (t1 - t0) / 1E6;End;
Procedure TForm1.Button1Click(Sender: TObject);Begin label1.Caption := FloatToStr(GetCpuSpeed) + ' mhz';End;
A program lekérdezi a processzor sebességét, majd megjeleníti azt egy
Tlabel komponens Caption mezőjében.
Egy program memóriaigényének csökkentésére is találtam egy
hatékony függvényt a www.preview.org weboldalon.
FreeLibrary(GetModuleHandle('OleAut32'));
A program így nem használja az OLE-t (Object Linking and
Embedding). Felszabadítja a hozzá szükséges DLL-eket, (OleAut32.dll,
OLE32.dll), és az alkalmazás így közel 1MB-tal kevesebb memóriát használ.
A monitor kikapcsolása a következő metódussal valósítható meg:
SendMessage(Application.Handle, WM_SYSCOMMAND, SC_MONITORPOWER, 0);
Bekapcsolni hasonlóképp lehet:
SendMessage(Application.Handle, WM_SYSCOMMAND, SC_MONITORPOWER, -1);
Mint láthatjuk, rengeteg lehetőség kínálkozik a hardver kezelésére, és
ahogy egyre többet ismerünk meg a Delphi-ből, annál több hasonló technikát
sajátíthatunk el.
Az ilyen eljárásokat nem lehet könyvekben, referencia kiadványokban
megtalálni. A forrásokat keressük az Interneten, szaklapokban vagy gyakorlott
programozók publikus programjaiban.
Delphi a gyakorlatban
65
Tippek trükkök Delphi-ben
Az itt következő rész olyan eljárásokat, trükköket tartalmaz, melyek a
könyvekben, leírásokban nem szerepelnek. Az ismeretük a programozás során
nem elengedhetetlen, de nagyon hasznos lehet.
A fejezet felsorolás jellegű, csak ott fűztem hozzá magyarázatot, ahol az
feltétlenül szükséges volt. Az ilyen és ehhez hasonló fogásokat az Interneten
gyűjtöttem, barátoktól, ismerősöktől, de legfőképp tanáraimtól tanultam.
Az alábbi eljárással könnyen megoldható az egymásba ágyazott
könyvtárak egyidejű létrehozása: (Ezt a ForceDir eljárással is meg lehet
oldani, de gyakorlásnak nem árt, ha ismerünk egy másik megoldást is.)
Uses SysUtils, FileCtrl;...Procedure MkDirMulti(sPath : string);Begin If ('\' = sPath[Length(sPath)]) then Begin sPath := Copy(sPath, 1, Length(sPath)-1); End; If ( ( Length( sPath ) < 3 ) or FileCtrl.DirectoryExists(sPath) ) then Begin Exit; End; MkDirMulti(SysUtils.ExtractFilePath(sPath ) ); Try System.MkDir( sPath ); Except { kivételkezelés } End;End;
Egy példa a használatára:
Procedure TForm1.Button1Click(Sender: TObject);Begin MkDirMulti('c:\temp\one\two\three\four' );End;
Fájlok másolása: (így is lehet)
66
Uses LZExpand;...Procedure CopyFile(FromFileName, ToFileName: string);Var FromFile, ToFile: File;Begin AssignFile(FromFile, FromFileName); AssignFile(ToFile, ToFileName); Reset(FromFile); Try Rewrite(ToFile); Try If LZCopy(TFileRec(FromFile).Handle, TFileRec(ToFile).Handle) < 0 then raise EInOutError.Create('Error using LZCopy') Finally CloseFile(ToFile); End; Finally CloseFile(FromFile); End;End;
Fájl törlése a kukába:
Az alacsony szintű törléseknél - ilyet végez a DeleteFile eljárás is - a
file letörlődik. A következő kódrészlet segítségével azonban, egy API hívást
használva a kukába helyeződik át a file.
Egy file törléséhez egyszerűen meg kell hívni a DeleteFileWithUndo()
eljárást, paraméternek megadva a file nevét. Amennyiben a művelet sikeres
volt, az eljárás TRUE-t ad vissza.
Uses ShellAPI; ...Function DeleteFileWithUndo( sFileName : string ): boolean; Var fs:TSHFileOpStruct; Begin FillChar(fs,SizeOf(fs),0); With fs do Begin wFunc := FO_DELETE; pFrom := PChar( sFileName ); fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT; End;
67
Result := ( 0 = ShFileOperation( fs ) );End;
Egy könyvtárat és teljes tartalmát az alábbi módon lehet átmásolni egy adott helyre:
ImplementationUses ShellAPI;
{$R *.DFM}
Procedure TForm1.Button1Click(Sender: TObject);Var FS: TSHFileOpStruct;BeginWith FS do Begin Wnd := Self.Handle; wFunc := FO_COPY; //Másolás pFrom := 'c:\idapi\*.*'; //Honnan és mit másolunk? pTo := 'c:\proba'; //Ahová másoljuk fFlags := FOF_NoConfirmMkDir; //Nem kérdez rá a műveletreEnd; SHFileOperation(FS);End;
A szövegben szereplő animációk gyűjteménye
Tartalom Animáció
Adatbázisok Adatbázis(1).mpg
CheckBox CheckBox (1) .mpg
CheckListBox CheckListBox (1) .mpg
ComboBox ComboBox (1).mpg
Drag n’ Drop Drag n’ Drop (1) .mpg
Edit Edit (1) .mpg
GroupBox GroupBox .mpg
Image Image (1) .mpg
Listbox ListBox (1) .mpg
ListVieW ListView (1) .mpg
MainMenu 1 MainMenu (1) .mpg
68
MainMenu 2 MainMenu (2) .mpg
MainMenu 3 MainMenu (3) .mpg
MainMenu 4 MainMenu (4) .mpg
MainMenu 5 MainMenu (5) .mpg
MainMenu 6 MainMenu (6) .mpg
MaskEdit MaskEdit (1) .mpg
MDI Formok MDI (1) .mpg
OpenDialog 1 OpenDialog (1) .mpg
OpenDialog 2 OpenDialog (2) .mpg
Panel Panel (1) .mpg
PopUpMenu PopUpMenu (1) .mpg
ProgressBar ProgressBar (1) .mpg
RadioButon RadioButton (1) .mpg
RichEdit RichEdit (1) .mpg
StringGrid StringGrid (1) .mpg
ToolBar ToolBar (1) .mpg
Több Form használata TöbbForm (2) .mpg
TrackBar TrackBar (1) .mpg
TreeView TreeView (1) .mpg
Az animációk az elektronikus változatban elindíthatóak a Windows Media Player, vagy egyéb lejátszók segítségével (a DVD mellékleten avi és avi_data könyvtár)
Végszó
Alapozásnak ennyi elég is lesz. Ha a felsorolt részek mindegyikét
megértettük és megtanultuk alkalmazni, a további munka nem okozhat
nagyobb problémákat. A Delphi rendszert ellátták egy jól használható Help
rendszerrel, mely a Windows Start menü-jéből, és az IDE-ből is könnyen
elérhető. A Help szinte minden témakörben segítséget nyújt a programozó
számára, s készítői minden témakörhöz készítettek példaprogramokat is. Igaz,
hogy a segítség angol nyelvű, de a példákon keresztül könnyen megérthetjük az
egyes részeket.
69
Ha kíváncsiak vagyunk egy komponens tulajdonságaira, a forráskódban
vigyük rá a kurzort, majd nyomjuk le az F1 billentyűt, ezzel aktivizáljuk a súgó
rendszert.
14. ábra - A Delphi Fejlesztői Rendszer Help funkciója
A Delphi Help-jén kívül segítségünkre lehet még az MS SDK Help
Files is, mely a Windows programozásának lehetőségeiről ad felvilágosítást,
segít eligazodni a (sokszor 8-10 paraméterrel rendelkező ) függvények
között.
Végezetül elmondhatjuk, hogy aki megismeri a Delphi rendszert,
hatékonyabb programokat tud írni, betekintést nyer a fejlettebb operációs
rendszerek (Windows, Unix) programozásának technikáiba, és piacképesebb
tudást mondhat magáénak, mint azelőtt. A számítástechnikát tanuló diákok
számára fontos, hogy naprakészek legyenek a programozás területén, hogy a
kornak megfelelő tudással rendelkezzenek a felvételiken és később a
pályakezdésnél.
Jelenleg már a Delphi 8-as verziója is elérhető. (Sajnos ez már a
FrameWorkSDK nevű eszközre fordít, és a natív kód helyett felügyelt kódokat
készít. A 8-as verzióban ugyanúgy programozhatunk, mint az előzőekben, de a
létrejött programok nem Win32 típusúak…), s Linux alá is megjelent egy
70
változata Kylix néven. A választást mindenképpen a Kedves Olvasóra bíznám.
A választását befolyásolni fogja az elérhető hardveres és szoftveres környezet,
valamint a rendelkezésre álló anyagi forrás mennyisége. Remélem, a
dolgozatban kellően körül tudtam járni a témakört, valamint a video és webes
anyagokkal sikerült megadnom a segítséget a Delphi, vagy valamely vizuális
nyelv oktatásának elkezdéséhez! Sok sikert kívánok minden jelenlegi és
jövőbeni Delphi programozónak, és azoknak a tanároknak, akik a vizuális
nyelvek oktatást tűzik ki célul!
Király Roland
71