VYSOKÁ ŠKOLA BÁŇSKÁ ŠKOLÍCÍ STŘEDISKO STUDIUM K VÝKONU SPECIALIZAČNÍCH ČINNOSTÍ ICT KOORDINÁTORA Závěrečná práce Název práce: Distanční opora pro výuku Delphi Objektově orientované programování 1. díl Autor práce: Ing. Radim Štefan Vedoucí práce: Mgr. Anna Martinková Ostrava 2007-1 -
Název práce: Distanční opora pro výuku Delphi Objektově orientované programování 1. díl Autor práce: Mgr. Anna Martinková Vedoucí práce: Mgr. Anna Martinková Počet stran: 50 Závěrečná práce specializačního studia ICT koordinátora. Ing. Radim Štefan VŠB v Ostravě Porubě - 2 -
Prohlašuji, že předložená práce je mým původním autorským dílem, které jsem vypracoval samostatně. Veškerou literaturu a další zdroje, z nichž jsem při zpracování čerpal, v práci řádně cituji a jsou uvedeny v seznamu použité literatury. Ostrava 2007 podpis - 3 -
Obsah 1 VYSVĚTLIVKY K POUŽÍVANÝM SYMBOLŮM... 5 2 ÚVODNÍ SLOVO... 6 3 CÍLE PŘEDMĚTU... 7 4 DELPHI... 8 4.1 ZÁKLADNÍ TYPY POUŽITÉ V DELPHI... 8 4.2 VÝVOJOVÉ PROSTŘEDÍ DELPHI... 11 4.2.1 Projekt... 11 4.2.2 Spuštění vývojového prostředí Delphi... 12 4.2.3 Základní ovládání vývojového prostředí... 13 4.2.4 Nový projekt a základní operace... 14 4.2.5 Pár prvních zásad... 15 4.3 OBJEKTOVÉ PROGRAMOVÁNÍ... 16 4.3.1 Objekt... 16 4.3.2 Pravá kompilace... 17 4.4 PRVNÍ APLIKACE... 18 4.4.1 Vlastnosti formuláře... 18 4.5 PRVNÍ OBJEKTY NA FORMULÁŘI... 21 4.5.1 Použití nevizuálního objektu... 30 4.5.2 Jednoduchý poznámkový blok... 37 4.5.3 Jednoduchá kalkulačka... 43 5 ZÁVĚR... 50-4 -
1 Vysvětlivky k používaným symbolům Průvodce studiem komunikace autora se studentem. Navrhuje způsob práce s textem, povzbuzuje studujícího a doplňuje text o další informace. Příklad slouží k objasnění probíraného tématu, nebo k jeho procvičování. Pojmy k zapamatování upozorňuje na důležité informace, které je potřeba si zapamatovat pro pochopení dalších témat. Shrnutí souhrn základních informací z předcházející látky. Většinou se týká shrnutí kapitoly. Literatura použitá ve studijním materiálu. Kontrolní otázky a úkoly prověřují, do jaké míry byly text a problematika pochopeny a zda student dokáže nové znalosti vhodně aplikovat při řešení problémů. Korespondenční úkoly představují úkoly, které studenti samostatně řeší a posílají ke kontrole vyučujícímu. Úkoly k zamyšlení slouží především k aplikování získaných znalostí. Cíl stanovuje cíl, kterého by mělo být dosaženo po nastudování a procvičení příslušné části. Čas časový odhad pro nastudování příslušné části. Je jen orientační. Poznámka nebo důležitá informace. - 5 -
2 Úvodní slovo Vážená studentko, vážený studente, tento výukový text navazuje na distanční text Úvod do algoritmizace a programování. Než začnete dále studovat, je vhodné si zopakovat výše jmenovaný distanční text. Předpokládá se alespoň základní znalost algoritmizace jazyka Pascal a angličtiny. Oproti BP 1 se budeme věnovat objektovému programování, které je řízené událostmi 2. To bude od vás znamenat nový pohled na programování. V praxi se stále setkávám s názory, že programovat v jazyce Pascal je v dnešní době přežitek a jedině jazyk C má význam. Jenže vy (středoškolští studenti) máte při výuce programování obrovské problémy. Nejste zvyklí na způsob myšlení, který je při programování nutný. Musíte zvládnout syntaxi jazyka (Pascal je velice čtivý a přehledný), syntaktickou stavbu programu, k tomu analýzu a syntézu řešeného problému a nakonec logickou stavbu programu. K tomu všemu patří i hledání chyb v programu a jejich odstraňování. Pro výuku lze použít Borland Delphi, jehož některé verze lze pro potřeby výuky použít zdarma jen po registraci. Těmto verzím sice chybí některé objekty (komponenty), ale na Internetu existují alternativní a jsou free. Programování je nutné studovat opravdu systematicky a uvedené příklady (řešené i neřešené) se snažit samostatně řešit. V případě nejasností je důležité vracet se k příkladům i vícekrát. Musíte mít hodně trpělivosti a nevzdávat se při počátečních neúspěších. Někdy může trvat relativně dost dlouho, než začnete chápat souvislosti. [1] KOSTOLÁNYOVÁ, K. Algoritmizace a řešení problémů. Ostrava: OU v Ostravě, 2002, ISBN 80-7042-227-0 [2] TEIXEIRA, S., PACHECO, X. Mistrovství v Delphi 6. Praha: Computer Press, 2002, ISBN 80-7226-627-6 [3] KADLES, V. Delphi Hotová řešení. Brno: Computer Press, 2003, ISBN 80-251-0017-0 [4] SVOBODA, L., A KOL. J. 1001 tipů a triků pro Delphi. Praha: Computer Press, 2001, ISBN 80-7226-529-6 [5] ŠTEFAN, R. Programovaní. Ostrava: OU v Ostravě, 2002, SBN 80-7042-254-8 [6] ŠTEFAN, R. Úvod do algoritmizace a programování. Opava: SU v Opavě, 2006 [7] ŠTEFAN, R. Autorské systémy. Ostrava: OU v Ostravě, 2002, ISBN 80-7042-253-X Přeji Vám mnoho úspěchů ve studiu. Radim Štefan 1 BP Borland Pascal 2 Bude vysvětleno dále - 6 -
3 Cíle předmětu Cíle předmětu: po prostudování textu a příkladů budete znát a umět: Vytvářet jednoduché projekty ve vývojovém prostředí Delphi. Pracovat s vizuálními a nevizuálními objekty. Aplikovat své znalosti algoritmů do projektů. Vytvářet jednoduché programy. Získáte: Zvýšíte si schopnost analýzy a řešení problémů. Prohloubíte si logické myšlení. Budete schopni: Přesněji formulovat požadavky. Čas potřebný k prostudování učiva předmětu: 24 vyučovací hodiny 3 3 Není započten čas potřebný na samostatné a korespondenční práce. - 7 -
4 Delphi 4.1 Základní typy použité v Delphi Cíl Po prostudování oddílu 3.1 budete umět vysvětlit rozdíl mezi typy BP a Delphi. Klíčová slova Typy, proměnná, deklarace, celočíselná typ, typ s pohyblivou řádovou čárkou, integer, byte, single, int64. Čas potřebný k prostudování učiva oddílu 2 vyučovací hodiny. Delphi, prostředí, se kterým budeme pracovat, je 32bitové prostředí. Borland Pascal, který jsme dosud používali, je 16bitové prostředí. Z toho taky vyplývají určité změny v deklarovaných typech. Tabulka 1 ukazuje na celočíselné typy použité v prostředí Delphi. Tučně jsou zvýrazněné buď změněné, nebo nové typy. Levý sloupec Rozsah ukazuje rozsah jak je deklarován v Pascalu a pravý podle matematických pravidel. Poslední sloupec ukazuje velikost v bytech. Celočíselné typy v Delphi Type Rozsah Shortint 128..127 < 128, 127> 1 B Byte 0..255 <0, 255> 1 B Smallint 4 32768..32767 < 32768, 32767> 2 B Integer 5 2147483648..2147483647 < 2147483648, 2147483647> 4 B Longint 2147483648..2147483647 < 2147483648, 2147483647> 4 B Word 6 0..4294967295 <0, 4294967295> 4 B Longword 3 0..4294967295 <0, 4294967295> 4 B Cardinal 3 0..4294967295 <0, 4294967295> 4 B Int64 7-2 63 +1..2 63-1 <-2 63 +1, 2 63-1> -9,2*10 18.. 9,2*10 18 <-9,2*10 18, 9,2*10 18 > 8 B Tabulka 1 4 V BP původní rozsah ty Integer 5 Integer má nový rozsah stejný jako Longint v BP 6 Nové typy v Delphi 7 Nový typ, který má rozsah jako typ Comp, ale narozdíl od Comp je ordinální (výčtový) typ. To znamená např., že tento typ lze použít jako řídící proměnné cyklu. - 8 -
Typy s pohyblivou řádovou čárkou 1. Type Min. hranice Max. hodnota Číslice Real48 8 2.9x10 39 1.7x10 38 11 12 6 B Single 1.5x10 45 3.4 x 10 38 7 8 4 B Double 5.0x10 324 1.7x10 308 15 16 8 B Extended 3.6x10 4951 1.1x10 4932 19 20 10 B Real 9 5.0x10 324 1.7x10 308 15 16 8 B Tabulka 2 Typy s pohyblivou řádovou čárkou 2. Type Rozsah Číslice Comp < 2 63 +1, 2 63 1> 19 20 8B Currency 10 < 922337203685477.5808, 922337203685477.5807> 19 20 8B Tabulka 3 Tabulka 2 a Tabulka 3 přehledně ukazují typy čísel s pohyblivou řádovou čárkou, které lze použít pro vědecké výpočty nebo výpočty s měnovými údaji. Výjimku tvoří typ Comp, který je celočíselný, ale není ordinální typ. Tabulka 4 doplňuje základní deklarace, které potřebujeme k programování. Asi nejdůležitější změnou oproti BP jsou nárůsty velikosti typů String a Array. Omezení na 2 GB v obou případech je dostačující pro většinu aplikací. Pole můžeme deklarovat jako statické jedno i více rozměrné, stejně jako v BP. Pro zjištění nejmenšího a největšího indexu pole lze použít funkce Low a High. Která funkce vrátí jakou hodnotu, je vám doufám jasná. Nyní si stručně nastíníme možnosti dynamické deklarace pole. Oproti statické deklaraci, kdy se uvádějí rozměry (interval indexů) v hranaté závorce, se hranatá závorka neuvádí vůbec. Rozměry pole se nastavují až v průběhu programu pomocí procedury SetLength. Existují i jiné dynamické deklarace, ale ty jsou mimo rozsah tohoto kurzu. Příklad 1 Var A1: array[1..100] of integer; statická deklarace jednorozměrného pole A2: array[1..10,1..100] of integer; statická deklarace dvourozměrného pole A3: array[1..10] of array[1..100] of integer; statická deklarace dvourozměrného pole B1: array of integer; dynamická deklarace jednorozměrného pole B3: array of array of integer; dynamická deklarace dvourozměrného pole 8 Kompatibilní s typem REAL v BP. Není podporován matematickým procesorem. 9 Stejný rozsah jako Double. 10 Použití především pro práci s údaji obsahující měny. - 9 -
Deklarace A2 a A3 jsou zcela totožné jen jiný zápis. U deklarací dynamických polí B1 a B3 je nutné před prvním použití nastavit velikost: Begin SetLength(B1, 100); SetLength(B2, 10, 100); End; Výhodou dynamických polí je, že nastavujeme velikost pole až podle skutečné potřeby v programu. Je však nutné si uvědomit, že v těchto případech indexování začíná vždy od 0. Textové a další typy. Type Max. délka Obsazení paměti Použití String S direktivou 11 {$H+} = AnsiString S direktivou {$H-} = ShortString ShortString 255 zn. 2 256 bytů Kompatibilita s BP AnsiString 2 31 zn. 4 byty 2GB 8bit (ANSI) znaková sada WideString 2 30 zn. 4 byty 2GB Array 12 2 GB pole Unicode znaková sada pro víceuživatelské servery a vícejazyčné aplikace Char 1 zn. 1 B ANSI znaková sada Boolean 1 B Logická proměnná True / False Tabulka 4 Úkol 1 Zopakujte si pravidla pro deklarace proměnných a konstant v BP. 11 Standardně je nastaveno {$H+}. Použití direktiv je stejné jako u PB. Další podrobnosti naleznete v helpu 12 Pole mají mnohem větší rozsah než BP. Navíc existují možnosti deklarace dynamických polí, které však přesahují možnosti tohoto kurzu. - 10 -
4.2 Vývojové prostředí Delphi Cíl Po prostudování oddílu 3.2 dokážete založit nový projekt a budete se umět orientovat v prostředí Delphi. Klíčová slova Projekt, vývojové prostředí, Delphi, formulář, vlastnost, událost. Čas potřebný k prostudování učiva oddílu 2 vyučovací hodiny. 4.2.1 Projekt Než začneme s prvním programem, musíme se seznámit s novým vývojovým prostředím. Změna oproti BP je značná a bude chvíli trvat, než si zvyknete. Nakonec však zjistíte, že v tomto prostředí pracuje velice příjemně. Jako první, co si musíme vysvětlit je, že už nepíšeme program, ale projekt a algoritmy zapisujeme do Unit (jednotek) projektu. Název projektu musí splňovat podmínky pro tvorbu proměnných a uložený projekt má koncovku DPR. Pokud se podíváte, jaký je obsah souboru s koncovkou DPR (projekt), budete asi zklamaní. Obsahuje jen seznam našich Unit a program (příkazy mezi a end) se skládá jen z iniciace (Application.Initialize), vytvoření formuláře 13 nebo formulářů (Application.CreateForm(TForm1, Form1)) a spuštění aplikace (Application.Run). Příklad 2 program dynpole; // název projektu (programu) uses // připojení Unit Forms, // systémová unita pro práci s formuláři Unit1 in 'Unit1.pas' {Form1}; // formulář 1 Unit2 in 'Unit2.pas' {Form2}; // formulář 2 // soubor ve kterém jsou zdroje. Zatím se s ním nebudeme zabývat Application.Initialize; // Iniciace programu Application.CreateForm(TForm1, Form1); // Vytvoření prvního formuláře Application.CreateForm(TForm2, Form2); // Vytvoření druhého formuláře Application.Run; // Spuštění aplikace end. V tomto okamžiku je jasné, že zatím nevíte, o čem je řeč, ale postupně se bude vše vyjasňovat. 13 Formulář je vlastně okno, které známe z Windows. Za chvíli se dozvíte o formuláři více. - 11 -
4.2.2 Spuštění vývojového prostředí Delphi Při spuštění Delphi se buď nastaví prázdný projekt (Obrázek 1), nebo projekt, na kterém se pracovalo minule. Záleží na nastavení, které si ukážeme později. Standardně se objeví prázdný projekt. Máme k dispozici 4 okna. První okno Delphi 6 Project 1 je základní okno vývojového prostředí. Druhé okno je Object TreeView, Object Inspektor. V záložce Object Inspektor (dále jen OI) nastavujeme vlastnosti (Properties) objektů (formulářů, tlačítek, menu, atd.) a události 14 (Events) objektů (kliknutí myši, stisk klávesy, změna rozměru, změna údaje, atd.). Další dvě okna, která mají v názvu Form1 a Unit1.pas, jsou okna, ve kterých programujeme náš projekt. Form1 je komponenta na kterou budeme umisťovat různé objekty a okně Unit1 budeme zapisovat zdrojový kód. Vývojové prostředí Delphi Vývojové prostředí Object Inspectors Vlastnost / Události Formulář Zdrojový kód Obrázek 1 14 Tyto události řídí celý náš program, jak už jsem se zmínil v úvodu. - 12 -
4.2.3 Základní ovládání vývojového prostředí Okno vývojového prostředí se skládá z několika panelů Obrázek 2. Jeden panel je Menu, který obsahuje všechny potřebné položky pro práci v prostředí. My se seznámíme jen s několika, které nutně potřebujeme k práci. Další panely obsahují ikony, které nám urychlí ovládání a poslední největší panel se záložkami obsahuje ikony, které reprezentují objekty (komponenty), které můžeme použít při programování. Okno vývojového prostředí Panel s Menu Panel s řídícími ikonami Panel s objekty Obrázek 2 Základní ovládací ikony Nový projekt Otevření projektu nebo unity Uložení aktuální unity Uložení všeho Přidání/odebrání unity z projektu Překlad a spuštění programu Vytvoření nového formuláře Obrázek 3 Zobrazení formuláře - 13 -
4.2.4 Nový projekt a základní operace Kliknutím na ikonu Nový projekt (New) nebo pomocí Menu-> Files-> Other Aplication vyvoláme okno New Items, kde máme k dispozici galerii různých typů projektů, aplikací, formulářů, knihoven, atd. Nás bude zatím zajímat jen možnost aplikace (Aplication) popř. formulář (Form). Nové položky Obrázek 4 Pro otevření existujícího projektu můžeme použít ikonu (Open). Stejnou ikonu lze použít i pro otevření unit, popř. dalších souborů, které v Delphi existují. Ikona (Save) uloží právě aktuální editovanou unitu a ikona (Save All) uloží všechny změněné unity. Pro vytvoření dalšího formuláře v projektu stačí kliknout na ikonu (New Form). Současně vznikne i unita se stejným číslem jako je číslo formuláře. Poslední pro nás důležitá ikona (Run) spustí překlad, a pokud nebude nalezena syntaktická chyba, spustí i aplikaci. Stejnou službu provede i horká klávesa F9. Poznámka: Spuštění aplikace proběhne jen tehdy, pokud pracujeme s projektem. Studenti občas dělají chybu, že si jen otevřou unitu, a pak spuštění aplikace nefunguje. - 14 -
4.2.5 Pár prvních zásad Než přejdeme k prvním příkladům, stanovíme si několik zásad, které postupně ještě budeme rozšiřovat. Zásady nám umožní rychlejší orientaci v programech kolegů, snadnější vyhledávání syntaktických 15 i logických 16 chyb. 1. Každý projekt uložíme v samostatném adresáři. 2. Unity nebudeme přejmenovávat. Tj. necháme názvy, které navrhne vývojové prostředí. Úkol 2 Vytvořte a uložte několik projektů. Projekty uložte do různých adresářů a vhodně pojmenujte. Vždy si vyzkoušejte funkčnost překladem a spuštěním spustí se vždy okno, které má vlastnosti běžného okna ve Windows. Vyjmenujte vlastnosti formuláře. Všimněte si i rozdílu oproti BP. 15 Syntaktická chyba chyba odhalená překladačem. Chyba v zápisu zdrojového kódu. 16 Logická chyba chyba, kterou překladač neodhalí. Způsobuje neočekávané chování programu při běhu. - 15 -
4.3 Objektové programování Cíl Po prostudování oddílu 3.3. budete umět vysvětlit pojem objekt a jaké jsou vlastnosti. Klíčová slova Objekt, zapouzdření, dědičnost, polymorfismus. Čas potřebný k prostudování učiva oddílu 1 vyučovací hodina. Pokud jste se už těšili, že už začnete psát své první programy, musím vás zklamat. V objektovém programování budeme pracovat s objekty a tak si o nich nejdříve musíme říct aspoň základní informace. 4.3.1 Objekt Vytvoření funkčního formuláře (okna) nás nestálo ani čárku zdrojového kódu. Jedním z důvodů je dědění 17 vlastností okna ze systému. Stejné okno se stejnými vlastnostmi by v BP znamenalo mnoho programátorské práce. S formulářem lze myší posouvat po obrazovce, lze měnit jeho velikost, jsou k dispozici ikony pro maximalizaci a minimalizace formuláře, systémové menu a ikona pro zavření aplikace. Formulář, jak bylo zmíněno výše, dědí své vlastnosti přímo z operačního systému Windows. Důkaz je jednoduchý stačí změnit vlastnosti oken ve Windows a náš formulář je změní také. Jaké vlastnosti má tedy objekt? Jsou tři hlavní vlastnosti, které tvoří základní koncepci objektově orientovaného programování: zapouzdření spojení dat a programového kódu do třídy (Class), dědičnost vytváření nové odvozené (synovské dceřinné) třídy, která dědí vlastnosti rodiče, polymorfismus se synovskou třídou se pracuje stejně jako s třídou rodičovskou. 17 Jedna z vlastností objektů - 16 -
4.3.2 Pravá kompilace V celé řadě vývojových prostředí Windows se generuje spustitelný kód jen jako částečně kompilovaný nebo jako p-kód 18. Takto vytvořený p-kód však žádný počítač nedokáže vykonávat přímo, takže se znovu musí překládat za běhu a to má velký nepříznivý vliv na rychlost zpracování. Představte si, kolik strojového času procesoru se musí zbytečně vynaložit při provádění rutin, které provádějí konverzi kódu! V Delphi je naopak zabudován skutečný kompilátor 19 a linker 20, které jako spustitelný program vytvářejí l00% nativní strojový kód počítače. Tento spustitelný kód již nevyžaduje při provádění žádnou režii. Plnohodnotná kompilace má také další výhodu díky ní můžeme vytvářet dynamicky linkované knihovny (DLL), které mohou obsahovat libovolné komponenty z knihovny komponent. S pomocí těchto knihoven DLL je pak možné dále rozšiřovat aplikace v Delphi, nebo mohou poskytovat určité služby programům, vyvíjeným v jiných vývojových prostředích. Zapamatujte si vlastnosti objektů: zapouzdření, dědičnost a polymorfismus. 18 Takovýto kód potřebuje ke své činnosti program, který zdrojové příkazy postupně vykonává. Typický představitel je Basic (potřebuje tzv. Runtime modul) nebo HTML kód (ke své činnosti potřebuje Internet Explorer nebo jiný prohlížeč). 19 Překladač zdrojového kódu do spustitelného módu. 20 Systém, který připojí k přeloženému zdrojovému kódu potřebné knihovny. - 17 -
4.4 První aplikace Cíl Po prostudování oddílu 3.4 budete umět nastavit některé základní vlastnosti formuláře. Klíčová slova Formulář, properties, object inspector. Čas potřebný k prostudování učiva oddílu 3 vyučovací hodiny. 4.4.1 Vlastnosti formuláře Podle kapitoly 3.2 vytvoříme nový projekt s formulářem. Teď se zaměříme na základní vlastnosti formuláře, které jsou k dispozici v OI. Vlastnosti formuláře Obrázek 5 Vlastnosti jsou v OI seřazeny abecedně. Některé vlastnosti mají více položek, které zobrazíme klinutím na + před vlastností. V následující tabulce je přehled základních vlastností a jejich nastavení formuláře. Ještě než se pustíte do studování tabulky vlastností, musíte vědět, že všechny vlastnosti, které lze nastavit v OI, lze nastavit i za běhu programu! - 18 -
Vlastnosti formuláře Properties Name Caption AutoSize Popis jméno formuláře. Standardně FormXX, kde XX je číslo. Tento údaj měnit nebudeme. název formuláře umístěný na horní liště. velikost formuláře se nastaví tak, že budou viditelné právě všechny objekty na ploše. Pokud nemáme na ploše žádné objekty, dopadl by výsledek překladu a spuštění takhle. Je vidět pouze horní lištu se základními ikonami pro schování aplikace do systémové lišty, ikona pro zvětšení na celou obrazovku (v tomto případě nebude fungovat) a ikona pro ukončení aplikace. Tato vlastnost by se měla nastavovat spíže za běhu programu. ikony, které mají být k dispozici na horní liště aplikace: +BroderIkons BorderStyle Height ClientHeight Width ClientWidth Left Top Color Constraints Enable +Fonts FormStyle bisystemmenu - formulář bude mít k dispozici systémového menu, které se aktivuje kliknutím na ikonu v levém horním rohu na liště aplikace biminimize - ikona uschování aplikace do systémové lišty (minimalizace) bimaximize - ikona pro zvětšení formuláře přes celou obrazovku Styl okraje formuláře: bssizeable standardní okraje s proměnnou velikostí formuláře bsnone formulář nebude mít žádné okraje, ani horní lištu bssingle velikost formuláře není možné měnit myší ani klávesnicí. výška celého formuláře v bodech (v pixlech) včetně okrajů a horní lišty výška vnitřní plochy formuláře v bodech hodí se pro úpravy velikostí a umístění objektů ve formuláři během programu. šířka celého formuláře v bodech včetně okrajů šířka vnitřní plochy formuláře v bodech umístění levé části formuláře na obrazovce v bodech. 0 formulář bude umístěn úplně vlevo obrazovky. umístění horního okraje formuláře v bodech. 0 formulář bude umístěn úplně na vrcholu obrazovky. barva formuláře. Barvu lze vybrat z nabídky barev nebo proměnných, které dědí barvu z Windows. clbtnface standardní barva pozadí formuláře. Nastavení mezních hodnot šířky a výšky formuláře. MaxHeight maximální výška formuláře MaxWidth maximální šířka formuláře MinHeight minimální výška formuláře MinWidth minimální šířka formuláře true formulář je aktivní a aktivní jsou i objekty umístěné na formuláři, false formulář není aktivní (objekty umístěné na ploše formuláře nejsou aktivní nereagují na myš ani klávesnici). nastavení vlastností fontu tohoto formuláře. Objekty, které umístíme na plochu formuláře, zdědí i vlastnosti nastaveného fontu. (U každého objektu lze vlastnosti individuálně měnit pak se dědění ruší). U fontu lze nastavovat tyto hlavní parametry: barvu textu (Color), typ fontu (Name), velikost (Size), styl fontu (tučné, kurzíva, podtržené, ), fsnormal normální styl zobrazování formuláře - 19 -
Hint ShowHint Icon Position Visible TransparentColor TransparentColorValue WindowState Tabulka 5 fsstayontop okno bude umístěno vždy nad ostatními okny text, který bude zobrazen po události 21 onhint. Tato událost vznikne i při umístění kurzoru na objekt. Tzv. bublinová nápověda k objektům. nastavení vlastnosti na true znamená, že pokud se kurzor umístí nad objekt (v tomto případě formulář) zobrazí se na určitou dobu text uvedený v parametru Hint. False nápověda se nezobrazí. nastavení ikony aplikace (levý horní roh formuláře). Vybíráte ze souborů s koncovkou ICO. umístění formuláře na obrazovce po spuštění aplikace. podesigned formulář po spuštění bude umístěn na místo, kde jsme ho umístili při návrhu podesktopcenter formulář bude umístěn uprostřed obrazovky True formulář bude viditelný, False formulář bude neviditelný True pokud se bude barva formuláře rovnat barvě uvedená ve vlastnosti TransparentColorValue, bude zobrazena jako průhledná. Hodnota průhledné barvy formuláře wsnormal okno bude zobrazeno normálně wsmaximized okno se zobrazí přes celou obrazovku wsminimized okno se po spuštění umístí do lišty Příklady k procvičování Příklad 3 1. Vytvořte nový projekt a uložte ho pod názvem Priklad_3. 2. Zajistěte, aby text v horní liště formuláře byl Můj první formulář. 3. Nastavte výšku formuláře na 600 a šířku na 480 bodů. 4. Zrušte možnost okno minimalizovat i maximalizovat. 5. Nastavte minimální možné rozměry okna na hodnotu výšku 500 a šířku 400 bodů. 6. Nastavte maximální možné rozměry okna na hodnotu výšku 800 a šířku 600 bodů. 7. Zajistěte, aby se formulář po spuštění zobrazil uprostřed obrazovky. 8. Nastavte, aby se když kurzor myši umístíte na formulář, se zobrazila bublinová nápověda s textem 22 Toto je bublinová nápověda. 21 Události (Events) budou vysvětleny v následující kapitole. 22 Musíte nastavit dvě vlastnosti. Jedna, že se má nápověda zobrazovat a druhá, vlastní test. - 20 -
4.5 První objekty na formuláři Cíl Po prostudování oddílu 3.5. budete umět vložit na formulář některé vizuální objekty. Klíčová slova Vizuální objekty, nevizuální objekty, Label, OnMouseMove, OnKeyDown, OnKeyUp, IntToStr, Sender, Self. Čas potřebný k prostudování učiva oddílu 4 vyučovací hodiny. Umístění objektu na formulář je velice snadné. Z panelu nástrojů (Obrázek 2) vybereme příslušný objekt kliknutím myši. Pak přesuneme myš nad formulář a kliknutím se vybraný objekt vloží na místo, kam ukazuje kurzor myši. S objekty lze po formuláři pomocí myši nebo kurzorových kláves volně pohybovat. K dispozici jsou vizuální i nevizuální objekty. Nevizuální objekty se zobrazují na formuláři jako ikony, kdežto vizuální přímo vidíme (Obrázek 6). S vizuálními komponentami můžeme po spuštění programu většinou hned pracovat. Činnost nevizuálních komponent aktivujeme až za běhu programu. Vizuální komponenty Editace textu Edit Poznámkový blok Memo Tlačítko Button Vizuální a nevizuální objekty na formuláři Nevizuální komponenty Časovač Timer Dialog pro otevření souboru Dialog pro uložení souboru Obrázek 6 Po překladu a spuštění 23 programu (Obrázek 7) budou na formuláři vidět právě jen vizuální komponenty. Můžeme klikat myší na tlačítko, které dělá animaci zmáčknutí. 23 Dále budu používat jen termín spuštění programu. - 21 -
Když klikneme do některého z editovatelných objektů, objeví se kurzor a můžeme psát. Dokonce můžeme pracovat i se schránkou, jak jsme zvyklí z editorů textu. To je tak vše, co můžeme dělat (kromě běžné práce s oknem, kterou formulář zdědil s oken operačního systému). Formulář po překladu a spuštění programu. Obrázek 7 Aby program začal dělat i něco víc, než jsme si ukázali, je potřeba jednotlivým objektům naprogramovat metody k některým událostem. Např. u tlačítka to bude nejčastěji událost OnClick tj. co se má stát, když klikneme myší na tlačítko. Nyní si ukážeme některé základní a nejčastěji používané objekty a jejich nejdůležitější vlastnosti a události. Začneme se standardními komponentami a jejich stručným popisem. Menu 24 PopupMenu Label Edit Memo komponenta pro vytvoření standardního menu, jak ho známe z většiny programů pod Windows. komponenta nabídkového menu, které se aktivuje kliknutím pravého tlačítka myší na objekt, který je s tímto menu propojen. komponenta pro textový popisek (nápis). komponenta pro editaci jednořádkového textu, např. položky v databázi. komponenta pro editaci souvislého i více řádkového textu obdoba poznámkového bloku. PopupMenu Menu Label Edit Memo GroupBox ScrollBar RadioGroup Panel Obrázek 8 Button CheckBox RadioButton ComboBox ListBox 24 Všechny názvy objektů mají před názvem písmeno T, protože se jedná o typ. V učebním textu jsem toto písmeno vypustil. - 22 -
Button CheckBox RadioButton ListBox ComboBox ScrollBar GroupBox RadioBox Panel komponenta tvořící tlačítko. zaškrtávací tlačítko možnost výběru více tlačítek. výběrové tlačítko výběr právě jednoho tlačítka z více, které jsou umístěny v objektu (formulář, RadioBox, Panel). řádkový seznam s možností výběru jedné nebo více položek. rozbalovací seznam s možností výběru jedné položky. lišta s posuvníkem. komponenta na kterou je možné umístit jiné vizuální komponenty, které zdědí vlastnosti této komponenty (např. velikost a typ fontu textu). Často se používá pro objekty TCheckBox. obdoba komponenty TGroupBox, ale použitelná pro komponentu TRadioButton. komponenta, na kterou lze opět umístit jiné vizuální komponenty. Nyní začneme pracovat s tou nejjednodušší komponentou Label 25. Vytvořte si nový projekt s názvem PR01 a uložte ho do adresáře PR01. Na formulář vložte komponentu Label. Obrázek 9 Text Label1 je uveden v OI ve vlastnosti Caption. Stejná vlastnost u formuláře měnila text horním pruhu formuláře. Vlastnost Caption u všech objektů, pokud ji mají, slouží k zobrazování textu. V textu lze používat diakritiku. Pokud si pozorně pročteme vlastnosti OI objektu Label, zjistíme, že vlastnost Name má rovněž text Label1 (v tomto případě se jedná o jméno objektu). Můžeme ho přejmenovat, ale název musí splňovat pravidla pro tvorbu názvu proměnných. Z toho mimo jiné vyplývá zákaz používání diakritiky ve vlastnosti Name. Další důležité vlastnosti: Alignement Autosize Color Cursor zarovnání textu vlevo, vpravo a na střed. nastavení pevné nebo pohyblivé velikosti pomyslného rámečku kolem textu. barva pozadí. Pokud ji nezměníme, objekt dědí barvu z formuláře. vzhled kurzoru myši, když se přesuneme myší nad Label. Pokud ho nezměníme, dědí tvar, který je nastaven ve Windows. 25 V textu budeme používat názvy komponent bez prvního písmene T, které značí, že se jedná o Typ. - 23 -
Font v této vlastnosti můžeme měnit velikost písma, typ fontu, barvu, tučné písmo, kurziva, podtržení, atd. Vlastnost, kterou nenastavíme, se zdědí z formuláře nebo nadřazeného objektu (např. panelu). Hight, Width výška a šířka komponenty. Top, Left umístění objektu ve formuláři (nebo v panelu). Levý a horní kraj objektu je počítán od nuly. Když se v OI podíváme na události (Events), které jsou připojeny k objektu Label, zjistíme, že tam jsou i události OnClick a OnDblClick. Tyto události se aktivují kliknutím nebo dvojitým kliknutím myší na Label. Takže i Label může fungovat jako tlačítko. Nyní si prakticky ukážeme práci s komponentou Label. Příklad 4 Nastavujte tyto vlastnosti v projektu PR01: 1. Změňte u formuláře velikost písma (Font) na 12 bodů (velikost písma se současně změní i v Label1 26 ). 2. Do vlastnosti Label1 Caption napište text Můj program. 3. Nastavte vlastnost Label1 Autosize na hodnotu false. 4. Nastavte šířku (width) Label1 na 150. 5. Nastavte barvu (color) na žlutou clyellow. 6. Změňte hodnotu Cursor na crhandpoint. 7. Spusťte program F9. Když budete přejíždět kurzorem myši přes Label1 změní se jeho tvar Obrázek 10. Obrázek 10 8. Program vypněte kliknutím na křížek v horní liště. Naprogramujeme si naši první událost a to když myš se umístí nad Label1 nebo ho opustí. V OI si klikneme na záložku Events. 26 Překladač názvy vložených objektů automaticky čísluje, aby nedošlo k duplicitě v názvech. - 24 -
Událost OnMouseMove nám oznámí, že je kurzor myši nad objektem, a opuštění nám oznámí vznik události OnMouseLeave. Jak vytvoříme metodu (proceduru), která se spustí, když vznikne událost OnMouseMove? Stačí udělat dvojklik na vedlejší sloupec vedle události OnMouseMove a ve zdrojovém kódu se vygeneruje prázdná metoda (procedura): procedure TForm1.Label1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); V parametru Sender je uveden objekt, který metodu vyvolal. Pro nás v tomto okamžiku nezajímavá informace. V parametru Shift je uvedena informace, zda je na klávesnici stisknutý Shift, Ctrl nebo Alt a nebo stisknuto levé, pravé a střední tlačítko myši, popř. zda je proveden dvojklik. Názvy jednotlivých konstant jsou: ssshift, ssalt, ssctrl, ssleft, ssright, ssmiddle, ssdouble. V proměnných X, Y jsou uvedeny aktuální souřadnice kurzoru myši. Do metody napíšeme následující příkaz: procedure TForm1.Label1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); Label1.Caption:= 'Jsem nad Label1'; Stejným způsobem vygenerujeme metodu události OnMouseLeave a dopíšeme: procedure TForm1.Label1MouseLeave(Sender: TObject); Label1.Caption:= 'Jsem mimo Label1'; Poznámka: Při psaní vlastních příkazů napíšeme slovo Label1. (včetně tečky za slovem) a počkáme, až se objeví nabídka metod: Obrázek 11 Listovat v nabídce můžeme kurzorovými klávesami nebo myší. Stisknutím písmena na klávesnici se omezí výběr. Spusťte program a myší se pohybujte po formuláři a toto bude výsledek: Obrázek 12-25 -
Poznámka: Pokud budeme chtít odstranit naprogramované metody, musíme vymazat jen to, co jsme sami napsali. Prázdnou metodu pak překladač odstraní při prvním překladu např. Ctrl-F9. Příklad 5 Zadání: Zobrazte pozici kurzoru na formuláři pomocí dvou komponent Label. Než začneme, je nutné ukázat si jedno řešení drobného problému. Vlastnost Caption je vždy typu string, kdežto informace o umístění kurzoru X, Y v události OnMouseMove je typu integer. Z toho vyplývá, že musíme integer převést na string. K tomu lze použít funkci IntToStr 27. Parametrem funkce je číslo typu integer nebo Int64 a výstupem je string. Řešení: 1. Vytvořte nový projekt s názvem PR02 a uložte do adresáře PR02. 2. Nastavte vhodné rozměry formuláře (např. 600x480 bodů). 3. Na plochu formuláře vložte dvě komponenty Label. 4. Ve formuláři vygenerujte událost OnMouseMove (dejte si pozor ať je to událost opravdu formuláře a ne některých z objektů Label!). 5. Do události vložte příkazy pro zobrazení souřadnic kurzoru myši: procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); Label1.Caption:= IntToStr(X); Label2.Caption:= IntToStr(Y); 6. Spusťte program. Při pohybu kurzoru myši po formuláři se budou zobrazovat aktuální souřadnice pozice kurzoru. Obrázek 13 27 K dalším převodním funkcím patří i FloatToStr (převod pro pohyblivou řádovou čárku), FloatToStrF (převod pro pohyblivou řádovou čárku s formátováním), DateToStr (převod datumu), TimeToStr (převod času), atd. - 26 -
Úkol: Program má jednu vadu na kráse. Když se kurzor dostane nad některý z objektů Label, přestanou se čísla měnit. Zamyslete se nad příčinou, navrhněte řešení a naprogramujte vše zkonzultujte s vyučujícím. Příklad 6 Zadání: V projektu PR02 zobrazujte současně stisk kláves Shift, Ctrl, Alt a tlačítko myši Řešení: 1. Na formulář projektu PR02 přidejte další komponentu Label. 2. Do metody události OnMouseMove formuláře přidejte algoritmus detekující stisk příslušné klávesy, tlačítka myši popř. kombinace kláves. procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); Label1.Caption:= IntToStr(X); Label2.Caption:= IntToStr(Y); if Shift=[ssShift] then Label3.Caption:= 'Shift'; if Shift=[ssAlt] then Label3.Caption:= 'Alt'; if Shift=[ssCtrl] then Label3.Caption:= 'Ctrl'; if Shift=[ssLeft] then Label3.Caption:= 'Levé tlaèítko myši'; if Shift=[ssRight] then Label3.Caption:= 'Pravé tlaèítko myši'; if Shift=[ssMiddle] then Label3.Caption:= 'Prostøední tlaèítko myši'; if Shift=[ssShift, ssalt] then Label3.Caption:= 'Shift+Alt'; if Shift=[ssShift, ssctrl] then Label3.Caption:= 'Shift+Ctrl'; if Shift=[ssAlt, ssctrl] then Label3.Caption:= 'Alt+Ctrl'; if Shift=[ssShift, ssalt, ssctrl] then Label3.Caption:= 'Shift+Alt+Ctrl'; Určitě jste si všimli, že konstanty ssshift, ssalt,, jsou při testování v hranaté závorce. Je to proto, že deklarace TShiftState je následující: type TShiftState = set of (ssshift, ssalt, ssctrl, ssleft, ssright, ssmiddle, ssdouble); Deklarace set je označována jako deklarace množiny. Používá se tehdy, když může nastat možnost kombinace více než jedné hodnoty. V našem případě jsou to např. kombinace kláves. Poznámka: Mnozí z vás se teď asi zarazili, protože neví, jak vlastně zjistit informace o tom, jak je Shift deklarován a jaké jsou jeho možné hodnoty. Všechno je to jen o práci s Helpem, bez kterého se při programování neobejdeme. V našem případě najedeme kurzorem na text TShiftState a stiskneme Ctrl-F1. Dozvíme se vše, co potřebujeme vědět. Pokud jsou uvedeny příklady (examples) nebo další příbuzné metody (See also), je vhodné si vše přečíst. Tuto metodu budeme používat na získání informací o neznámých objektech, metodách, typech a událostech. - 27 -
3. Spusťte program. Při pohybu myší tiskněte příslušné klávesy (Shift, Ctrl, Alt, tlačítka myši) a naprogramované kombinace kláves. Obrázek 14 Všimněte si, že zobrazení stisknutých kláves se provede jen při pohybu myší. Pokud bychom chtěli, aby se informace o stisknutých klávesách objevila i při stisku bez pohybu myší, museli bychom to řešit pomocí události stisku klávesy na formuláři. Příklad 7 Zadání: Projekt PR02 upravte, aby se klávesy (Shift, Alt, ) zobrazily hned po stisku příslušné klávesy. Řešení: 1. V Unit1 projektu PR02 přidáme do sekce Private nebo Public pomocné proměnné x1 a y2, kde budeme ukládat aktuální hodnoty pozice kurzoru myši. private x1, y1: integer; public { Public declarations } 2. Do metody události OnMouseMove formuláře přidáme ukládání aktuální pozice kurzoru myši. procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); x1:= x; y1:= y; Label1.Caption:= IntToStr(X); 3. Vytvoříme události formuláře OnKeyDown (došlo ke stisku klávesy) a OnKeyUp (klávesa byla uvolněna). V obou metodách sami zavoláme metodu OnMouseMove. Simulujeme pohyb myši, aniž k pohybu došlo a metodě předáme potřebné parametry Shift, X1 a Y1. procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); Form1.OnMouseMove(self, Shift, x1, y1); procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); Form1.OnMouseMove(self, Shift, x1, y1); - 28 -
Musíme si vysvětlit skutečné parametry, které jsme použili při volání metody OnMouseMove. Deklarace hlavičky této metody je následující: OnMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); Za parametr Sender použijeme klíčové slovo Self (český já). Sdělujeme, že ten, kdo vyvolal danou událost, jsme byli my. Formální parametr Shift nahradíme skutečným parametrem Shift, ve kterém jsou uloženy informace o skutečně stisknutých nebo uvolněných klávesách. Za parametry X a Y použijeme proměnné x1 a y1 ve kterých je uložena hodnota aktuální pozice kurzoru myši. Program bude nyní fungovat tak, že pokud je myš nad formulářem (i když se myš nepohybuje), bude se zobrazovat stisk kláves Shift, Ctrl a Alt. Shrnutí. V této kapitole jsme se dozvěděli mnoho nových informací. Jedna z nich je, že jsme si ukázali, jak je program řízený událostmi. Systém nás o všech událostech, které nastanou, informuje a nám jen stačí naprogramovat, co se má při dané události dít. Korespondenční (samostatný) úkol. Příklad 8 Zadání: Vytvořte projekt s názvem PR03 a uložte ho do adresáře PR03. Na formulář umístěte komponentu Label. Naprogramujte, aby když kliknete na formulář, se v Label zobrazil text Klinutí na formulář a když kliknete na Label, objevil se text Kliknutí na Label. Stejně naprogramujte i dvojklik text bude Dvojklik na formulář a Dvojklik na Label. Celý adresář PR03 zkomprimujte a zašlete na e-mail vyučujícího. Pro řešení použijte metody OnClick a OnDblClick. - 29 -
4.5.1 Použití nevizuálního objektu Cíl Po prostudování oddílu 3.5.1 budete umět naprogramovat nevizuální objekt Timer. Klíčová slova Timer, OnTimer, Interval, Enable, Help, DateTime, Result, funkce. Čas potřebný k prostudování učiva oddílu 4 vyučovací hodiny. V této kapitole se naučíme používat objekt Timer (časovač), který se v aplikacích často používá. V tomto objektu existuje událost, která opakovaně vzniká podle navoleného časového intervalu. Nejmenší čas intervalu je 1 ms. Nejdelší je maximální hodnota typu integer v ms. Timer má v systému Windows vysokou prioritu, přesto však musíme zvolit vhodnou délku intervalu. Souvisí to s činností, kterou budeme při vzniku události dělat. Musíme si uvědomit, že jsou různě rychlé počítače a co zvládne jeden v bez problémů, druhý zvládat nemusí. Zkusme si nyní představit, že v události, kterou generuje systém podle hodnoty uvedené v Timeru, se budou ukládat rozsáhlá data do souboru na disku. Pokud ukládání bude delší, než interval časovače, nastane situace, že systém vygeneruje událost, a program ještě neskončil ukládání dat z předchozí události. Takže aniž došlo k dokončení předchozího ukládání, začíná ukládání nové. Asi tušíte, že by mohlo dojít k značným komplikacím kousnutí programu, ztráta dat, V tom případě je potřeba buď nastavit takový interval, který i na nejpomalejším PC nemůže kolidovat, nebo musíme zajistit, aby se děj v události spustil jen v případě, že předcházející děj již byl ukončen. Druhý způsob si ukážeme na konci kapitoly. Takže už dost povídání a začneme s praktickou částí. Příklad 9 Zadání: Vytvořte projekt PR04, který bude zobrazovat digitální čas v PC hodiny. Řešení: 1. Vytvoříme nový projekt PR04 a uložíme do adresáře PR04. 2. Na formulář umístíme komponentu Label. 3. Nastavte u formuláře písmo Courier New CE, velikost 20 a tučné. 4. Na formulář umístěte komponentu Timer ze záložky Systém. - 30 -
Když se podíváme na vlastnosti a události objektu Timer, zjistíme, že jich je nezvykle málo: Enable Obrázek 15 True událost OnTimer bude generována v intervalu který je zadán. False systém přestane událost OnTimer vyvolávat. Timer se může sám vypnout když Enable převede do False v události OnTimer. Interval interval generování události OnTimer. Je uváděn v ms a standardně je nastaven na 1 s (1000 ms). V našem projektu nám interval 1000 ms bude vyhovovat. Ještě budeme potřebovat zjišťovat aktuální čas PC. Zkusme logicky přijít no to, jak zjistit, která metoda nás bude o aktuálním čase informovat. Anglicky se čas řekne time. Slovo time napíšeme kdekoliv do zdrojového textu. Umístíme na něj kurzor a vyvoláme help (Ctrl-F1). Obrázek 16 Z nabídky si vybereme možnost CLX nebo VCL reference (výběr je libovolný). Pokud si nebudeme jisti co vybrat, vybereme postupně všechny. Po kliknutí na tlačítko Zobrazit se dostaneme k informaci, kterou potřebujeme: Obrázek 17-31 -
Funkce Time vrátí aktuální čas ve formátu TDateTime 28. Kliknutím na odkaz See also zjistíme další příbuzné metody: Obrázek 18 Kliknutím na odkaz Example získáme informaci, která náš problém přímo řeší: Obrázek 19 Vrátíme se zpět k našemu příkladu: 5. Vytvoříme si metodu, která se spustí při vzniku události OnTimer. 6. Do této metody dopíšeme algoritmus na získání a převodu času do vlastnosti Caption objektu Label. procedure TForm1.Timer1Timer(Sender: TObject); Label1.Caption:= TimeToStr(Time); 7. Po spuštění programu dostáváme funkční hodiny. Obrázek 20 28 TDateTime je formát ve kterém je uloženo datum i čas. - 32 -
Rozšíříme zadání, na zobrazování tisícin vteřin. Zde si musíme vypomoci procedurou, která nám poskytne příslušné informace: procedure DecodeTime(Time: TDateTime; var Hour, Min, Sec, MSec: Word); Procedura vrátí hodiny, minuty, sekundy a milisekundy. Převod na string si však již musíme provést sami. 1ms. Příklad 10 Zadání: Vytvořte projekt PR05, který bude zobrazovat digitální čas v PC s přesností na Řešení (první 4 body jsou shodné s Příkladem 9): 1. Vytvoříme nový projekt PR05 a uložíme do adresáře PR05. 2. Na formulář umístíme komponentu Label. 3. Nastavíme u formuláře písmo Courier New CE, velikost 20 a tučné. 4. Na formulář umístíme komponentu Timer ze záložky Systém. 5. Naprogramujeme si funkci, která převede číslo na string a doplní nevýznamné nuly. U programování funkcí došlo oproti BP k několika změnám. Funkce může být např. i typu Record. Výsledek se nezapisuje do identifikátoru, ale do speciální proměnné Result. S proměnnou Result lze pracovat jako s běžnou proměnou. Může se tedy vyskytovat na levé i pravé straně dosazovacího příkazu 29. Postup při programování vlastní funkce. Do části implementation napíšeme hlavičku funkce (popř. procedury) s logickými závorkami a end. implementation {$R *.dfm} function TForm1.FixStrL(s: string; znak: char; dec: integer): string; Před identifikátorem (název funkce) musí být uveden název typu objektu, pokud chceme, aby funkce (procedura) byla metodou tohoto objektu. Název objektu oddělíme od identifikátoru funkce tečkou TForm1.FixStrL. 29 V BP se identifikátor funkce mohl vyskytovat jen na levé části dosazovacího příkazu. - 33 -
Dalším krokem je umístění této metody do části Public nebo Private, ale již bez názvu typu objektu 30 : public function FixStrL(s: string; znak: char; dec: integer): string; Posledním krokem je naprogramování vlastního algoritmu. Pokračujeme v řešení našeho zadání: 6. Chceme, aby metoda FixStrL zleva doplnila do stringu znak uvedený v proměnné znak, tak, aby nová délka řetězce byla podle hodnoty uvedené v proměnné dec. To bude sloužit u zobrazování času k doplňování nevýznamných nul. Pro vlastní algoritmus použijeme cyklus s podmínkou na začátku a využijeme vlastností proměnné Result. Výsledek je následující: function TForm1.FixStrL(s: string; znak: char; dec: integer): string; Result:= s; while Length(Result)<dec do Result:= znak+result; Přeloženo do češtiny: doplňuj před text, který je v Result, znak, který je v proměnné znak, dokud je výsledná délka Result menší, než požadovaná. 7. Nyní naši novou metodu uvedeme do života. Pokud chceme získat setiny sekundy, musíme použít proceduru DecodeTime. Deklaraci a způsob práce s touto procedurou si prohlédněte pomocí helpu. procedure TForm1.Timer1Timer(Sender: TObject); var hh,mm,ss,s100: word; DecodeTime(Time,hh,mm,ss,s100); Label1.Caption:= FixStrL(IntToStr(hh),'0',2)+':'+FixStrL(IntToStr(mm),'0',2) +':'+FixStrL(IntToStr(ss),'0',2)+','+FixStrL(IntToStr(s100),'0',3); Dekódujeme aktuální čas na jednotlivé části, jako jsou hodiny, minuty, sekundy a milisekundy. Pak z těchto částí vytvoříme string, jak jsme při zobrazování času zvyklí. FixStrL(IntToStr(hh),'0',2) vnořená funkce IntToStr převede údaj na string. Funkce FixStrL, pokud je hh menší než 10, doplní před číslo nulu. To provedeme i s minutami a sekundami. Mezi ně vložíme dvojtečku. Za sekundy vložíme čárku a za ní budeme zobrazovat milisekundy na tři desetinná místa. 8. U Timeru nastavíme interval na 1ms. 9. Spustíme program a měli bychom získat tento výsledek: Kde se samozřejmě čas mění. 30 Tuto činnost budeme dělat vždy, když budeme tvořit vlastní metody. - 34 -
Nyní si ukážeme, jak zabezpečit, aby se algoritmus v události OnTimer nespustil dříve, než bude předešlý dokončen. Příklad 11 Zadání: V projektu PR05, zabezpečte, aby se algoritmus v metodě OnTimer neprováděl dřív, než bude ukončeno vykonávání předešlého algoritmu. Řešení: 1. Vytvoříme si v public logickou proměnnou s názvem TimerRun. public TimerRun: boolean; function FixStrL(s: string; znak: char; dec: integer): string; Je nutno dodržovat zásadu, že v public (nebo private) jsou nejprve uvedeny deklarace proměnných a teprve potom deklarace metod. 2. V OI Timeru nastavte vlastnost Enable na false. 3. Ve formuláři vytvoříme metodu OnCreate a v ní nastavíme počáteční hodnotu proměnné TimerRun na False. V dalším příkaze nastavíme Timer1.Enable na true a tak se spustí časovač. procedure TForm1.FormCreate(Sender: TObject); TimerRun:= false; Timer1.Enabled:= true; 4. Metodu události OnTimer upravíme následujícím způsobem. procedure TForm1.Timer1Timer(Sender: TObject); var hh,mm,ss,s100: word; if TimerRun then exit; // pokud předcházející děj neskončil nedělej nic TimerRun:= true; // nastavím, že Timer právě běží DecodeTime(Time,hh,mm,ss,s100); Label1.Caption:= FixStrL(IntToStr(hh),'0',2)+':'+FixStrL(IntToStr(mm),'0',2) +':'+FixStrL(IntToStr(ss),'0',2)+','+FixStrL(IntToStr(s100),'0',3); TimerRun:= False; // nastavím, že činnost skončila V prvním řádku testujeme, zda předcházející událost OnTimer skončila. Pokud tomu tak není, skončíme a dále nepokračujeme. V druhém řádku nastavíme proměnnou TimerRun na true, jako potvrzení, že událost právě běží. V posledním řádku nastavíme proměnnou TimerRun na false, jako informaci, že událost již skončila. - 35 -
Poznámka: V tomto případě je tento způsob zbytečný, ale v žádném případě není na škodu. V případě, že budete v Timeru vykonávat nějaké časově složité operace, je tento způsob nezbytný. - 36 -
4.5.2 Jednoduchý poznámkový blok Cíl Po prostudování oddílu 3.5.2 budete umět vytvářet Menu a pracovat s objektem Memo. Klíčová slova Vizuální objekty, nevizuální objekty, Label, OnMouseMove, OnKeyDown, OnKeyUp, IntToStr, Sender, Self. Čas potřebný k prostudování učiva oddílu 4 vyučovací hodiny. Příklad 12 Zadání: Vytvořte projekt, který se bude chovat jako poznámkový blok. Součástí bude i Menu. Řešení: 1. Vytvořte projekt s názvem PR06 a uložte do adresáře PR06. 2. Na plochu formuláře vložte objekt Menu. Dvojklikem na ikonu otevřeme okno pro editaci položek Menu. Obrázek 21 3. Další nejvhodnější postup je, že do Caption vybraného pole menu napíšeme název položky. Jakmile napíšeme text položky a stiskneme Enter, automaticky se vytvoří i název položky (name), ale vypustí se znaky s diakritikou. Současně se vytvoří i prázdné položky pro tvorbu dalších položek. Obrázek 22-37 -
4. Doplňte nejdříve názvy položek podle vzoru: Obrázek 23 5. Na formulář vložte objekt Memo. Obrázek 24 6. Nyní je vhodné nastavit a naprogramovat parametry Memo1, tak, aby se jeho rozměry měnily se změnou rozměrů formuláře. 7. V události OnCreate formuláře nastavíme levou a horní část objektu Memo1. Současně vymažeme obsah Memo1 (text) metodou Memo1.Lines.Clear. Tato metoda se používá u typu objektu TStrings (neplést s typem proměnné string), což je objekt Lines v Memo k vymazání obsahu. Další metody se dozvíme postupně. procedure TForm1.FormCreate(Sender: TObject); Memo1.Left:= 0; Memo1.Top:= 0; Memo1.Lines.Clear; 8. Vytvoříme metodu události formuláře OnResize. Tato událost nastane kdykoliv se změní velikost formuláře. Je aktivovaná i při události OnCreate. procedure TForm1.FormResize(Sender: TObject); Memo1.Width:= Form1.ClientWidth; Memo1.Height:= Form1.ClientHeight; Vlastnosti ClientWidth a ClientHeight informují o vnitřní šířce a výšce formuláře, kterou můžeme použít pro naše vizuální objekty. 9. Spusťte program a vyzkoušejte si, že se změnou formuláře měníme i rozměry Memo1. Obrázek 25-38 -
Nyní se začneme věnovat metodám, které budeme aktivovat z menu. 10. Začneme ukončením programu. Klikneme-li na položku menu Soubor, rozbalí se podmenu. Kliknutím na položku podmenu Konec se vytvoří metoda události, která vznikne při kliknutí na tuto položku. Pokud chceme aplikaci ukončit, stačí zavolat metodu Close 31 nebo Form1.Close. procedure TForm1.Konec1Click(Sender: TObject); Close; Po spuštění můžeme program ukončit výběrem položky Menu Konec. 11. Položce Konec lze přiřadit horkou klávesu (kombinace kláves), takže program můžeme ukončit s klávesnice stiskem této kombinace. V OI položky Konec nastavíme ShortCut na Ctrl+X. Po spuštění můžeme program vypnout stisknutím kombinace kláves Ctrl+X. 12. Kliknutím na položku menu Nový vymažeme text v Memo1. procedure TForm1.Nov1Click(Sender: TObject); Memo1.Lines.Clear; 13. Nyní načteme textový soubor do Memo1. K tomu budeme potřebovat další nevizuální komponentu OpenDialog ze záložky Dialogs, kterou umístíme na formulář. Obrázek 26 14. V tomto objektu nastavíme filtr pro otvírání typů souborů. Pro komponentu OpenDialog v OI vybereme vlastnost Filter a kliknutím na vedlejší sloupec aktivujeme editor filtru. Ten naplníme podle vzoru. Obrázek 27 31 Název objektu (Form1) před Close nemusíme uvést, překladači je jasné, že se jedná o metodu patřící k formuláři. - 39 -
V prvním sloupci uvádíme název skupiny souborů, ve druhém pomocí hvězdičkové konvence vytvoříme příslušný filtr. Pokud chceme spojit více filtrů, oddělíme seznam středníkem (*.txt; *.bat; *.ini). 15. Naprogramujeme načtení textového souboru do Memo1. Vytvoříme si metodu k události položky Menu Otevřít a zapíšeme následující algoritmus. procedure TForm1.Otevt1Click(Sender: TObject); if OpenDialog1.Execute then Memo1.Lines.LoadFromFile(OpenDialog1.FileName); Metoda Execute objektu OpenDialog je logická a má hodnotu TRUE, pokud došlo k výběru souboru. Proto se musíme na tuto skutečnost vždy nejdříve dotázat. Při výběru souboru se uloží do vlastnosti FileName název vybraného souboru, mimo jiné informace, které se mohou občas potřebovat. V objektu Lines (objekt TStrings) existuje metoda pro načtení textu ze souboru. Spuštěním programu a výběr položky menu Otevři se spustí klasické okno pro výběr souboru, jak ho známe z Windows. Obrázek 28 Nabídnou se pouze soubory s koncovkou TXT. Můžeme změnit typ souboru podle toho, co jsme nastavili ve filtru. Po výběru souboru se název souboru objeví v Memo1.FileName. Metoda LoadFromFile objektu Lines načte obsah vybraného souboru do Memo1. 16. Ještě nám zbývá uložit text z Memo1 do souboru. K tomu použijeme objekt SaveDialog ze záložky Dialogs. Nastavíme stejně filtr jako u OpenDialog. 17. Vytvoříme metodu k události Ulož položky Menu a naprogramujeme uložení. procedure TForm1.Uloit1Click(Sender: TObject); If SaveDialog1.Execute then Memo1.Lines.SaveToFile(SaveDialog1.FileName); Je vidět, že podoba mezi uložením a načtením je značná. - 40 -
Teď už nám jen zbývá doprogramovat vlastnosti Memo. 18. Začneme nastavením fontu Memo. Budeme potřebovat další nevizuální komponentu ze záložky Dialogs a to FontDialog. V OI můžeme nastavit počáteční parametry fontu, popř. tyto parametry můžeme načíst z Memo1 v události OnCreate formuláři jak je uvedeno v příkladu. procedure TForm1.FormCreate(Sender: TObject); Memo1.Left:= 0; Memo1.Top:= 0; Memo1.Lines.Clear; FontDialog1.Font:= Memo1.Font; To lze samozřejmě provést i obráceně, jak je zřejmé v dalším bodě. 19. Vytvoříme metodu události kliknutí na položku Font z Menu. Naprogramujeme změnu fontu objektu Memo. procedure TForm1.Font1Click(Sender: TObject); if FontDialog1.Execute then Memo1.Font:= FontDialog1.Font; Shodné s dialogy, které již známe. 20. Pro změnu barvy pozadí Memo použijeme komponentu ColorDialog ze záložky Dialogs. Událost na kliknutí položku Pozadí z Menu. procedure TForm1.Pozad1Click(Sender: TObject); if ColorDialog1.Execute then Memo1.Color:= ColorDialog1.Color; Posledním naším úkolem je nastavení zalamování dlouhých textů v Memo. 21. Nejdříve nastavíme v OI u položky Zalamovat v Menu vlastnost AutoCheck na hodnotu True a Check taky na True. Kliknutím na takovou položku běžícího programu se provede zaškrtnutí nebo zrušení zaškrtnutí. Dále naprogramujeme událost kliknutí na tuto položku. Hodnoty WordWrap i Checked jsou logické, a tak můžeme napsat dosazení přímo jako je v příkladu. procedure TForm1.Zalamovn1Click(Sender: TObject); Memo1.WordWrap:= Zalamovn1.Checked; Text se zalamuje Text se nezalamuje Obrázek 29 Obrázek 30-41 -
Na závěr lze jen konstatovat, že jsme vytvořili funkční model jednoduchého poznámkového bloku. Teď už jen záleží vás a vaší fantazii, jak projekt vylepšit. Korespondenční (samostatný) úkol. Popište a navrhněte, k čemu by šlo použít následující metody objektu Memo. Enabled, ReadOnly, Visible, Modified, Undo, CanUndo. Využijte alespoň tři tyto metody v projektu PR06 a rozšiřte o ně tento projekt. Výsledky (popis metod a komprimovaný adresář PR06) zašlete na e-mail vyučujícího. - 42 -
4.5.3 Jednoduchá kalkulačka Cíl Po prostudování oddílu 3.5.3 budete umět pracovat s dalšími základními objekty (Edit, Buton, PopupMenu, Panel, CheckBox, RadioButton). Klíčová slova StaticText, Edit, Buton, Panel, ShowMessage. Čas potřebný k prostudování učiva oddílu 6 vyučovacích hodin. Příklad 13 Zadání: Vytvořte projekt, který bude fungovat jako jednoduchá kalkulačka. Řešení: 1. Vytvořte projekt s názvem PR07 a uložte do adresáře PR07. Do vlastnosti Caption formuláře zapište text Kalkulačka. 2. Na formulář vložte komponentu Panel ze záložky Standard. Pojmenování Panelu necháme původní Panel1. Nastavte vlastnosti Top a Left na nulu. Vymažte text z vlastnosti Caption. Šířku panelu nastavte na 190. 3. Na plochu objektu Panel1 vložte komponentu Edit ze záložky Standard. Bude sloužit pro vstup dat. Dále na stejnou plochu umístěte komponentu StaticText ze záložky Additional. Tato komponenta je podobná objektu Label, ale má několik vylepšení, jako např. zobrazení ohraničení. Obrázek 31 4. U objektu Panel1 nastavte vlastnost Font-Size na 12. - 43 -
5. U objektu StaticText1 nastavte tyto vlastnosti: Autosize false BorderStyle sbssunken Alignment tarightjustify Top 2 Left 2 Width 180 Hide Výsledek ShowHide True Caption 0 6. U objektu Edit nastavte vlastnost Left na 2, Width na180 a komponentu umístěte pod StaticText. Ve vlastnosti Text vymažte text. Objekty, které slouží k editaci, nemají vlastnost Caption, ale vlastnost Text. Obrázek 32 7. Na plochu formuláře pod Panel1 umístíme Panel2. Vlastnost Left nastavte na 2 a šířku na 190. Ve vlastnosti Caption odstraňte text. Font nastavte na velikost 12 a tučné písmo. 8. Na Panel2 vložte komponentu Button ze složky Standard. Bude to jedno tlačítko z klávesnice kalkulačky. Do Caption vložte číslici (text), kterou bude tlačítko představovat. Jako název tlačítka použijte taky číslici, ale umístěte před ní podtržítko 32. Postupně do objektu Panel2 vložte tlačítka podle příkladu (Obrázek 33). Obrázek 33 Názvy tlačítek budou: _7, _8,, _3 _0, _tecka, _plus_minus, _plus, _minus, _krat, _deleno, _enter, _Clr, _Delete. Šířka tlačítek bude 40 a výška 25. 32 Názvy proměnných nesmí začínat číslici. - 44 -