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.
Diskuze (7) Další článek: Letos by měl poprvé od roku 1986 klesnout roční prodej PC

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


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

Blíží se Juno. Jeden z nejhezčích Linuxů pro normální lidi

Blíží se Juno. Jeden z nejhezčích Linuxů pro normální lidi

** Ubuntu a Fedora patří k nejpopulárnějším linuxovým OS pro desktop ** A pak je tu zástup dalších nebo jejich odvozenin ** Jedním z nich je Elementary OS, který se brzy dočká novinek

Jakub Čížek | 71

Nechcete platit za Total Commander? Těmito bezplatnými programy ho můžete nahradit

Nechcete platit za Total Commander? Těmito bezplatnými programy ho můžete nahradit

** Total Commander je na Windows takřka legendou ** Licence však stojí více než tisíc korun ** Našli jsme pro vás deset alternativ dostupných zdarma

Karel Kilián | 121

Našli jsme 22 schopných internetových prohlížečů: Vyberte si, který vám nejvíc sedne

Našli jsme 22 schopných internetových prohlížečů: Vyberte si, který vám nejvíc sedne

** Není jen Chrome, Firefox, Edge či Opera. Na výběr máte mnohem více! ** Internetové prohlížeče se liší funkcemi, zaměřením i designem. Našli jsme 22 použitelných prohlížečů pro Windows ** Vyberte si prohlížeč, který vám bude nejvíce vyhovovat

Karel Kilián | 30

Jak dopadl velký den Applu s náloží novinek: Sledujte, co letos připravil

Jak dopadl velký den Applu s náloží novinek: Sledujte, co letos připravil

** Apple večer představil novinky ** Ukáže nové operační systémy, ale čekala se i nová zařízení ** Začíná vývojářská konference Applu WWDC 2018

Karel Javůrek | 87

Šmírovačka kamerami Googlu: Koukněte se, co nového zachytily na Street View

Šmírovačka kamerami Googlu: Koukněte se, co nového zachytily na Street View

Google stále fotí celý svět do své služby Street View. A novodobou zábavou je hledat v mapách Googlu vtipné záběry. Podívejte se na výběr nejlepších!

redakce | 42

Rekordy počasí: V Česku to ještě jde, skutečné extrémy zažívají jinde

Rekordy počasí: V Česku to ještě jde, skutečné extrémy zažívají jinde

** Teplotní extrémy dokážou překvapit. Seznamte se s rekordy v Česku i ve světě ** Rekordní hodnoty jsou mnohdy až k neuvěření ** Zjistěte, kdy ke bylo největší horko, zima, déšť či vítr

Karel Kilián | 7


Aktuální číslo časopisu Computer

Kdy necháme řídit chytrá auta?

6 Wi-Fi Mesh systémů ve velkém testu

Srovnali jsme 7 sportovních kamer

Znáte pravidla pro létání s drony?