A Delphi fejlesztőinek célja egy könnyen gyors, megbízható programok (alkalmazások) fejlesztését lehetővé tévő eszköz készítése volt. Ezeken belül is kiemelkedő hangsúlyt kapott az adatbázis alkalmazások készítésének elősegítése. Nézzük most meg a fejlesztő – a programozó – szemszögéből ezt az eszközt.
A Delphi megtervezésekor az egyik jelszó a következő volt: Legyen látható (és elkészíthető) tervezési időben, ami csak lehet!
A komponens Borland féle definíciói:
A RAD és az alkalmazás generátor
A RAD (Rapid Application Development; gyors alkalmazásfejlesztés) egy komplex fogalom, amely a hatékony programfejlesztés különböző tényezőit foglalja magába. Lényege:
Az integrált debugger és egyéb nyomkövetési eszköz
Ami kimaradt
Nagyon hiányzik az editorból egy makrórögzítő, amellyel gyakran használt tevékenységeket automatizálhatnánk (3-asban még nincs).
Egyebek
A Delphi 3-ban lehetőség van ActiveX komponensek használatára. Az erre szolgáló technológiákat az Active Insight tartalmazza, melyeket a kliensoldali fejlesztésnél használunk. Ezek a következők:
A Delphi 3-ban valósították meg az ún. Broker Technologies-t, amely az előzővel ellentétben a szerveroldali fejlesztést segíti. Részei a következők:
Indítsuk el a Delphi fejlesztői környezetet. Válasszuk ki a File/New Application menüpontot. Ekkor kigenerálódik egy form, a hozzátartozó kód, illetve egy project állomány. Delphiben minden ablakhoz egy .pas és egy .dfm kiterjesztésű állomány tartozik. A .dfm írja le a form megjelenését (pl. az ablak fejlécének szövege, betütípusa), a .pas a form kódját. A project állomány (.dpr kiterjesztés) tartalmazza az projekthez tartozó fájlokat.
Példánkban ez a következőképpen néz ki:
Bal oldalon láthatjuk az Object Inspecort, jobb oldalon középen a Form megjelenési formáját, lent pedig a hozzátartozó kódszerkesztőt.
Tegyünk fel egy gombot a formra!
A kép jobb felső oldalán található a komponens paletta. Válasszuk ki a Standard fülből a Buttont:
Ezután klikkeljünk a formon egy tetszőleges helyre, ahova a gombot szeretnénk rakni. Ennek hatására a gomb megjelenik, és ha ráklikkelünk, az Object Inspectorban megjelennek a gomb állítható tulajdonságai (Properties), illetve az eseményei (Events).
Az Events fülből válasszuk ki az OnClick eventet, és klikkeljünk rá duplán! Ekkor a form kódszerkesztőjében megjelenik a Form1.Button1Click eljárás törzse. Írjuk bele a következőt:
A Hello world programunk már el is készült!
A Run/Run menüpont kiválasztásával elindíthatjuk a programunkat. (Előtte még rákérdez, hogy hova mentse el. Ha ezt eddig nem tettük meg jó programozó módjára, akkor most megtehetjük.)
A Delphi egyik legfontosabb eleme a komponens. A komponens egy olyan valami, amelynek attribútumai, metódusai, illetve eseményei lehetnek. Vannak kitüntetett komponensek, ezek az un. vizuális komponensek (VCL). Ezek – leegyszerűsítve - annyival tudnak többet az általános komponenseknél, hogy tervezési időben adhatóak a formhoz, illetve bizonyos esetekben a tulajdonságait is állíthatjuk. Vannak előre definiált komponensek (ezeket láthatjuk az eredeti komponenspalettán), illetve a programozó is készíthet komponenseket. Mint az alábbiakban látható, a komponens megírásához sok segítséget kapunk: a Delphi kigenerálja az alapokat, és nekünk csak a megfelelő dolgokat kell kitöltenünk. Sokat segít az is, hogy előre definiált komponens-vázakat használhatunk.
Készítsünk komponenst!
Készítsünk egy olyan TButton komponenst, amelynek default-ban 'Hello World!' a felirata. Válasszuk ki a kezdőablakon a File/New... menüpontot. A következő ablak jelenik meg:
Válasszuk ki a 'Component'-et.
Ekkor a megjelenő ablakon adjuk meg, hogy miből származtatjuk (Ancestor type), a leendő komponensünk nevét (Class Name), melyik palettán legyen (Palette Page), illetve mi legyen a forrásfájl neve.
Ezután nyomjuk meg a Create unit gombot!
A következő kód generálódik:
Adjuk meg, hogy a felirat ‘Hello World!’ legyen. Ehhez a Create metódust kell felüldefiniálnunk:
A Component/Install Component... menüponttal installálhatjuk a komponenst. A Samples fülről már használható a komponensünk.
Code Completion Wizard: helyes szintaxis biztosítása
Ha a kódban leírunk egy objektum azonosítót - amit már deklaráltunk -, akkor a hivatkozási pont (‘.’) leírása után a Delphi egy kis ablakban megjeleníti az adott objektum metódusait, illetve attribútumait. Innen egyszerűen kiválasztva és 'Enter'-t ütve a kódba generálódik az metódus/attribútum neve.
Ha például egy metódust választunk ki (Application.Messagebox), akkor a kurzor a zárójel mögé kerül, és hint formájában láthatjuk, hogy milyen formális paraméterei vannak az adott metódusnak. Nem kell magyarázni, hogy ez miért jó…
A Delphi fejlesztőinek nem titkolt célja a gyors adatbázis kezelő alkalmazások fejlesztésének elősegítése.
Ennek elemei a következők:
Borland Database Engine - Adatbázis Motor
A Delphi installálásakor felkerül a BDE is. Ezt elindítva a definiált adatbázis-hivatkozásokat (alias), illetve a default adatbázis-elérési paramétereket láthatjuk:
Az Object/New paranccsal hozhatunk létre új adatbázis-elérést.
Először meg kell adnunk, hogy milyen Driveren érhető el az adatbázis (a legtöbb adatbázis-kezelőt ismeri a Delphi: MSSQL, Paradox, Dbase, Oracle, Informix, Sybase,….),
majd meg kell adnunk a paramétereket (Alias név, Adatbázis-szerver neve, ha van, illetve egyéb driver-specifikus paramétert):
Egy hasznos tulajdonsága a BDE-nek, hogy ellenőrizhető, hogy „él”-e az adatbázis. Ezt az Object/Open paranccsal tehetjük meg.
Egyéb paramétereket (pl. System Date Format…stb.) a Configuration fülnél állíthatunk be.
Database Wizard - Egy egyszerű karbantartó program készítése
(megjegyzés: A Delphi installáláskor példaadatbázisok kerülnek a gépre. Ezeket használom a példákban.)
Válasszuk ki a File/New… menüpontot. A megjelenő ablakban válasszuk ki a Business fület:
Nyomjuk meg az OK gombot. Ekkor elindul a Database Form Wizard. Válasszuk ki a 'Simple Form' , illetve a 'Create a form using a TTable Object' elemeket.
Nyomjuk meg a Next gombot.
A megjelenő ablakban megadhatjuk, hogy melyik adatbázis (illetve alias)-nak megfelelő táblához generáljunk.
Válasszuk ki a DBDEMOS aliast és az ANIMALS.DBF-et. Nyomjuk meg a Next gombot.
Itt választhatjuk ki, hogy milyen mezők legyenek rajta a formon. A kiválasztás után nyomjuk meg a Next gombot.
Itt kiválaszthatjuk, hogy az adatmezők vízszintesen, függőlegesen, vagy Grid formátumban jelenjenek-e majd meg a formon. A kiválasztás után nyomjuk meg a Next gombot.
Itt megadhatjuk, hogy csak a formot generálja ki, vagy a hozzátartozó adatmodult is. A jobb strukturáltsághoz ajánlott a másodikat választani (adatkezelés és adatmegjelenítés külön modulban lesz).
Nyomjuk meg a Finish gombot. Ezzel el is készítettük az ANIMALS tábla kezelőformját, amely azonnal futáskész!
Database Desktop – Adatbázis böngésző
Ez a program teszi lehetővé az adataink megtekintését, illetve „kézi” módosítását.
Például nézzük meg, mi van az ANIMALS.DBF-ben.
A Database Desktop elindítása után válasszuk ki a File/Open/Table… menüpontot. Adjuk meg az aliast (DBDEMOS), illetve válasszuk ki az ANIMALS.DBF-et. Az OK gombra kattintva a következőt látjuk:
Itt megtekinthetjük, illetve módosíthatjuk az adatokat.
A Fil/New/Query…-vel hozhatunk létre új lekérdezéseket. Saját Queryk írása lásd: Database Explorer
Hasonlóan ezzel a programmal is megtekinthetjük az adatainkat. Lényeges tulajdonság, hogy egyszerű SQL parancsokat is futtathatunk az adatbázisainkon.
Nézzük például, hogy hogyan lehet lekérdezni az ’A’ betűvel kezdődő állatokat.
A Database fül alatt válasszuk ki a DBDEMOS-t. Ezután a jobb oldalon az Enter SL fül alá írjuk a következőt:
select * from ANIMALS where NAME like 'A%'
A ’villám’ gomb megnyomásával futtathatjuk a queryt, és az eredmény a jobb alsó részben jelenik meg:
Az adatok manipulálásán kívül általában listákat is kell készíteni. Ebben segít a Quick Report komponenscsomag, illetve a Quick Report Wizard.
Tegyük fel, hogy egy listát kell készítenünk az összes állatról. Ezt a listát a következőképpen generálhatjuk ki:
Válasszuk ki a File/New… menüpontot. A megjelenő ablakban válasszuk ki a Business fület:
A megjelenő ablakban válasszuk ki a Quick Report Wizardot.
Itt kell megadni az adatbázis aliast (DBDEMOS), illetve a tábla nevét, amiről listát akarunk készíteni (ANIMALS.DBF). Az adatok megadása után Next gomb.
Adjuk meg a megjelenítendő mezőket- Next.
...a report címét, illetve a betűtípust. A Finish gomb megnyomása után a report form elkészül. Megjegyzendő, hogy ha a formra generált Table1 komponenst aktiváljuk (Klikk a Table1-re, Object Inspectorban: Activate-et állítsuk true-ra), akkor a formon a jobb klikk menü/Preview menüponttal megnézhetjük a reportot úgy, hogy a programot valójában még el se indítottuk!
<
A program végrehajtásának ellenőrzése
A változók értékeinek figyelése az adatszerkezetekben
Az adatok értéknek a változtatása nyomkövetés közben.
Fordításidejű hibák
Logikai hibák
Futásidejű hibák
A fordításidejű hibákról: Ezek a hibák akkor jönnek elő, ha megsértettük a nyelv szintaxisának szabályait. A program nem fordítható le addig, amíg helytelen utasításokat, kifejezéseket tartalmaz. A leggyakoribb ilyen hibák: elgépelések, hiányzó pontosvessző, nem deklarált változó használata, kevés vagy túl sok paraméter használata függvény vagy eljárás hívásakor, típushibák.
A logikai hibákról: Logikai hibáknak a hibák azon csoportját nevezzük, amikor az utasításaink helyesek, de nem az történik, amit be szerettünk volna programozni. Pl.: ha a változóink rossz értéket tartalmaznak, vagy egy kép nem jó irányba néz, vagy a program kimenete nem a várt eredmény.
A futásidejű hibákról: Ezek a hibák akkor jelentkeznek, ha a programunk helyes utasításokat tartalmazott, de hiba történt a konkrét végrehajtás során. Pl.: a programunk nem létező file-t próbált megnyitni, vagy 0-val próbált osztani. Az operációs rendszer felfedezi a hibát és megállítja a programunk futását.
A beépített debugger a logikai és a futásidejű hibák kijavításában ad
segítséget, míg a fordításidejű hibákra a compiler figyelmeztet.
Összetett probléma esetén nehéz megtalálni a logikai hibák okát, és a
futásidejű hibák javítása is könnyebb, ha tudjuk, hogy hol és miért
keletkezik a hiba.
Az IDE automatikusan generál nyomkövetési információkat, de ha a nyomkövetés mégis ki lenne kapcsolva, bekapcsolhatjuk a Tools|Debugger Options panelen az Integrated debugging jelölőnégyzet bekapcsolásával. Ebben a menüpontban még több lehetőség is adódik a debugger finomhangolásra.
Fontos: A nyomkövetési információk használata (amit a Delphi generál) növeli a projektünk méretét, ezért ha elkészültünk és megbizonyosodtunk róla, hogy nincs benne hiba, akkor kapcsoljuk a ki az extra információ hozzáfűzését a Project|Options Compiler fül Debugging information jelölőnégyzet segítségével.
Running to the cursor -> A kurzor aktuális pozíciójától kezdődik, vagy folytatódik a debuggolás (Hotkey : F4)
Stepping through code -> Ezzel lehetőséget kapunk, hogy sorról sorra hajtsuk végre a programunkat, ezzel a (majdnem) maximális rálátást kapva a program állapotára. Ezt kétféleképpen tehetjük meg : Trace Into (F7) vagy Step Over (F8). Az első azt jelenti, hogy a debugger belemegy függvényekbe és eljárásokba is, majd a kiértékelés végeztével a hívás utáni első soron folytatja a debuggolást, míg a másodikat használva rögtön a függvény vagy eljárási utáni sorra kerülünk, és csak az alprogram hatását érzékeljük.
Running to a breakpoint location -> A kódszerkesztő ablakban töréspontokat (breakpointokat) definiálhatunk (F5), amelyek hatására a program végrehajtása felfüggesztődik, és debuggolhatjuk a programunkat. A Delphi nyilvántartja a töréspontjainkat is, ezért nem kell keresgélni a töréspontokat a forráskódban, hanem a Breakpoint List ablakban duplán kattintva a töréspontra odaugrik. Fontos megjegyezni, hogy csak érvényes programsorra állíthatunk töréspontot, tehát például egy kommentre állított töréspont nem érvényes.
Pausing your program
->Programunk megállítására egy egyszerűbb mód is adódik. Egyszerűen
futás közben Rum|Program Pause használatával vagy az eszköztáron ennek
megfelelő ikonra kattintással felfüggeszthetjük programunk futását. A
Run|Runnal újra elindíthatjuk. A legtöbb esetben a CPU-ablak fog
felugrani, mert az aktuális utasítás nem fordítható vissza egyértelműen
egy Delphi sorra.
Végrehajtási pont: Végrehajtási pontnak nevezzük azt a kódsort, amely a
végrehajtásban a soron következő utasítás. Ezt a Delphi debuggoláskor
más színnel jelzi.
Ha debuggolás céljából megállítottuk programunk futását, akkor lehetőségünk van megvizsgálni a különböző szimbólumok és adatstruktúrák értékét. Gyakran kell figyelni például indexváltozókat, amikor iterálunk egy adatszerkezeten, vagy az aktuális paraméterek értékét, amikor alprogramot hívunk. Majdnem mindent használhatunk megfigyelési kifejezésként, ami egy operátor jobb oldalán használható, kivéve azokat a változókat, amelyek nem érhetők el az aktuális végrehajtási ponttól.
A következő lehetőségeink vannak a programunk állapotának figyelésére:
Program értékeinek figyelése -> Ha egy változó vagy kifejezés aktuális értékét figyelni akarjuk, annyi a dolgunk, hogy felvesszük a figyelt értékek közé. Ezt debuggolás közben megtehetjük a Watch listába való felvétellel. (CTRL+F5) A Watch ablakban mindig a változó aktuális értéke fog látszani (ha azt ki lehet számolni).
Állapot megváltoztatása -> Lehetőségünk van debuggolás közben a változók értékének megváltoztatására is. Ezt itt tehetjük meg: Run|Evaluate/Modify. Különösen hasznos olyan hibák keresésekor, amelyek csak ritkán vagy bizonyos adatokra jönnek elő, de nagy haszna van ennek a módszernek akkor is, ha úgy gondoljuk, hogy rájöttünk a hibára és igazolni is akarjuk a debuggerből való kilépés nélkül.
Inspector ablak alkalmazása -> Talán ez a leghatékonyabb módja változók figyelésének, ha összetett adatstruktúrákról van szó, mert a debugger automatikusan formázza az ablakot a megfigyelt objektum típusától függően. Nagyon hasznos tömbök és láncolt listák esetén. Így érhetjük el: Run|Inspect
A program alacsonyszintű állapotának figyelése -> A CPU ablak előhozásával (Kódszerkesztő|Gyorsmenü|Debug|View CPU) alacsonyszintű állapotfigyelésre kapunk lehetőséget! Az ablak 5 fő részre tagolódik: Disassembly, Memory Dump, Machine Stack, Registers, Flags. Az elsőben programunk assembly kódját látjuk, a másodikban a memóriaképét, a harmadikban a program stack tartalmát, a negyedikben a regiszterek tartalmát, míg az utolsóban a FLAGek aktuális állását.
A Call Stack ablak
-> Ez az ablak a dinamikus hívási
láncot mutatja, ami lehetőséget ad arra, hogy megvizsgáljuk a megelőző
függvényhívásokat.
A Delphi megengedi, hogy más programozási nyelvekben megírt (C, C++, Assembly) és tárgykódra lefordított programok kódját is hozzálinkeljük saját programjainkhoz. Ennek a nyomkövetése is lehetséges, de csak akkor, ha a külső object file-okban nyomkövetési információ van elhelyezve. Ha az adott file-ban nincs nyomkövetési információ, akkor is tudunk lépkedni az utasításokon, de akkor csak a CPU ablakban megjelenő alacsony szintű kódot láthatunk.
Ha csak egy Delphiben megírt DLL-t
szeretnénk debuggolni, akkor nem szükséges az azt használó .exe file-t
is hozzáadni a projecthez, hanem a paraméteres nyomkövetést választva
(Run|Parameters) elegendő a Host applicationnáé kiválasztani az exe-t
és betölteni a debuggerbe.
Ha meg szeretnénk állítani a program futását, amint használni akarja a
DLL-ünket, akkor Module Load Breakpointot kell használnunk. Ezt így
tudjuk elérni: Run|Add Breakpoint|Module Load Breakpoint. Ekkor,
ha a külső program megpróbálja elérni a DLL-t, a program meg fog állni.
A Project Manager használatával -> A View|Project Manager használatával hozzáadhatjuk a debuggolni kívánt projekteket. Debuggolás közben nem tudunk fordítani, ezért érdemes újrafordítani az egészet kezdés előtt (Project|Build All Projects).
A Thread View használata ->A View|Debug Windows|Threads használatával lehetőségünk nyílik váltogatni az aktuálisan debuggolás alatt álló processzek között. A zöld nyíl jelzi az aktuális processzt, a kék a nem aktuálisakat.
Run|Parameters használata -> A Remote fülön található lehetőségekkel távoli gépeken futó folyamatok nyomkövetése is lehetséges.
a szál azonosítója,
állapota (Running or Stopped)
státusza (Breakpoint => A szál töréspont miatt állt meg, Faulted =>Feldolgozási hiba miatt állt le, Unknown =>Nem ez az aktuális szál, státusza nem ismert, Stepped =>A legutolsó léptetési parancs végrehajtva)
helye
View Source -> Megnyitja a kódablakot az aktuális pozíciónál, de nem teszi az aktuális ablakká.
Go to Source -> Ugyanaz, mint az első, csak aktiválja az ablakot is.
Make Current -> Aktívvá teszi a szálat (ha még nem az).
Figyelem: az alábbiak a WinSight 16-bites verziójára érvényesek. A program megtalálható a Delphi újabb verzióiban is, de kicsit másképp működik, pl. eltűnt az osztályfa nézet.
A WinSight lehetővé teszi ablakosztályok, ablakok és üzenetek nyomkövetését. Használatával könnyebben megérthetjük, hogy az alkalmazások hogyan hoznak létre ablakokat, pop-up menüket, és hogyan zajlanak az üzenetküldések.
A WinSight 3 fő nézete:
Ablakfa nézet -> Ez a nézet az ablakhierarchiát mutatja a munkaasztalon. Egy bejegyzés ezeket az információkat mutatja:
Handle (Az ablak azonosítója),
{Class} (Az ablak osztályának a neve),
Module (A futtató állomány, amely létrehozta),
Position (Az ablak pozícióját adja meg. Ha főablak, akkor a monitorhoz viszonyítva, ha alkalmazás ablaka, akkor az alkalmazásablakhoz viszonyítva. Hiddent ír, ha nem látható)
"Title" (Az ablak neve, ha van neki)
Az ablakokról részletesebb információt is
kaphatunk, ha kétszer rákattintunk a nevére.
Osztályfa nézet ->Az összes aktuálisan beregisztrált ablakosztályt mutatja, a következő formában :
Class (Az ablak-osztály neve /Néhányuknak csak számazonosítójuk van/)
(Module) (A futtató állomány neve)
Function (A függvény címe)
Styles (Az ablakra jellemző stílusbeállítások listája CS_ kezdettel)
Részletesebb információt is kaphatunk, ha kétszer rákattintunk a nevére.
Üzenetfa nézet ->Ez a nézet a kiválasztott ablak fogadott üzeneteiről mutat információkat a következő formában:
Handle (Az ablak azonosítója)
"Title"-or-{Class} (Az ablak neve, ha van neki, vagy az osztálya)
Message (Az üzenet neve, amely a WINDOWS.H-ban van definiálva, vagy ha az ismeretlen /felhasználó-definiált/, akkor a következő jelölést használja : WM_USER+0xXXXX)
Status (A következők lehetnek: Dispatched, Sent, Returns (részletesen lásd help))
... (Plusz információ, az üzenettől függően, pl. visszatérési érték)
Beállíthatjuk, hogy mely üzeneteket akarjuk nyomon követni (Messages|Options...) és azt is, hogy melyik processzét (Messages|Processes).