V dnešním díle si rozebereme VCL a řekneme si něco základního ke komponentám v Delphi. Tím zakončíme teoretickou část a od příštího dílu se už vrhneme na komponenty a programování.
V předchozích dílech jsme postupně prošli přes základy a základní teorie potřebné k vytvoření programu v Delphi. Ovšem Delphi jako vizuální vývojové prostředí nabízí pro vývoj aplikací nejen funkce, metody, instance, třídy atd., ale jejich hlavní síla spočívá v komponentách. Od tohoto dílu se postupně začneme prohrabávat VCL a komponentami, které obsahuje, a krůček po krůčku si vytvoříme vlastní aplikaci. Je možné, že někdy nebude možné danou komponentu do daného projektu použít, potom ji využijeme na samostatném ukázkovém příkladu.
Na konci tohoto dílu je také k dispozici přehled většiny nejčastějších vlastností, událostí a metod s popisem ve formátu PDF. Myslím, že se vám bude při programování docela hodit ;)
VCL
Ale i dnešní díl ještě věnujeme spíše teorii. Pro pochopení fungování Delphi je nutné si říct něco o VCL.
VCL obsahuje všechny komponenty a některé objekty, které v Delphi jsou. V některých verzích Delphi jsou dostupné i zdrojové kódy VCL, máte tedy možnost si prohlédnout, jak jsou jednotlivé komponenty a třídy naprogramovány (rozhodně ale nedoporučuji do zdrojových kódů jakkoliv zasahovat). Jako vše v počítačích (až na výjimky) musí i VCL mít svůj určitý řád – tím je hierarchické rozdělení na třídy. Každá komponenta ve VCL tak vytváří svou vlastní třídu, která je potomkem buď třídy nadřazené komponenty, nebo jedné ze základních tříd VCL. Zde je pro představu přibližný nákres toho, jak jsou rozděleny základní třídy ve VCL:
Nejvyšší třídou – předkem všech předků – je třída TObject. Mezi jednotlivými třídami jsou samozřejmě ještě další odvozené třídy. Nejvíce odvozených tříd (prakticky všechny komponenty) najdete u TWinControl a u nevizuálních komponent.
Komponenty ve VCL
Pokud při návrhu programu v Delphi umístíte na formulář komponentu, automaticky se do zdrojového kódu přidá definice nové instance třídy dané komponenty. Takto například bude vypadat definice, pokud na formuláři bude jenom komponenta Label (třída TLabel):
type
TForm1 = class(TForm)
Label1: TLabel;
private
{ Private declarations }
public
{ Public declarations }
end;
Vlastnosti komponent
Každá komponenta má své vlastnosti. Určité vlastnosti jsou všem komponentám společné, jedná se převážně o ty, které dědí po některém z vyšších předků, jako například TObject, TPersistent nebo TComponent.
Některé vlastnosti jsou přístupné přes Object Inspector, jiné pouze za běhu programu. Jak se pracuje s Object Inspectorem si, doufám, pamatujete. Přístup k vlastnostem za běhu programu se provádí pomocí tzv. tečkové notace, tedy stejným způsobem, jako jsme to dělali například u tříd:
Button1.Caption:=‘Tlačítko’;"
Během dalších dílů si jednotlivé vlastnosti probereme podrobně podle použití u dané komponenty. Pokud byste se i tak setkali s vlastností, o které jsme si nic neříkali, odkazuji vás na nápovědu Delphi, kde o tom najdete mnohem více.
Události
Máte na formuláři třeba tlačítko. Hezké. Ale k čemu nám je, když se po kliknutí na něj nic nestane? Nebo potřebujeme detekovat změnu velikosti okna? Určitě se nám to může někdy hodit, ale jak na to?
Na jednoduchou otázku je celkem jednoduchá odpověď.
Ale než si ji zodpovíme, bylo by vhodné se podívat, jak vlastně naše milovaná Okýnka (též známá pod názvem Windows) zajišťují komunikaci mezi aplikacemi a jak dávají aplikacím vědět o tom, co se děje kolem nich.
Zjednodušeně: nejedná se o žádné komplikované řešení – pokud se něco stane, Windows jednoduše pošlou aplikaci zprávu. Nečekejte zprávu typu „Hele, ten blbec tě posunul vo 12 čísel dolu“. Každá zpráva je prakticky samostatná třída. Windows tak aplikaci pošlou název dané třídy a případně i nějaké parametry (v našem případě by to mohlo být wmWindowMove(12,down) (pouze ukázkový příklad, v reálu to vypadá jinak). Problematika zpráv ve Windows (tím teď myslím jaksi učivo o zprávách ve Windows, nikoliv případné chyby, které (ne)obsahují) je mnohem komplikovanější, ale pro naše účely tohle postačí.
Nyní zpět k té jednoduché otázce, co je na ní tak jednoduchá (tedy ještě před minulým odstavcem byla) odpověď. Pokud tedy například kliknete na tlačítko, přes zprávy se pak k aplikaci donese, že došlo ke kliknutí na tohle a tohle tlačítko. Aplikace se pak podívá na název procedury, která je k dané události přiřazená, a tu proceduru (může se jednat i o funkci) provede.
Určitě jste si v některém z předchozích příkladů všimnuli například této procedury obsluhující událost kliknutí na tlačítko:
procedure TForm1.Button1Click(Sender: TObject);
Kdybyste se podívali do Object Inspectoru, zjistíte, že k události OnClick je přiřazená právě procedura Button1Click.
Nová událost se dá vytvořit tak, že v Object Inspectoru poklepete na to bílé pole vedle názvu události. V Code Browseru se vám ihned nadefinuje a nadeklaruje nová procedura. Příkladem může být událost formuláře OnCreate, která se vyvolá ve chvíli, kdy je daný formulář vytvořen (pozor, vytvořen neznamená zobrazen, při spouštění aplikace se nejdřív vytvoří všechny formuláře (ke komponentám vytvářeným za běhu aplikace se možná taky dostaneme, ale to sem teď nepatří) a až potom zobrazí hlavní, pokud tedy chcete, aby se při zobrazení formuláře zobrazila hláška, musíte ji obsloužit v události onShow, nikoliv onCreate):
type
TForm = class(TForm)
Button1: TButton;
...
procedure Form1Create(Sender: TObject); //tady...
...
...
...
procedure TForm1.Form1Create(Sender: TObject); //...a tady se sama nadeklaruje a vytvoří příslušná procedura
begin
end;
...
Samozřejmě procedurám obsluhujícím události můžete dávat i svá jména, například Button1KlikNaMe.
Metody komponent
Jak jsme si řekli, komponenta je vlastně samostatná třída. Určitě si vzpomenete, jak jsme u tříd definovali jejich metody. Pokud si nevzpomenete, tak vám je připomenu já: metoda je vlastně procedura nebo funkce, která je objektem třídy.
Příklad metody, která zjistí, jestli je komponenta zaměřená (tzn. je na ní umístěn tabulátor), tedy jestli má tzv. focus. Pokud jej nemá, tak mu jej přidělí. V obou případech se jedná o metodu třídy TEdit komponenty Edit1:
if not Edit1.Focused then Edit1.SetFocus;
Jak primitivní, že? „Pokud neplatí, že komponenta Edit1 má focus, tak jí dej focus.“
K metodám není moc co víc uvádět.
Kromě komponent obsahuje VCL i objekty, se kterými se určitě také během dalších dílů setkáme. Jedná se také o třídy, ale často se jedná o datové typy vlastností některých komponent.
Příkladem může být vlastnost Font, která je typu TFont a jedná se o třídu obsahující veškeré informace o písmu a jeho atributech, které budou na komponentu aplikovány. Tedy:
...
Edit1.Font.Name=‘Arial’;
Edit1.Font.Size=12;
...
Toť k objektům vše a jdeme dál…
Nevizuální komponenty
Zní to možná divně (a myslete si o tom, co chcete), ale VCL obsahuje i nevizuální komponenty (asi se vývojářům nechtělo zavádět další knihovnu NCL – Non-visual Component Library). Jedná se o komponenty, které se od ostatních liší pouze tím, že za běhu programu nejsou vidět. Obvykle se jedná o komponenty pro určité služby probíhající na pozadí. Například komponenta Timer (časovač), která pouze vždy v daném intervalu vyvolá příslušnou událost (OnTimer). Tato komponenta obsahuje pár atributů a prakticky jen jednu událost. Dalším příkladem jsou pak komponenty pro internetovou komunikaci, třeba pro aplikace typu server-klient. Ke komponentě Timer se ještě určitě vrátíme, k těm internetovým asi ne.
Závěr
Již pošesté se blížíme ke konci. Tohle ale není konec jako všechny ostatní. Tohle je konec nudné teorie. Příště se již opravdu vrhneme do komponent a s tím souvisejícím programováním. Také vám představím plány na náš ukázkový program, který budeme postupně během dalších dílů vytvářet a vylepšovat.
Proto mi, prosím, jakkoliv (přes úkoly, ICQ nebo e-mail) posílejte návrhy na tu aplikaci, která nás bude provázet až skoro do konce kurzu. Čím víc a čím dřív mi návrhy pošlete, tím dřív budu moct začít psát další díl a tím dřív se ho i dočkáte.
Úkol
Dnes jsem se v závěru nějak rozepsal… Ale konečně jsou tady naše (vaše) oblíbené úkoly:
- Pokuste se pochopit, o čem je VCL (nečekaný úkol).
- Umístěte na formulář komponentu Label. V události formuláře OnCreate nastavte popisku (vlastnost Caption) komponenty Label na „Najeď myší“. Potom vytvořte události komponenty Label, které najdete v Object Inspectoru pod názvem OnMouseOver a OnMouseLeave, a v každé proceduře změňte popisku komponenty Label na něco jiného.
- Pokud si nebudete s čímkoliv vědět rady (ať už s úkolem nebo vám nebude něco v článku jasné), nebojte se mi napsat na ICQ (249-163-429) nebo napište do fóra.
- Již jsem to jednou zmínil v závěru, ale napíšu to sem radši ještě jednou: posílejte mi návrhy na aplikaci, kterou chcete postupně během celého kurzu vytvářet a na které budeme názorně demonstrovat použití různých komponent.
Soubory ke stažení
Zde je ke stažení nahoře slibovaný přehled nejpoužívanějších vlastností, metod a událostí komponent. Celý seznam je prakticky nekonečný, protože lze vytvářet vlastní komponenty a s ní i ty atributy.