Tvorba komponent pro C++ Builder 1. díl

V tomto seriálu se budeme zabývat tvorbou (nebo s tím související úpravou existujících) komponent pro vývojové prostředí Borland C++ Builder.
V tomto seriálu se budeme zabývat tvorbou (nebo s tím související úpravou existujících) komponent pro vývojové prostředí Borland C++ Builder. Jak asi víte, Borland C++ Builder je opravdu vizuální vývojové prostředí se všemi klady a zápory, které to přináší. I když slovo „visual“ má ve svém názvu také (mimo jiné) Microsoft Visual C++, v tomto případě se nejedná o vizuální nástroj v pravém slova smyslu, na rozdíl od „sesterského nástroje“ Microsoft Visual Basic. A z pohledu programátorů je to dobře. Microsoft Visual C++ umožňuje za cenu vyšších požadavků na čas vývoje a hlavně řekněme profesionální zdatnost programátora vyvíjet opravdu výkonné a efektivní aplikace. A pro ty, kteří chtějí (nebo musí) mít nástroj pro relativně snadný a hlavně rychlý vizuální vývoj aplikací, je tu právě Borland C++ Builder spolu s podobnými nástroji, jako je sesterský produkt Delphi, zmíněný Visual Basic nebo PowerBuilder. Pro programátory používající jazyk C++ je tady právě C++ Builder, který umožňuje zkušenějšímu programátorovi využít sílu jazyka C/C++ a alespoň částečně eliminovat záporné stránky vizuálního vývoje. Které to jsou? Vyšší paměťové nároky aplikace, většinou menší rychlost, větší nároky na systémové zdroje a podobně. Zmínil jsem se o možnostech zefektivnění programu v C++ Builderu, pro ty, kteří znají VCL, uvedu v tomto úvodu jako příklad třídu AnsiString, jejíž „nevhodné“ použití může v některých případech (mnohonásobné cyklické operace s řetězci) až neuvěřitelným způsobem zpomalit program ve srovnání s použitím „céčkovských řetězců“, přesněji ukazatelů na pole znaků (tedy typu CHAR>. Pro ty, kteří ví, o čem je řeč: Můžete si sami zkusit porovnat dva cykly, v jednom použít lstrcmp (popř. strcmp) a ve druhém AnsiCompare …..

Ponechme (alespoň na tomto místě) zatím stranou polemiku, které vývojové prostředí je lepší a pro jaké úlohy se více hodí. Řekněme si ale, že i C++ Builder nabízí „uplatnění“ i programátorovi, kterému jinak vizuální vývoj moc neříká (což je i můj případ, za své „domovské“ prostředí považuji Microsoft Visual C++, ale tvorbou komponent pro C++ Builder jsem si už vydělal „nějaké ty peníze“). A tou oblastí uplatnění je právě především tvorba komponent. Pokud tedy alespoň trochu znáte WinAPI, tj. základní principy programování ve Windows SDK a to, co s tím souvisí, „stačí“ se seznámit s principy VCL, samozřejmě s prací ve vývojovém prostředí C++ Builderu, a můžete se dát do tvorby komponent.

Nyní jednu asi špatnou zprávu: pokud jsem dobře informován (byl bych velmi potěšen, když mi někdo sdělí opak – pište na radek@rplusj.cz), komponenty vytvořené v C++ Builderu nelze použít standardním způsobem v Delphi. Naopak to možné je. Komponenty vytvořené v Delphi se dají snadno (mám to vyzkoušené) použít v C++ Builderu, dokonce lze i editovat a kompilovat kód v Pascalu. Vzhledem k rozšířenosti Delphi se takto významným způsobem omezuje rozsah uplatnění a „odbyt“ komponent napsaných v C++ Builderu. Ale nyní si již pojďme říci o komponentách.

C++ Builder obsahuje několik desítek standardních komponent, které jsou součástí instalace tohoto prostředí. Jejich rozsah závisí na verzi C++ Builderu, kterou máte zakoupenou (v českém prostředí by asi více sedělo: kterou používáte….). Existují totiž verze Standard, Professional a Enterprise lišící se mimo jiné právě „vybavením“ standardními komponentami. Každý však dříve nebo později narazí na nějaký úkol, na který prostě žádná z těchto komponent nestačí. Pokud programátor nemá takové znalosti, aby si to dokázal „udělat ručně“, začne se shánět po nějaké komponentě od třetí strany, která jeho problém zvládne. Není to sice ideální, ale pro takového člověka jediné možné řešení. A to je prostor pro tvůrce komponent. Dalším důvodem pro vytvoření nové komponenty může prostě být, že si programátor chce napsat komponentu čistě pro vlastní potřebu z důvodu opakovaného použití kódu. Tyto komponenty pak mají tu výhodu, že si je napíšete „na míru“, tj. bez dalšího „balastu“, který je sice univerzální, ale vás v tomto případě nezajímá a pouze zbytečně zatěžuje výsledný kód. Pro tento případ mohu uvést příklad z vlastní praxe. Chtěl jsem mít k opakovanému použití komponentu zapouzdřující tray-ikonu. Instalace C++ Builderu obsahuje (na paletě „Samples“) komponentu TTrayIcon. Ta sice obsahuje takové „parádičky“, jako je možnost „animovat“ tuto ikonu apod., ale chtěl jsem používat tzv. balónové-tooltipy, které jsou podporovány, pokud máte nainstalován Internet Explorer 5 a vyšší. Takže jsem si napsal vlastní komponentu (odvozenou přímo od TComponent), ve které jsem implementoval jen to, co jsem potřeboval. V souvislosti s balónovými tipy nelze neupozornit, že pánové od Borlandu poněkud zaspali dobu (alespoň pokud jde o platformu Windows). Když se podíváte do příslušné části dokumentace (Windows SDK) na popis struktury NOTIFYICONDATA, zjistíte, že nic takového vlastně neexistuje (mluvím o dokumentaci k poslední verzi 5). Teprve pohled do MSDN vám odhalí toto „tajemství“. Naštěstí (ve verzi 5) můžete tuto strukturu používat v její rozšířené podobě. A takových příkladů bych mohl uvést více: SetWindowLongPtr, FlashWindowEx, WM_XBUTTONDOWN,…. Doufám, že to stačí, mohl bych pokračovat. S tím souvisí rada pro vás: jako dokumentaci Windows SDK si nějakým způsobem pořiďte MSDN, i když budete psát v C++ Builderu. MSDN existuje i v on-line verzi (http://msdn.microsoft.com) , pokud máte odpovídající připojení k Internetu.

Tolik tedy na úvod a v tomto prvním článku si ještě řekněme, jak tedy začít.

Balíčky

Komponenty v C++ Builderu jsou součástí tzv. balíčků. Balíčky, ve smyslu výsledného kódu balíčku, jsou v podstatě běžné dynamicky linkované knihovny (dll) Windows s tím, že mají koncovku .bpl. V nastavení projektu pak máte možnost zvolit, zda chcete tyto runtimové balíčky používat dynamicky, nebo je přilinkovat staticky do výsledné aplikace. Dynamické použití samozřejmě nese nutnost mít použité balíčky na počítači, kde má aplikace běžet, distribuovány, tj. „mít je na cestě“. Ke statickému linkování ještě doplním, že pokud chcete mít aplikaci naprosto nezávislou na dalších knihovnách, je třeba ještě v nastavení projektu („Project Option“) na záložce „Linker“ zrušit zaškrtnutí (check-box) „Use dynamic RTL“. V opačném případě program vyžaduje ke svému spuštění knihovnu „borlndmm.dll“, což je právě ta run-timové knihovna RTL (Run Time Library). Volba dynamického použití balíčků je na záložce „Packages“ jako check-box „Build with runtime packages“, pod nímž je uveden seznam balíčků, které program bude vyžadovat jak run-timové.

Když vytváříte novou komponentu, při její instalaci musíte určit balíček, do něhož má být umístěna. Můžete mít předem vytvořený svůj balíček, do kterého budete umisťovat vlastní komponenty, nebo použít tzv. uživatelský balíček, který vám nabídne C++ Builder.

Výběr předka komponenty

Důležitou součástí rozhodovacího procesu před vlastním vytvořením komponenty je výběr předka komponenty. Tímto předkem samozřejmě může být zase opět komponenta knihovny VCL, včetně vlastních a již nainstalovaných komponent. Knihovna VCL (zkratka z Visual Component Library) je knihovna vizuálních komponent, které jsou přístupné ve vývojovém prostředí pro nastavení vlastností a událostí v době návrhu, tedy „vizuálně“. Samozřejmě vždy můžeme tyto vlastnosti libovolně měnit v runtimu.

Je třeba brát v úvahu, že pokud chceme pouze rozšířit některou již funkční komponentu o nové vlastnosti (property) a události (events), můžeme si za předka vybrat některou komponentu na konci hierarchického stromu VCL. To nám zjednoduší situaci v několika aspektech: naše komponenta automaticky zdědí všechny „property“ a „events“, které jsou „published“. Když se totiž podíváte na komponenty jako TCustomxxxxx, například TCustomEdit, a porovnáte je s TEdit, zjistíte, že jejich funkčnost je zcela totožná a jediný rozdíl je, že TCustomEdit nemá ty property a events, které jsou v něm implementovány jako nové, publikovány (tedy published), ale má je chráněné (protected). A TEdit tyto zmíněné protected prvky pouze publikuje, nic více nic méně. Pokud tedy odvodíme komponentu od TCustomEdit, musíme v hlavičkovém souboru, v deklaraci třídy do části published vypsat ty z prvků, které chceme zdědit a publikovat. I přes tuto „práci“ to má ale výhodu, protože z důvodu přehlednosti máme možnost skrýt prvky, o kterých víme, že je vývojář nebude používat, a v ObjectInspector bude vše přehlednější a bude tam jen to potřebné. Tento aspekt je významný zejména tehdy, když si píšeme komponenty pro sebe nebo svůj vývojový tým. V případě, že dáváme komponentu k širokému použití, těžko můžeme o některém prvku předem předpokládat, že o jeho funkci nebude mít nikdo zájem. A pokud nedistribuujeme komponentu se zdrojovým kódem, pro dotyčného programátora zůstane tento prvek „nedobytný“. Sami si tam prostě tu property či events přidáme, komponentu, resp. balíček znovu přeložíme, a vše je v pořádku. Dalším, víceméně kosmetickým rozdílem mezi komponentou typu „custom“ a její „konečnou“ variantou je to, že v případě komponenty odvozené od „konečné“ varianty tato odvozená komponenta automaticky zdědí (pokud neurčíme jinak – také se naučíme jak) ikonku (přesněji bitmapu), která ji reprezentuje na paletě komponent. V opačném případě bude komponenta reprezentována defaultní bitmapou tvořenou 3 geometrickými obrazci v červené, modré a žluté barvě.

Zatím jsem se zmiňoval o koncových větvích stromu VCL. Často však je výhodné novou komponentu napsat „od základu“, což znamená odvodit ji od některého „základního uzlu“. V případě „okenních komponent“, tedy těch, které představují skutečné okno Windows, tj. mají handle, patří k nějaké třídě, mají proceduru okna atd., odvodíme takovou komponentu od TWinControl. Když se podíváte na hierarchický strom VCL, samozřejmě zjistíte, že všechny komponenty reprezentující standardní prvky Windows, tj. tlačítka, list-boxy, editační okna a mnoho dalších, jsou odvozeny přirozeně od TWinControl (samozřejmě s více či méně mezistupni jako zmíněné třídy typu TCustomxxxx). Dalším významným uzlem je objekt TComponent, což je nejnižší (nebo nejvyšší, podle směru pohledu na strom VCL) předek, od něhož můžete komponentu odvodit. Od tohoto objektu je odvozena většina nevizuálních komponent, tedy nevizuálních v tom smyslu, že nejsou viditelné v běžícím programu a během návrhu jsou reprezentovány svojí ikonou na formuláři. Jako příklad lze uvést třeba TTimer. V dalších dílech si ukážeme, jak vytvořit takovouto nevizuální komponentu, která umožní programátorovi-návrháři snadno zachytávat některé události, které běžný TForm neumí, třeba zprávy myši v neklientské oblasti okna a mnoho dalších.

Příště

Po tomto možná trochu nezáživném stručném teoretickém úvodu se v příštím pokračování již vrhneme na konkrétní tvorbu komponenty. Ukážeme si, jak založit nový balíček, do něhož si budeme komponenty umisťovat, a vytvoříme si první komponentu, kterou bude komponenta fungující jako hypertextový odkaz.

Témata článku: Software, Windows, Programování, Významná součást, Strom, Komponenta, Tvorba, TomTom, Toto, Běžná součást, Opačný případ, Díl, Visual Basic, Standardní verze, Tito

Určitě si přečtěte

Tesla chce změnit nákladní dopravu. Její elektrický náklaďák má ohromující parametry

Tesla chce změnit nákladní dopravu. Její elektrický náklaďák má ohromující parametry

** Tesla představila elektrický kamion ** Má obdivuhodný výkon i dojezd ** Prodávat by se měl už za dva roky

17.  11.  2017 | Vojtěch Malý | 228

Nejlepší notebooky do 10 tisíc, které si teď můžete koupit

Nejlepší notebooky do 10 tisíc, které si teď můžete koupit

** I pod hranicí desíti tisíc korun existují dobře použitelné notebooky ** Mohou plnit roli pracovního stroje i zařízení pro zábavu ** Nejlevnější použitelný notebook koupíte za pět a půl tisíce

16.  11.  2017 | Stanislav Janů | 54

Do 20 let nebude nikdo vlastnit auta, říká zkušený šéf několika automobilek

Do 20 let nebude nikdo vlastnit auta, říká zkušený šéf několika automobilek

** Bývalý šéf a expert z několika velkých automobilek se vyjádřil k budoucnosti tohoto průmyslu ** Do 20 let „nikdo“ nebude vlastnit auta ** Veškerá doprava bude řešená pomocí velkých logistických platforem

15.  11.  2017 | Karel Javůrek | 75


Aktuální číslo časopisu Computer

Otestovali jsme 5 HDR 4K televizorů

Jak natáčet video zrcadlovkou

Vytvořte si chytrou domácnost

Radíme s koupí počítačového zdroje