Delphi szoftverfejlesztés haladóknak



Hasonló dokumentumok
Programozási alapismeretek 4.

3.2. Az alkalmazások ablaka

1. Origin telepítése. A telepítő első képernyőjén kattintson a Next gombra:

C++ programozási nyelv

Thermo1 Graph. Felhasználói segédlet

Programozási technológia

Pénzintézetek jelentése a pénzforgalmi jelzőszám változásáról

Java programozási nyelv 6. rész Java a gyakorlatban


Segédlet kriptográfiai szolgáltatást beállító szoftverhez (CSPChanger)

A program telepítése. A letöltés lépései: 1. nyissa meg a WEB-oldalt, majd válassza a Letöltés menüpontot a felső sorban:

Programozási technikák Pál László. Sapientia EMTE, Csíkszereda, 2009/2010

Miután létrehoztuk, szeretnénk neki beszédesebb nevet adni. A név változtatásához a következőt kell tenni:

1 Rendszerkövetelmények

1. Mi a fejállományok szerepe C és C++ nyelvben és hogyan használjuk őket? 2. Milyen alapvető változókat használhatunk a C és C++ nyelvben?

EDInet Connector telepítési segédlet

WordPress segédlet. Bevezető. Letöltés. Telepítés

Aromo Szöveges értékelés normál tantárggyal

Szilipet programok telepítése Hálózatos (kliens/szerver) telepítés Windows 7 operációs rendszer alatt

Már megismert fogalmak áttekintése

PDF. Tartalomjegyzék 1/21

Programozás II. 3. gyakorlat Objektum Orientáltság C++-ban

1.A. feladat: Programablakok

CIB Internet Bank asztali alkalmazás Hasznos tippek a telepítéshez és a használathoz Windows operációs rendszer esetén

Programozás BMEKOKAA146. Dr. Bécsi Tamás 8. előadás

Gyökértanúsítványok telepítése Windows Mobile operációs rendszerekre

Microsoft Office PowerPoint 2007 fájlműveletei

Objektumorientált programozás Pál László. Sapientia EMTE, Csíkszereda, 2014/2015

munkafüzet open eseményéhez

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Tartalomjegyzék. A Delphi 5 integrált fejlesztõkörnyezet 8. A Delphi 5 kiadásai 7

TERKA Törvényességi Ellenőrzési Rendszer Kiegészítő Alkalmazás

OOP #14 (referencia-elv)

Aromo Szöveges értékelés kódolt tantárggyal

CitiDirect BE SM Felhasználói útmutató

A LOGO MOTION TANÍTÁSA

Objektumorientált programozás Pál László. Sapientia EMTE, Csíkszereda, 2014/2015

Az importálás folyamata Felhasználói dokumentáció verzió 2.1.

Digitális aláíró program telepítése az ERA rendszeren

Swing GUI készítése NetBeans IDE segítségével

POSZEIDON dokumentáció (1.2)

A CAPICOM ActiveX komponens telepítésének és használatának leírása Windows7 operációs rendszer és Internet Explorer 8-es verziójú böngésző esetén

A MOKKA hitelesítő szoftver telepítése és használata

Dokumentum létrehozása/módosítása a portálon:

MEH-EIA felhasználói dokumentáció gyakran ismételt kérdések

DogsWorld nevelde telepítése és beállítása

ÁNYK53. Az Általános nyomtatványkitöltő (ÁNYK), a személyi jövedelemadó (SZJA) bevallás és kitöltési útmutató együttes telepítése

SSL VPN KAPCSOLAT TELEPÍTÉSI ÚTMUTATÓ

Image Processor BarCode Service. Felhasználói és üzemeltetői kézikönyv

3. Ezután a jobb oldali képernyő részen megjelenik az adatbázistábla, melynek először a rövid nevét adjuk meg, pl.: demo_tabla

Bevezetés a Python programozási nyelvbe

WINDOWS TELEPÍTÉSI ÉS AKTIVÁLÁSI ÚTMUTATÓ A FOTOBETYAR.HU - PHOTOSHOP PLUGINJEIHEZ

Tanúsítványkérelem készítése, tanúsítvány telepítése Lotus Domino szerveren

A számítógép beállításainak megváltoztatása

Segédlet kriptográfiai szolgáltatást beállító szoftverhez (CSPChanger)

A NetBeans IDE Ubuntu Linux operációs rendszeren

Oktatás. WiFi hálózati kapcsolat beállítása Windows XP és Windows 7-es számítógépeken. SZTE Egyetemi Számítóközpont

18. Szövegszerkesztők

Tartalom jegyzék 1 BEVEZETŐ SZOFTVER ÉS HARDVER KÖVETELMÉNYEK 2 2 TELEPÍTÉS 2 3 KEZELÉS 5

ELSŐ LÉPÉSEK A SZÁMÍTÓGÉPEK RODALMÁBA AMIT A SZÁMÍTÓGÉPEKRŐL TUDNI ÉRDEMES

Digitális aláíró program telepítése az ERA rendszeren

GIRO GSM MODEM/VPN KAPCSOLAT TELEPÍTÉSI ÚTMUTATÓ

1. A Windows programok telepítése

Órarendkészítő szoftver

Digitális aláírás általános telepítése és ellenőrzése

Adatbázis Rendszerek II. 5. PLSQL Csomagok 16/1B IT MAN

A program telepítése. A letöltés lépései: 1. nyissa meg a WEB-oldalt, majd válassza a Letöltés menüpontot: 2. Kattintson a DbérWIN 2015 hivatkozásra:

Java telepítése és beállítása

Java telepítése és beállítása

Megújított tanúsítvány cseréje a Windows tanúsítványtárban

A szerzõrõl... xi Bevezetés... xiii

Java Programozás 5. Gy: Java alapok. Adatkezelő 1.rész

Tanúsítványkérelem készítése, tanúsítvány telepítése Microsoft Internet Information szerveren

Adóbevallás leadása elektronikusan

1. DVNAV letöltése és telepítése

VARIO Face 2.0 Felhasználói kézikönyv

Cikktípusok készítése a Xarayában

FELHASZNÁLÓI ÚTMUTATÓ

3. Osztályok II. Programozás II

GENERIKUS PROGRAMOZÁS Osztálysablonok, Általános felépítésű függvények, Függvénynevek túlterhelése és. Függvénysablonok

AZ N-WARE KFT. ÁLTAL ELEKTRONIKUSAN ALÁÍRT PDF DOKUMENTUMOK HITELESSÉGÉNEK ELLENŐRZÉSE VERZIÓ SZÁM: 1.3 KELT:

VarioFace dokumenta cio

Telepítési útmutató a SMART Response 2009 szoftverhez

QGIS gyakorló. --tulajdonságok--stílus fül--széthúzás a terjedelemre).

Bevezetés a QGIS program használatába Összeálította dr. Siki Zoltán

Dropbox - online fájltárolás és megosztás

Duál Reklám weboldal Adminisztrátor kézikönyv

Interfészek. PPT 2007/2008 tavasz.

Telenor Webiroda. Kezdő lépések

Mappák megosztása a GroupWise-ban

Belépés a GroupWise levelező rendszerbe az Internet felől

HF-DVR H.264 Hálózati Rögzítő. Felhasználói kézikönyv

Műveletek makrókkal. Makró futtatása párbeszédpanelről. A Színezés makró futtatása a Makró párbeszédpanelről

Hozzávalók keresése és csatolása

Delphi programozás I.

Online naptár használata

Oktatási segédanyag. Weboldalszerkesztési gyakorlatok

Oralce kliens installálása Windows Server 2003-ra

DebitTray program Leírás

Átírás:

Delphi szoftverfejlesztés haladóknak Salga Péter DE, AVK Gazdasági- és Agrárinformatikai Tanszék 1

Tartalomjegyzék 1. Bevezetés... 3 2. MDI alkalmazások létrehozása... 4 a) Egy kis MDI-elmélet... 4 b) Készítsük el a keretablakot!... 5 c) MDI függvények és használatuk... 9 Csoportmunka... 9 Kötelező feladatok... 10 Szorgalmi feladatok... 10 3. Öröklődés, ősök... 11 a) Objektumorientált programozás... 11 b) Öröklődés... 13 c) Származtatás az alapformból... 14 Csoportmunka... 18 Kötelező feladatok... 18 Szorgalmi feladatok... 19 4. Komponensek... 20 a) Bevezető... 20 b) Komponenscsomagok... 20 c) A komponenskészítés szabályai... 21 d) Az alapvető komponensosztályok... 22 e) Komponenscsomag telepítése... 22 f) Komponens minta (template) készítése... 27 Csoportmunka... 29 Függvények, eljárások... 29 Kötelező feladatok... 30 Szorgalmi feladatok... 31 5. Komponensfejlesztés... 32 a) Miért szoktak az emberek komponenseket írni?... 32 b) Miből célszerű származtatni az új komponenst?... 32 c) TElsoSajatKomponensem... 33 d) Események létrehozása... 36 e) TskBetuKombo... 38 Csoportmunka... 40 Változók használata... 40 Kötelező feladatok... 41 Szorgalmi feladatok... 42 6. Adatbáziskezelés alapjai... 43 a) Az adatbáziskezelés fogalma... 43 b) Programozási környezetünk frissítése... 43 c) BDE... 45 d) Egy egyszerű BDE-alkalmazás... Hiba! A könyvjelző nem létezik. 2

1. Bevezetés Gyakorlat nélkül az elmélet olyan, mintha egy almafát ültetnénk a kertünkben, gondoznánk, nevelnénk, figyelnénk, amikor virágba borul, de amikor almák teremnek rajta egyet sem szakítanánk le, hogy megkóstoljuk. Az elmúlt félév során remélhetőleg megismerted a Windows szoftverfejlesztés szépségeit, rájöhettél arra, hogy egy egyszerűbb program megírásához nem kell különleges, mágikus képesség, elég az egyszerűbb fogalmak ismerete és logikus gondolkodás. A második félévben megpróbálunk bevezetni Téged a programozás mélyebb bugyraiba, ahol olyan fogalmakkal fogsz találkozni, amelyek már a modern programozáshoz szükségesek. Manapság a szoftverfejlesztés csapatmunka, nagyobb rendszerek kifejlesztését ugyanis csak a legritkább esetben képes egyetlen ember véghezvinni. A fejezetek végén a Csoportmunka részben megismertetünk a team-munkát támogató eszközökkel, és azokkal a fogalmakkal, módszerekkel, amelyek egy csapat segítségére lehetnek egy nagyobb rendszer fejlesztésének kézben tartására. Magyarországon a programozási feladatok túlnyomó része valamilyen üzleti, gazdasági, ügyviteli probléma megoldásához kötődik, és ezek a feladatok szinte mindig igényelnek adatbázis-programozást. A félév során megismerkedhetsz az adatbázisok delphis kezelésének alapjaival, és megtanulhatod a Delphi beépített adatbázisának, az Interbase-nek az alapjait, valamint a kimutatás-készítés eszközeit. A modern alkalmazásokban elengedhetetlen az Internetes programozás, többszál technika alkalmazása, de ejtünk szót az XML-ről, komponenskészítésről, DLL, COM, ActiveX programozásról és az ADO-ról. A félév során egy kölcsönző ügyviteli rendszerét készítjük el, amire néha majd olyan funkciókat is ráerőltetünk, amelyek nem szükségesek feltétlenül minden kölcsönzőben. Célunk az, hogy a fentebb leírt fogalmakat és módszereket megismerd, és hogy megfelelő előkészítést adjunk a félév végén végrehajtásra kerülő önálló csapatmunkában elkészítendő feladathoz. Nagyon fontos, hogy az egyes fejezetek végén található feladatokat vedd nagyon komolyan! Ahhoz, hogy elsajátítsd az anyagot, feltétlenül szükséges, hogy ezen feladatok mindegyikét maradéktalanul megoldd. Ha nehézséged akadna egyegy feladattal, akkor azt jelezd tanáraidnak. Legyél mindig kritikus önmagaddal, de a könyv gyakorlataival és megoldásaival szemben is. A jegyzetben felfedezett hibákat, nem működő programrészleteket, légy szíves, jelezd a salga@thor.agr.unideb.hu e-mail címen. Tartsd szem előtt azt is, hogy a Delphi fejlesztőkörnyezete is tartalmazhat hibákat, amiket meg kell tanulni a kikerülni, és hogy rendszerint nem csak egyetlen jó megoldás létezik! Ha a későbbiekben nem akarsz szoftverfejlesztéssel foglalkozni, akkor fogd fel úgy ezt a félévet, mint annak megismerését, mi mindent lehet ma megvalósítani a modern fejlesztő eszközökkel. Amennyiben a későbbiekben is akarsz még írni programokat, akkor ez a félév jó alapozás lehet egy olyan hosszú és göröngyös utazáshoz, amely során tapasztalt szoftverfejlesztő válhat belőled. Így vagy úgy, mi kívánunk Neked ehhez a félévhez nagyon sok kitartást és azt, hogy a gyakorlás során felmerülő apró problémáidhoz társuljon mindig a megoldás öröme. 3

2. MDI alkalmazások létrehozása a) Egy kis MDI-elmélet Amikor elindítunk egy szövegszerkesztő vagy táblázatkezelő programot, lehetőségünk van egyszerre több dokumentum megnyitására, az ún. keretablak -on belül, amelyben kezelni tudjuk ezeket a dokumentumokat. A Windows jegyzettömbje vagy azok a programok, amelyeket a múlt félévben írtatok nem ilyenek. Ezek a korábban megismert alkalmazások egyszerre csak egy ablakot tudnak kezelni, és amikor egy másik ablak megjelenítését akarjuk elérni, akkor külön párbeszédablakok segítségével tudjuk ezt elérni. 1.ábra A Delphiben természetesen van lehetőség több ablakot kezelő alkalmazások írására. Tulajdonképpen a Delphi is ilyen alkalmazás (annak egy speciális formája), mivel azonban hiányzik a főablak háttere és néhány más tulajdonsága, egy kicsit ezt nehezebb felismerni. Azokat az alkalmazásokat, amelyek egy főformon belül megjelenő több formból állnak MDI (Multiple Document Interface), vagy többablakos felületű programnak nevezzük (1. ábra). Ez a technika általánosan használatos a Windows-os alkalmazásokban, ezért néhány éve már, ha komolyabb programot írtak hacsak a program valamelyik funkciója ezt nem tette lehetővé az mindig MDI alkalmazás volt. 4

A Windows 95 operációs rendszer volt az előszele annak a divatnak, ami ma is virágkorát éli az operációs rendszer felületek és az irodai programcsomagok körében, amit egydokumentumos felületnek nevezünk. Az Office 2000 már teljes mértékben SDI (Single Document Interface) egydokumentumos felület. Ez a technika - elméleti szinten ugyanaz, ahogyan az előző félévben készítettétek a programjaitokat, de természetesen annak egy tervezésben, design-ban kifinomultabb módja. Az ügyviteli programok legnagyobb része még ma is MDI szemlélettel készül, mivel az üzleti folyamatok követéséhez közelebb áll ez a szemléletmód. Ezért választjuk a mi kölcsönző programunk számára is ezt a megoldást. Az MDI alkalmazás főablaka úgy viselkedik, mint egy tároló vagy keret, rendelkezik saját menüvel, és ha a főablakot mozgatjuk, akkor minden egyes objektum, ami benne található vele együtt mozog. A főablakot szülőablaknak vagy keretnek nevezzük, míg a keretablakban nyíló ablakokat gyerekablakoknak. A gyerekablakok csak a keretablak területén belül helyezkedhetnek el, és bármilyen típusúak lehetnek. A gyerekablakok ugyanazokkal a tulajdonságokkal rendelkezhetnek, mint a szülőjük, semmilyen korlátozás nincs rájuk, viszont a keretablakuk nélkül nem létezhetnek. Tehát ha bezárjuk a főablakot, akkor az összes gyerekablak is bezáródik. Ha meg akarjuk változtatni a keretablak és a gyerekablakok viszonyát vagy mélyebb tulajdonságait, akkor nem kerülhetjük el az API (Application Programming Interface) programozást, ami a Windows operációs rendszer beépített interfésze, gyakorlatilag függvények gyűjteménye a windows-üzenetek kezelésére. Bár egy gyakorlott programozónak elengedhetetlen az API függvények ismerete, és a komponensek létrehozásánál utalni fogunk még rájuk, ennek a jegyzetnek nem témája az API programozás. Ha érdeklődsz ebben a témában, akkor ajánljuk figyelmedbe a Delphi Developers s Handbook című könyvet (1998, Sybex). b) Készítsük el a keretablakot! Válasszuk a File New menüpontot, majd a megjelenő ablakon váltsunk a Projects oldalra és válasszuk ki az MDI Application ikont (2. ábra). 2. ábra 5

3. ábra Az OK gomb megnyomása után a felugró ablakban el kell mentenünk a projectet megadva a munkakönyvtárat (jegyezzük meg az elérési utat!), és már működik is! Indítsuk el a programot, és próbáljuk ki mi mindent tudunk vele csinálni! Nyissunk meg új gyerekablakokat, próbálgassuk a menüpontokat és az eszköztári gombokat! Ha már mindent megnéztünk, akkor térjünk vissza a Delphi IDE-hez a programunk bezárásával. Ha a főablakban voltak megnyitott gyerekablakok, akkor az alkalmazással ők is automatikusan bezáródtak. A View Projectmanager menüpont kiválasztásával figyeljük meg, hogy projectünk 3 unitból és 3 formból áll: AboutBox (Névjegy), ChildWin (Gyerekablak), Main (Keretablak). Ezt ellenőrizhetjük egy fájlkezelő alkalmazásban is, ha megnézzük az elmentett projekt fájljait. Nézzünk bele a Keretform kódjába! A New menüpont elindításánál a következőket találjuk: procedure TMainForm.FileNew1Execute(Sender: TObject); CreateMDIChild('NONAME' + IntToStr(MDIChildCount + 1)); A CreateMDIChild egy eljárás, aminek a bemenő paramétere egy string típusú változó, ami a gyerekablak neve lesz. Az eljárás deklarációját sem kell nagyon keresnünk: procedure TMainForm.CreateMDIChild(const Name: string); var Child: TMDIChild; { create a new MDI child window } Child := TMDIChild.Create(Application); //megcsináljuk az ablakot 6

Child.Caption := Name; //a bemenő paraméter lesz a form címkéje if FileExists(Name) then //ellenőrzi a kód, hogy van-e ilyen nevű fájlunk Child.Memo1.Lines.LoadFromFile(Name); //ha talál, feltölti a sorait a gyerekablak Memo komponensébe Figyeljük meg a típusdeklarációt: Child: TMDIChild;. Keressük meg mi is az a TMDIChild. Ehhez a Project Manager-ben nyissuk meg a Childwin unitot és formot. A form egyetlen Memo komponensből áll és a Code Explorerben a unit típusdeklarációjánál láthatjuk, hogy a TMDIChild a TForm osztályból származik (az örököltetésről és az ősökről nemsokára bővebben is szólunk majd). A keretablak következő eljárása az új MDIChild (azaz gyerekablak) elkészítését végzi: procedure TMainForm.FileNew1Execute(Sender: TObject); CreateMDIChild('NONAME' + IntToStr(MDIChildCount + 1)); Ebben az eljárásban meghívódik a fentebb deklarált eljárás, és paraméterként átadódik a NONAME szóhoz hozzáfűzve a már meglévő gyerekablakok száma + 1, tehát ez lesz a megnyíló ablak címsorában. Ez utóbbit az MDIChildCount nevű függvénnyel kérdezhetjük le. Ha már meglévő fájlt nyitunk meg az alkalmazásunk segítségével, akkor az szöveges formában jelenik meg egy új ablakban. A következő kódrészlet végzi a megnyitást: procedure TMainForm.FileOpen1Execute(Sender: TObject); if OpenDialog.Execute then CreateMDIChild(OpenDialog.FileName); 4. ábra 7

Az OpenDialog-ot már ismered (a komponens a formon van elhelyezve 4. ábra) és látható, hogy ebben az eljárásban is a CreateMDIChild-ot használjuk paraméterként a megnyitott fájl elérési útját (!) és nevét adjuk, azaz ez fog látszani a címsorban. Mielőtt a következő eljárás tárgyalásába kezdenénk, indítsuk el újra az alkalmazást és ellenőrizzük, hogy minden rendben működik-e. Ha még nem tettük eddig, akkor nyissuk meg a Help About menüpontból nyíló AboutBoxot, ami elég kezdetleges még. Bezárva az alkalmazást a Delphiben szabd át ezt a formot kedved szerint. Rakj rá képet, verziószámot és egyéb információkat, amit fontosnak tartasz magadról és a programról közölni a leendő felhasználónak. Ha most visszatérsz a keretablakra, akkor láthatod, hogy ellentétben az SDI alkalmazás formjával, itt már alapból rápakolt a Delphi jónéhány komponenst (4. ábra). Az OpenDialog mellett találunk egy MainMenu komponenst, amire duplán kattintva láthatjuk a menü teljes szerkezetét. Új menüpontot Insert-tel szúrhatunk be, almenüt a Ctrl + jobb nyíl segítségével, törölni pedig a Delete gombbal tudunk (jobb egér kattintásra felugró menüből is elvégezhetőek ezek a műveletek). A menüpontra kattintva az Object Inspector-ban adhatók meg a menüpontok tulajdonságai, pl. a nevük, a Caption (ez a szöveg jelenik meg a menüpontban, figyeljük meg, hogy a & karakter után lévő karakter aláhúzással jelölődik, és az alkalmazás megnyitásakor alt + aláhúzott betű lenyomásával aktivizálódik), de képet is adhatunk meg a menüponthoz. Valamennyi menüpontnak az OnClick eseményére lehet kötni az eljárást, amit végre kell hajtania. 5. ábra 8

A MainMenu mellett találunk egy ActionList komponenst, ami arra hivatott, hogy azokat a feladatokat tartsuk nyilván vele, amit az alkalmazás több pontjáról is indíthatunk. Vegyük például az új ablak létrehozását, aminek van menüpontja a főmenüben, de az eszköztáron is találunk ilyen gombot. Ha rákattintunk az eszköztár első gombjára, akkor az Object Inspector Action tulajdonsága mellett a FileNew1 nevet látjuk. Ugyanez a hivatkozás látható a főmenü File New menüpontjánál (szintén Action property). A FileNew1 az ActionList komponens egyik listaelemére hivatkozik, amit a komponensre duplát kattintva, a File kategórában találsz (5. ábra). Kijelölve a FileNew1 elemet, az Object Inspectorban látható, hogy a Caption, Enabled, HelpContext, Hint, ImageIndex, Shortcut és Visible tulajdonságok és az OnExecute esemény beállítható. Ha egy menüponthoz vagy gombhoz ezek után hozzárendeljük az egyik ActionList elemet, akkor ezek a tulajdonságok automatikusan beíródnak és nem kell egyenként állítgatni őket. Figyeljük meg, hány menüpontnál használja még az alkalmazásunk az ActionList-et! Az ImageList komponensre kettőt kattintva már látható, hogy mire való: ikonképeket lehet betölteni bele, amire hivatkozhatunk az eszköztár gombjainál és a menüpontoknál az ImageIndex tulajdonság használatával. Ez főleg akkor hasznos, ha egy képet több helyen is felhasználunk, hiszen csak egyszer kell eltárolni, így a programunk kevesebb tárhelyet igényel (bár ezek a képecskék elég aprók, de sok kicsi sokra megy). Megemlíthető még a form legalján található Statusbar (státuszsor) komponens, amivel nemsokára részletesebben is foglalkozunk. Az ablakokon még sok minden nem úgy néz ki, ahogyan majd azt az éles alkalmazásunkban szeretnénk, de ezekkel majd a későbbiekben foglalkozunk. c) MDI függvények és használatuk Van néhány hasznos metódus és tulajdonság, amelyek kizárólag az MDI ablakokhoz kapcsolódnak: Az ActiveMDIChild az MDI keretform futásidejű, csak olvasható tulajdonsága, amely az egyetlen aktív gyermekablakot adja vissza. A programon belül ennek változtatása a Next vagy a Previous eljárások használatával érhető el. A Next a belső sorrenden belül az aktívat követő gyerekablakot helyezi előtérbe, míg a Previous a megelőzőt. A ClientHandle tulajdonság a főform belső területét fedő MDI ügyfélablak Windows leíróját tartalmazza. Ezt kell használnunk pl. amikor egy képet akarunk felrakni a keretform hátterének. MDIChildCount tulajdonság, ahogyan arról már volt szó, a gyerekablakok aktuális számát adja meg. Az MDIChildren tulajdonság a gyermekablakok tömbje. Ezt és az előző tulajdonságot a gyermekablakok közötti mozgásra használhatjuk, például egy for ciklusban. Csoportmunka Figyeld meg a kódszerkesztőben a Delphi által generált kódot! Csapatmunkában nagyon fontos, hogy amikor más kódját vagy kénytelen böngészni, akkor az ismerős legyen. Ennek egyik legfontosabb beállítása a behúzás vagy indent. Akár tabulátornak is nevezhetnénk, de ez veszélyes is lehet, ha valaki a TAB billentyűhöz rendelné gondolatban az indent fogalmát. 9

Ahogyan a Delphi által generált kódban is láthatod, az alapértelmezett behúzás két szóköz. Ha bármelyik profik által megírt programot nézed meg, ezzel a konvencióval találkozol. Ez tulajdonképpen azt jelenti, hogy amikor új sort kezdesz, ami új szakaszhoz tartozik, akkor két szóközzel mindig beljebb kezded, mint az előző sort. Ezután alkalmazd Te is ezt a konvenciót az általad írt programokban. Természetesen a -end blokkok, a kód strukturáltsága amivel már előző félévben foglalkoztunk továbbra is nagyon fontos az olvashatóság szempontjából. Kötelező feladatok 1. A programot, amit írni fogsz magyar emberek fogják használni ezért nagyon fontos, hogy magyar nyelvű felülettel találkozzanak. Magyaríts meg mindent az alkalmazásodban, amivel a felhasználó kapcsolatba kerülhet! Menüpontok, hintek, az ablakok címsorai stb., és ne feledkezz meg a project nevéről sem, amely mint az alkalmazás futtatható állományának neve fog megjelenni! 2. Találd ki, hogy a Childwin unitban miért van szükség a FormClose eljárásban az Action := cafree; kódra! 3. Írj egy rövid metódust az MDI alkalmazásodhoz, ami megnyit 5 ablakot, majd sorban aktívvá teszi őket 5-5 másodpercre! 4. Írj egy olyan ciklust, ami a főablak minden megnyitott gyerekablakát bezárja! A ciklusban használd az MDIChildCount függvényt! 5. Hol van definiálva a Keretform Windows Cascade menüpontjára végrehajtódó eljárás? 6. Alakítsd át egy múlt félévbeli alkalmazásodat MDI alkalmazássá újraírás nélkül! (Legalább két form kell hozzá, és használd a FormStyle tulajdonságot!) Szorgalmi feladatok * 1. Készíts egy egyszerű, Jegyzettömbhöz (Notepad) hasonló szövegszerkesztő alkalmazást! 2. Készíts olyan MDI alkalmazást, amelynél a főablak háttere tetszőleges.bmp kiterjesztésű képfájl lehet és a felhasználó beállíthatja a háttérképet! A megoldásban segítséget nyújt Marco Cantú Delphi 5 című könyvének (2000, Kiskapu) első kötete (8. fejezet). A kész alkalmazást teszteld alaposan! * Ha szorgalmi feladatot oldottál meg, mindenképpen küldd el a teljes kódot a varal@thor.agr.unideb.hu vagy a salga@thor.agr.unideb.hu címek valamelyikére. A beküldött megoldásokat értékeljük, és év végén szerény anyagi jutalmat, és nagy erkölcsi elismerést kapnak a legjobbak! 10

3. Öröklődés, ősök a) Objektumorientált programozás Bár az előző félévben már volt róla szó, most átismételjük az objektumorientált szemlélet néhány alapfogalmát. Az osztály (class) egy programozó által definiált adattípus, melynek van megjelenése és vannak műveletei. Az osztályoknak vannak belső adatai és metódusai (függvények vagy eljárások). Általában akkor érdemes egy osztályt létrehoznunk, ha több hasonló objektumot akarunk csoportosítani benne. Az objektum (object) az osztály egy példánya (instance) vagy az egy, az osztály által meghatározott típusú változó. A program futása közben az objektumok memóriát foglalnak le belső leírásuk számára. Az objektumok és az osztály kapcsolatát leginkább a változók és adattípus kapcsolathoz hasonlíthatjuk. Az osztálydeklarálás módja: type TEnOsztalyom = class Nev, Cim: String; procedure Beallit (n, c: String); function HanyBetusANeve: Integer; A Delphiben minden osztály és típus neve elé hagyományőrző módon T (type) betűt szokás tenni. A csapatmunka támogatására, de saját kódod olvashatóságának növelésére is érdemes ezt a konvenciót alkalmaznod. Most akkor csináljunk egy új objektumot, ami természetesen a fent deklarált osztály tagja lesz: var EnObjektumom : TEnOsztalyom; //létrehozás EnObjektumom:= TEnOsztalyom.Create; //használjuk EnObjektumom.Beallit( Első, Ez a címe ); ShowMessage( Ez egy + IntToStr(EnObjektumom.HanyBetusANeve) + karakteres objektum. ); //felszabadítás EnObjektumom.Free; Az EnObjektumom.HanyBetusANeve függvényhívás egy kicsit más, mint az EnObjektumom.Nev adatelérés, bár formátumban ugyanúgy néznek ki, ez egy hatékony kényelmi funkció a Delphiben. A Delphiben az osztály létrehozásakor nem jön létre automatikusan az osztály egy példánya, létre kell hoznunk, és amikor létrehozzuk, akkor egy hivatkozás jön 11

létre, amely az objektum helyét jelöli a memóriában (objektumhivatkozási modell). Tehát, amikor deklarálunk egy változót, nem jön létre az új objektum, kizárólag az objektumra mutató hivatkozás számára foglaljuk le a memóriát. Az általunk definiált objektumpéldányokat nekünk kell létrehoznunk a konstruktorukkal, ami a Create metódus. Hogy gyakoroljuk és elmélyítsük néhány fontos fogalom használatát egészítsük ki az előző fejezetbeli MDI alkalmazást úgy, hogy a gyerekformok egérkattintásra gombokat hozzanak létre dinamikusan a felületükön (6. ábra). 1. ábra procedure TMDIGyerek.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var Gomb: TButton; Gomb:= TButton.Create(self); Gomb.Parent:= self; Gomb.Left:= X; Gomb.Top:= Y; Gomb.Width:= Gomb.Width + 80; Gomb.Caption:= Format('Egy gomb a %d, %d pozíción', [X, Y]); Ne felejtsük el felvenni a uses listára a SysUtils unitot, mert ebben van definiálva a Format függvény (hogy mi hol van definiálva, arról legegyszerűbben a 12

Help-ből tájékozódhatunk). Le kell vennünk még az MDIChild-ról a Memo komponenst, hogy hozzáférjünk a keretform munkafelületéhez. Vegyük észre, hogy a MDIGyerek (az MDIChild neveződött át az előző fejezetben erre a névre) helyett a kódban a Self kulcsszót használtuk, ezzel hivatkozunk az aktuális objektumra. Általában nem tapasztalnánk változást, ha a selfet a konkrét form nevére módosítanánk, de ha több példányt is használunk, mint azt itt az MDI alkalmazásunkban tesszük, akkor egyszerre nem tudunk a kódban több példányt megnevezni, és mindig a megnevezett formon jelennének meg a gombok, ezért nagyon hasznos a Self kulcsszó. A Create konstruktor feladata, hogy memóriát foglaljon le az objektum (az osztály egy példánya) számára. A konstruktor által visszaadott példányt hozzárendelhetjük egy változóhoz (Gomb:= TButton.Create(self);), így a későbbiekben használhatjuk. A Create konstruktor minden objektumok ősének a TObject objektumnak a konstruktora, és mivel miden objektum a TObjectből öröklődik, öröklik a Create metódust is. Az alapértelmezett Create konstruktor az új példány minden adatát nullára állítja. Ha nem nulla kezdőértékekkel szeretnénk objektumot létrehozni, akkor saját konstruktort kell írnunk. Talán felmerült benned, hogy ha létrehozunk valamit, akkor azt ha már nem használjuk el is kell tűntetnünk. Szerencsére a Delphiben nem lehet hosszú távon szemetelni a memóriába, mert a nem használt objektumokat felszabadítja a memóriából a rendszer. De azért nem szabad felelőtlenül kezelni az általunk létrehozott objektumokat, hanem ha már nincsen rájuk szükségünk be kell dobnunk őket a virtuális kukába. Destruktornak nevezzük azt az eljárást, amely felszabadítja az objektumot a memóriából. Ez általában a TObject-ből származó destroy metódus. Nem ajánlott viszont a destroy-t használni, csak kivételes esetekben. Használjuk inkább a Free metódust, amely csak abban az esetben hívja meg a destroy-t, ha az objektum létezik (vagyis nem nil). A Free nem állítja automatikusan nil-re a objektum értékét, mivel az objektum nem tudja, hogy mely változók hivatkoznak rá, így nem is tudja nilre állítani azokat. Ezt a nagy hiányosságot a FreeAndNil(TObject) metódus hívásával tudjuk kiküszöbölni, ami nemcsak felszabadítja, de nil-re is állítja az objektum hivatkozásait. b) Öröklődés Az objektumorientált programozás lényege, hogy a korábban már megírt osztály módosított változatát használni tudjuk. Ezt nevezzük örököltetésnek, ami a biológiából vett fogalom, de jól előrejelzi az öröklődés tulajdonságait. A legegyszerűbb az lenne, ha a módosítást az eredeti osztály kódjába írjuk bele, viszont akkor az eredeti osztályt az eredeti formájában nem tudjuk többé használni. Logikusan gondolkodva, hogy mindkét osztályt használni tudjuk, először készítsünk másolatot az eredeti osztályról, utána változtassuk meg a másolat kódját, majd mentsük el más néven. Az így létrehozott kód működik, de ha egy új metódust akarunk implementálni, mind az eredeti mind a másolt osztályba, akkor mindkét osztály kódjához hozzá kell nyúlnunk. Az öröklődés megoldja ezeket a problémákat. Az öröklést már sokkal gyakrabban használtad, mint gondolnád. Ha például belenézel az MDIGyerek kódjába, akkor a következő deklarációs rész egy öröklés: 13

type TMDIGyerek = class(tform) Azaz a TMDIGyerek osztály örökli a TForm osztály összes metódusát, mezőjét, tulajdonságát és eseményét. A TForm összes nyilvános metódusát alkalmazhatjuk a a TMDIGyerek osztály példányaira is. Ennek segítségével egy formot származtathatunk egyszerűen egy másik formból, majd kiegészíthetjük azt új komponensekkel, illetve módosíthatjuk a meglévő komponensek tulajdonságait. Ha olyan alkalmazást szeretnénk írni, amely sok ablakot tartalmaz és ezek között sok hasonló van (a kölcsönző programunk éppen ilyen), akkor létrehozhatunk egy alapformot olyan komponensekkel, amelyek mindegyik ablakon rajta lesznek, megfelelő eseménykezelő eljárásokat definiálhatunk. Az objektumorientált programozás legfontosabb előnye, hogy ha lecseréljük vagy megváltoztatjuk az eredeti formot, amiből örököltettük a többit, akkor a származtatott formokon is érvényesülnek a változások. c) Származtatás az alapformból Az MDI alkalmazásunkból először tisztítsuk ki azt a kódot, amit az imént raktunk bele, vagyis az egérkattintásra megjelenő gombokat. Erre a funkcióra természetesen nem lesz szükségünk a kölcsönző-programban. Viszont a Memo komponens se szükséges a gyerekablakok felületére. Ezek után alakítsd a gyerekablakot olyan jellegűre, amint azt a 7. ábrán láthatod. 2. ábra A gombok TBitBtn komponensek, figyeld meg rajtuk, hogy a Caption első betűi alá vannak húzva. Ezek a betűk gyorsbillentyűként működnek, ha például 14

megnyomod az ALT+A billentyűkombinációt, akkor az Adatmentés gomb aktiválódik. Ennek megvalósítása hasonlóan történik, mint azt a TMainMenu komponensnél láthattuk. A gombok fölött egy DBGrid komponens található, amit a Data Controls palettán találsz a Delphiben. Ebben a gridben jelennek meg majd az adatbázis adatai, és itt lehet majd szerkeszteni, törölni őket vagy éppen egy új rekordot hozzájuk adni. Ezután írjuk meg a Kilépés gomb kattintásra végrehajtódó eseménykezelőjét: procedure TMDIGyerek.btnKilepesClick(Sender: TObject); if MessageDlg('Valóban be akarod zárni az ablakot?', mtconfirmation, [mbyes, mbno], 0) = mryes then Close else ShowMessage('Akkor meg ne nyomogasd a "Kilépés" gombot!'); Ezután futtassuk a programot és nézzük meg az eredményt. Mivel ősformot készítünk, amelynek örököltetett példányait fogjuk majd használni alkalmazásunkban, ezért nagyon fontos, hogy csak a tökéletes kinézettel elégedjünk meg. Ha például valami 8. ábrához hasonlót látunk, akkor vegyük észre, hogy a gombok a gyerekablak alján a form átméretezésével elég szokatlan helyre kerülhetnek. 3. ábra 15

Ennek kiküszöbölésére használjuk a gombok Anchors propertyjét, és ami még hasznosabb: a TPanel komponenst. A Standard fülön található TPanel komponenst akkor fogjuk a legjobban értékelni, ha több részből álló formokkal akarunk dolgozni. A komponensek csoportosításánál, a Splitter-rel történő méretezésnél, átméretezésnél előforduló torzulási problémáknál mutatkozik meg az igazi ereje ennek a komponensnek. A Panel komponenst, tegyük a gombok alá, ügyelve arra, hogy kitöröljük a Caption tulajdonságához rendelt szöveget (Panel1), mert az igencsak csúnyán mutatna, ha az ablak átméretezésnél az egyik gom alól kikandikálna a felirat. Az ablak beállításánál ügyelj még a komponensek bejárási sorredjére (Taborder tulajdonságok) és ha kedved tartja kiegészítheted az OnClose eseménykezelőt is egy kérdéssel, amiben meggyőződsz, hogy komoly kilépési szándékkal nyomogatja-e a felhasználó az ablak címsorában lévő (X) bezárás gombot. Ha ezek után úgy érzed, hogy az ablakod tökéletes, akkor el is kezdhetjük az ősform elkészítését és a származtatást. A legtöbb Delphi könyv ehelyütt leírja, hogy hogyan kell az Object Repositoryhoz új elemeket - jelen esetben formokat adni (Tools Repository ). Valójában sokkal egyszerűbb a helyzet, ha csak örököltetni akarunk. Nyissuk meg a File New menüpontot és lépjünk át a project-ünk nevét viselő oldalra (9. ábra). 4. ábra Az alkalmazásunk összes formját megtalálhatjuk itt, és kiválasztva a formot majd megnyomva az OK gombot (csak az Inherit opció aktív, de nekünk nem is kell más, mivel örököltetni akarunk), már el is készült az első örököltetett ablakunk (10. ábra). 16

5. ábra A szép, új gyerekablakunk örökölte az őse összes tulajdonságát. Itt az ideje, hogy leteszteljük, valóban működik-e az objektum-orientált programozás a Delphiben. Változtassunk meg az ősformon (ezután Ős) valamit, pl. a gomb méretét (a gyerekformon (ezután Gyerek) vele együtt változik a tulajdonság), rakjunk fel új komponenst, majd töröljük, stb. Folyamodjunk cselszövéshez: változtassuk meg a Gyereken az Adatmentés gomb Height propertyjét 35 pontra. Ezután térjünk vissza az ősre és állítsuk ott az Adatmentés gomb Height tulajdonságát 15 pontra. Nézzük meg a Gyereket!... Valami érdekes történt, a gyereken nem változott a property értéke. Próbáljuk a Width propertyt nagyobbra állítani: a Gyereken az Adatmentés gomb Width propertyje szolgai módon követi a változást. Hogy is van ez? Jegyezzük meg, hogy ha megváltoztattuk egy örökölt komponens valamely tulajdonságát, és később ugyanezt a tulajdonságot módosítjuk az eredeti komponensnél, akkor a változtatás az örökölt komponensben nem jelenik meg. Természetesen a nem változtatott tulajdonságok továbbra is öröklődnek. 6. ábra 17

Van azonban mód a szinkronizálásra. Ha visszatérünk a Gyerekhez és az Adatmentés gombra kattintva az Object Inspector helyi menüjében a Height propertynél kiválasztjuk a Revert to inherited menüpontot, a tulajdonság visszaállítódik az eredetire (11. ábra). Amit még megtehetünk, hogy az Őst valami Őshöz méltó névre kereszteljük át, pl. OsGyerek MDIGyerek helyett. Csoportmunka Miért van szükség kódolási konvenciókra? A cél, hogy az egy projectben dolgozók olyan forráskódot készítsenek, amely a többiek által is könnyen átlátható és szükség esetén gyorsan javítható. Ehhez szükséges néhány alapelv bevezetése a program szintaxisára vonatkozólag és célszerű néhány alapvető programozási technikával kapcsolatos dologban is hasonlóan gondolkozni/dolgozni. Természetesen ez nem jelenti azt, hogy nem lehetnek mindenkinek egyéni ötletei egy adott probléma implementálását illetően, de ha ezt olyan formában készíti el, hogy mindenkinek már ránézésre ismerős legyen a kód, akkor sokkal hatékonyabb lesz a csapatmunka. Általános elvek: - Szóközt használjunk tabulátor helyett, szintenként kettőt; - Ne írjunk 80 karakternél hosszabb sorokat; hosszú kifejezéseknél a következő sort bentebb kezdjük (2 szóközzel!) - Lehetőleg minden függvény férjen bele egy képernyőbe - Megjegyzések írása: először is írjunk minden hosszabb ill. nem triviális függvényhez, eljáráshoz vagy akár ciklushoz megjegyzést, amiből egyértelműen kiderül, hogy mi a feladata az adott kódrészletnek; - Írjunk minden Delphi reserved és keyword-öt kisbetűvel; A következő fejezetek Csoportmunka bekezdéseiben a kódolási konvenciók ajánlott formátumát fogjuk részletezni. Kötelező feladatok 1. Örököltess az MDIGyerek formból egy példányt, ez után írd úgy át a kódot, hogy a származtatott példány az MDIKeret származtatott példánya legyen! 2. Az előbbi feladatban kézzel származtatott osztálynak írj egy konstruktort, ami bizonyos tulajdonságokat adott értékekre állít be, ezután szúrj be egy új menüpontot a Fájl menübe, amire rákötöd újonnan létrehozott konstruktorunkat. Nézd meg futás közben hogy néz ki, amit elkövettél! 3. Az új formod bezárásánál próbáld ki azokat a memória-felszabadítási lehetőségeket, amelyekről ebben a fejezetben tanultál! 4. Írj egy osztályt, ami bemeneti értékként egy személy magasságát kéri centiméterben, majd visszaadja azt méterben! 5. Lazíts! Menj ki a szabadba, sétálj egyet, vagy nézz meg egy filmet a kedvenceid közül! Megérdemled! 18

Szorgalmi feladatok 1. Készítsd el a gerincesek törzsének osztályhierarchiáját! A rendek és osztályok legyenek egy-egy osztály, definiálj hozzájuk metódusokat (pl. repül), függvényeket (megeszi_e(tgerinces) : boolean), és tulajdonságokat (szcsíkos). Származtass egy példányt valamelyik osztályból, és keltsd életre! 19

4. Komponensek a) Bevezető Sok Delphi-programozó a készen kapott Delphi-s komponenseket használja, de sokszor szükség lehet a meglévő komponensek módosítására, vagy teljesen új komponensek írására a munka egyszerűbbé tételére. Amikor egy új komponenst készítünk, akkor mindig a VCL (Visual Component Library) egy már meglévő osztályát bővítjük ki. Ehhez az Object Pascal nyelv számos olyan tulajdonságát használni kell, amelyekre a kész komponensek írásakor ritkán van szükség. Nem szabad azonban megijedned a feladattól, és ha problémákba ütközöl, akkor lapozz fel egy Object Pascal referenciát, vagy a Delphi Help-et segítségért. A Delphi komponenseket osztályoknak is tekinthetjük, a VCL pedig nem más, mint a Delphi osztályokat leíró komponensek gyűjteménye. Minden alkalommal, amikor egy komponenseket tartalmazó új csomagot (package) adunk a Delphihez, valójában a VCL-t bővítjük ki egy újabb osztállyal. Az új osztály természetesen mindig egy már létező komponens osztályának leszármazottja lesz (a létező komponens osztálya az ős), annak örökölt tulajdonságait bővíti ki új lehetőségekkel. A fentiekből sejthető, hogy ebben a fejezetben nagyrészt az előző fejezetben tanultakra támaszkodunk. b) Komponenscsomagok A komponensek a Delphiben úgynevezett komponenscsomagokba kerülnek. Minden komponenscsomagnak BPL (Borland Package Library) a kiterjesztése, ami mellesleg egy DLL * (dinamikus csatolású könyvtár) csak álruhában. A csomagoknak két formája van: fejlesztési idejű (design time) komponenscsomagok, ezeket fejlesztési időben csak a Delphi használja, és a futásidejűek (run-time), amelyek a kész alkalmazásokhoz (is) kapcsolódnak. A $DESIGNONLY vagy $RUNONLY kapcsolók határozzák meg a csomag típusát. Amikor egy csomagot telepítünk, akkor az IDE ellenőrzi, hogy melyik kapcsolót használtuk, és eldönti, hogy a felhasználó telepítheti-e a csomagot és hogy azt hozzá kell-e adni a futásidejű csomagok listájához. Mivel a két kapcsoló nem zárja ki kölcsönösen egymást, ezért négy típus van, két általánosabb és két különlegesebb változat: A fejlesztési idejű komponensek telepíthetőek a Delphi fejlesztői környezetébe. Rendszerint a komponens tervezési idejű részeit, a tulajdonságszerkesztőket és a regisztrációs kódot tartalmazzák. A tervezési idejű csomagok komponenseinek kódja rendszerint statikusan szerkesztődik be a futtatható állományba, a megfelelő DCU (Delphi Compiled Unit) fájl kódjának felhasználásával. A statikus beszerkesztés vagy statikus kötés azt * A DLL-ek futtatható állományok, amelyek függvényeket és osztályokat tartalmaznak. Ezeket programok illetve más dll-ek használhatják futásidőben. Legfőbb előnyük, hogy ha ugyanarra a dll-re egyszerre több programnak is szüksége van, annak csak egy példányát kell tárolnunk a háttértárolón, és a futtatható állomány mérete is kisebb lesz. Másik előnyük, hogy egy több modulból álló rendszer részeit dll-ekbe fordítva könnyedén tudjuk a rendszerünket a dll-ek másolgatásával is testreszabni. A jegyzet egy külön fejezetében fogunk majd foglalkozni a dll-ek készítésével. 20