A Delphi programozási nyelv

Kezdőknek

A Delphiről általában

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:



Egy egyszerű alkalmazás készítése – Hello World!

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:

ShowMessage('Hello World!');

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.)



Komponensek

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:

unit MyButton; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TMyButton = class(TButton) private { Private declarations } protected { Protected declarations } public { Public declarations } published { Published declarations } end; procedure Register; implementation procedure Register; begin RegisterComponents('Samples', [TMyButton]); end; end.

Adjuk meg, hogy a felirat ‘Hello World!’ legyen. Ehhez a Create metódust kell felüldefiniálnunk:

unit MyButton; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TMyButton = class(TButton) private { Private declarations } protected { Protected declarations } public constructor Create(AOwner: TComponent); override; { Public declarations } published { Published declarations } end; procedure Register; implementation constructor TMyButton.Create(AOwner: TComponent); begin inherited Create(AOwner); Caption := 'Hello World!'; end; procedure Register; begin RegisterComponents('Samples', [TMyButton]); end; end.

A Component/Install Component... menüponttal installálhatjuk a komponenst. A Samples fülről már használható a komponensünk.



Segítség a fejlesztésben

  • 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ó…



    Adatbázis-kezelés

    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


    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:


    QuickReport – Report készítő

    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!
    <

    Nyomkövetés Delphiben és a beépített debugger

    Akármilyen gondosan is írjuk meg programjainkat, nagyobb projektek esetén elkerülhetetlen, hogy olyan hibákat vétsünk, amelyek nem szűrhetőek ki szintaktikai szinten, azaz a Delphi fordítója nem jelzi nekünk, hanem futás közben, nem megfelelő programműködés formájában bukkannak elő.

    A nyomkövetés (debugging) ezen hibák megtalálásának és kijavításának folyamata. A Delphi számos eszközt ad a programozó kezébe, hogy minél egyszerűbbé tegye a nyomkövetés folyamatát.
    A beépített debugger a következő három dolgot teszi lehetővé:

    1. A program végrehajtásának ellenőrzése

    2. A változók értékeinek figyelése az adatszerkezetekben

    3. Az adatok értéknek a változtatása nyomkövetés közben.
       

    A hibák  három főbb osztályba sorolhatók:

    1. Fordításidejű hibák

    2. Logikai hibák

    3. 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.

    A debugger beállítása

    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.

     

    A nyomkövetési stratégia meghatározása

    A program megtervezése után a munkánk folyamatos kódolásból és debuggolásból áll. Csak átfogó teszt után szabad átadni a kész terméket a végfelhasználóknak. Ezért kap fontos szerepet a nyomkövetési stratégia. Az egyik jó startégi például az, ha külön részekre osztjuk a programunkat, amit szisztematikusan tudunk debuggolni. Ha hibát találtunk, akkor javítás és egy újrafordítás után ismételhetjük az előző műveleteket, ha még mindig szükséges.

    A programvégrehajtás vezérlése

    Mint már említettem, a beépített debugger nagy előnye, hogy lehetőséget ad a program végrehajtásának az ellenőrzésére. Mi írhatjuk elő, hogy melyek azok a részek, amelyeket már jól ismerünk, és melyek azok, amiket vizsgálni szeretnénk. Erre a következő lehetőségek adottak :

    A program változóinak vizsgálata

     

    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:

    Külső egységek nyomkövetése

     

    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.

     

    DLL-ek nyomkövetése

    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.

    Szálak nyomkövetése

    Delphiben lehetőség van a szálak (threadek) nyomkövetésére is. Háromféle lehetőségünk is van ezt megtenni.
    1. 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).

    2. 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.

    3. 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.

    FONTOS: Többprocesszes debuggolás indítása előtt mindig érdemes egy Project|Build All Projects-et használni, mivel a folyamatok közös file-okat oszthatnak meg egymás közt. A Threads Status Box előhozatalával fontos információkat kaphatunk a szálainkról, mint például: Egy jobb klikkel egy szálon a következő lehetőségeket érhetjük el :



    Pár szó a WinSightról

    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:

    1. 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.
       

    2. 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.

    3. Ü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).