Články

 

 

Průvodce tvorbou nápovědy – 8. díl

Další díl seriálu o tvorbě nápovědy. Tématem pro dnešek je tvorba nápovědní třídy a její využití v komponentě ActiveX DLL.

 

Vážení čtenáři,

 

dovolte, abych vás přivítal u dalšího dílu seriálu o nápovědě. Naše dnešní povídání bude malinko specifické, no myslím, že rozhodně užitečné. Tématem pro dnešek je tvorba nápovědní třídy a její využití v komponentě ActiveX DLL. Povíme jsi, co to vlastně třída je, jak se sestavuje, napíšeme vlastní třídu pro využití nápovědy v dalších aplikacích a vzpomeneme i využití nápovědy při tvorbě třídy.

 

 Pojem třída

 Třída a komponenty ActiveX

 Tvorba komponenty ActiveX DLL

 Testování komponenty ActiveX DLL

 Implementace nápovědy do komponenty ActiveX DLL

 Distribuce a registrace komponenty ActiveX DLL

 

Co jsi představit pod pojmem „třída“? Pro zjednodušení uvažujme o třídě jako o jakési definici nebo šabloně, která slouží k vytváření jednotlivých instancí objektů. Pokud budeme abstrahovat od obecné teorie objektového programování a zaměříme se jenom na použití třídy ve Visual Basicu, potom můžeme prohlásit, že třída slouží jako nevyhnutný „podklad“ pro vytváření objektů. Samotný objekt, neboli instance určité třídy, je kombinací dat a algoritmů a je charakteristický svými metodami a vlastnostmi. Pomocí interakce s okolím je pak objekt schopný reagovat na vnější podněty, ve vizuálním programování označované jako události. Řečeno jinými slovy, objekt má svojí vlastní identitu a může pohotově reagovat na okolní podněty. V našem ponímání není nezbytné, aby jsme objektovou koncepci zkoumaly příliš do hloubky. Nám stačí, když budeme vědět, že třída je pro nás základním kamenem pro generování objektů jistého typu.

 

Aby jsme byly konkrétnější, přesuňme se nyní do prostředí Visual Basicu. Tady je třída chápána jako jistý druh modulu, kterému se říká modul třídy. Moduly tříd mají (ve VB) standardně třípísmennou koncovku .cls a podle tohoto znaku je můžete lehce poznat. Samotná anatomie modulu třídy je velmi podobná standardnímu modulu. Pokud máte zkušenosti s práci s klasickými moduly, nebude vám dělat potíže ani programování vlastních tříd.

 

Třída je základem pro vývoj určitého typu objektu. Objekt je zase charakterizován svými vlastnostmi a metodami. Možná se teď ptáte, jak vlastně takové vlastnosti a metody objektu vytvořit. Odpověď na tuto otázku spočívá v jistém ponímání nebo-li specifickém pohledu na modul třídy jako takový. Metody objektu jsou implementovány jako jednotlivé procedury, které do modulu třídy vloží programátor. Vlastnosti lze objektu přiřadit dvěma způsoby, a sice definováním veřejných proměnných v deklarační částí modulu třídy, nebo využitím speciálních procedur typu Property Get a Property Let. Pokud tedy nahlížíte na třídu takhle, určitě vám je celá problematika ihned jasnější.

 

Proč ale mluvím o třídách? Jednoduše proto, že jejich zařazení do projektu v podobě komponent ActiveX je velmi užitečné a poskytuje mnoho výhod. Pod pojmem komponenta ActiveX lze chápat tři základní typy: ActiveX DLL, ActiveX EXE a ovládací prvek ActiveX. Dynamicky linkovaná knihovna ActiveX DLL je ponímána jako vnitroprocesový server, protože je vždy načtena do procesu klientské aplikace. Naproti tomu je zde další komponenta, ActiveX EXE, která je označována jako mimoprocesový server, protože je vždy načtena do svého vlastního procesu a takhle poskytuje služby dalším aplikacím. Posledním je ovládací prvek ActiveX, co je ve skutečnosti prvek, který můžete umístit na panel nástrojů ve VB. Nebudu vás dále zatěžovat teoretickými poznatky a charakteristikami jednotlivých komponent ActiveX. Jenom bych rád zdůraznil, že při vývoji komponent ActiveX jsou prvotním základem vždy třídy. Jak jsem již konstatoval, napsání takové vlastní komponenty má více výhod. Především je to znovupoužití programového kódu a minimální míra jeho duplicity. Když jednou vytvoříte skvěle fungující komponentu, můžete ji použít v dalších nastávajících projektech bez toho, abyste jakkoliv měnily strukturu procedur nebo samotného kódu. Jednoduše existující komponentu přidáte ke svému projektu a všechny vlastnosti a metody, které jste naprogramovaly můžete okamžitě využít. A tím se postupně dostáváme k jádru věci. Předpokládám, že při vývoji aplikací dbáte na komplexnost, a tedy pracujete i s nápovědou. Proč byste ale měly psát tentýž kód pro použití nápovědy v každé další aplikaci, když jsi můžete vytvořit vlastní komponentu ActiveX a všechny potřebné nezbytnosti realizovat pomocí jedné třídy? Aby vaše cesta byla co možná nejmíň problematická, ukážeme jsi, jak takovou „nápovědní“ třídu vytvořit.

 

Spusťte VB a při výběru typu projektu zvolte „ActiveX DLL“.

 

 

VB automaticky vytvoří projekt s jedním modulem třídy, který je standardně pojmenován jako Class1. Přesuňte se do okna Properties a změňte jméno třídy na NápovědníTřída1. Dále klepněte v okně Project Explorer na první položku (označenou jako Project1) a přejmenujte ji na Nápověda1DLL. Následně projekt uložte.   

 

Když máte vše připravené, můžeme konečně začít s psaním metod pro naši třídu. Zvolte nabídku Tools a první položku Add Procedure. V dialogovém okně zadejte název procedury, jak je uvedeno na obrázku níže, a stiskněte tlačítko OK.

 

 

VB vloží do modulu třídy proceduru se zadaným názvem. Aby procedura věděla, který soubor nápovědy má použít, je nutno jej blíže určit. Patrně nejlepším místem pro uchování jména nápovědného souboru je první parametr procedury. Po úpravě by měla procedura vypadat takhle:

 

Public Sub ZobrazitObsahNapovedy(soubor As String)

 

End Sub

 

Pro zobrazení souboru nápovědy použijeme funkci WinHelp. První parametr funkce WinHelp přijímá identifikaci okna (handle) ve tvaru dlouhého celého čísla (Long). Pro zjištění handle okna použijeme API funkci GetActiveWindow (budeme předpokládat, že vždy aktivní okno aplikace si bude žádat spuštění nápovědy). Deklarace obou funkcí zkopírujte z aplikace API Viewer (nebo z níže uvedeného výpisu) a vložte je do deklarační části modulu třídy. Dále vložte i konstanty potřebné pro funkci WinHelp. Postačí tyto čtyři: HELP_CONTENTS, HELP_CONTEXT, HELP_CONTEXTPOPUP a HELP_QUIT. Rozsah působnosti vložených funkcí a konstant upravte z Public na Private.

 

Deklarační část modulu třídy by potom měla mít následující podobu:

 

Private Const HELP_CONTENTS = &H3&

Private Const HELP_CONTEXT = &H1

Private Const HELP_CONTEXTPOPUP = &H8&

Private Const HELP_QUIT = &H2

 

 

Private Declare Function GetActiveWindow Lib _

"user32" () As Long

 

Private Declare Function WinHelp Lib _

"user32" Alias "WinHelpA" ( _

ByVal hwnd As Long, _

ByVal lpHelpFile As String, _

ByVal wCommand As Long, _

ByVal dwData As Long _

) As Long

 

Nyní se přemístěte do procedury ZobrazitObsahNapovedy a zapište do ní tento kód:

 

Call WinHelp(GetActiveWindow(), soubor, HELP_CONTENTS, 0)

 

Uvedený segment kódu volá funkci WinHelp a zobrazuje úvodní nabídku nápovědy. Všimněte jsi, že jako druhý parametr funkce WinHelp je předán parametr funkce ZobrazitObsahNapovedy. Další zajímavostí je vnořená funkce GetActiveWindow.

 

 Poznámka: Jestli používáte soubor nápovědy, který obsahuje i obsahový soubor, potom by bylo vhodnější nahradit konstantu HELP_CONTENTS konstantou HELP_FINDER, jejíž hodnota je 11 (neboli &HB v hexadecimálním tvaru).    

 

Výborně, první metoda je vytvořená. Identickým postupem můžete přidat další proceduru, kterou pojmenujte jako ZobrazitTemaNapovedy. Procedura bude následovní:

 

Public Sub ZobrazitTemaNapovedy(soubor As String, CisloTemy As Long)

Call WinHelp(GetActiveWindow(), soubor, HELP_CONTEXT, CisloTemy)

End Sub

 

Pro zobrazení nápovědného tématu musíte jednoznačně specifikovat i jeho kontextové číslo neboli identifikátor. Předpokládá se, že volaný soubor nápovědy má k jednotlivým tématům přiřazeny kontextová identifikační čísla Jak přiřadit tématům nápovědy kontextová čísla?.

 

Pro úplnost uvedu již jenom výpis kódu zbylých procedur i s komentáři.

 

Public Sub ZobrazitPopupOkno(soubor As String, CisloTemy As Long)

Call WinHelp(GetActiveWindow(), soubor, HELP_CONTEXTPOPUP, CisloTemy)

End Sub

 

Procedura (metoda) ZobrazitPopupOkno zabezpečuje zobrazení nápovědného tématu v popup okně (popup oknem se rozumí okno obdélníkového tvaru, většinou se žlutou barvou pozadí).

 

Public Sub UkoncitNapovedu(soubor As String)

Call WinHelp(GetActiveWindow(), soubor, HELP_QUIT, 0)

End Sub

 

Procedura UkoncitNapovedu je odpovědná za zavření nápovědného okna a ukončení spuštěné instance WinHelpu.

 

Po sepsání všech procedur vygenerujte komponentu ActiveX DLL. V menu File klikněte na volbu Make Nápověda1DLL.dll a aktivujte tlačítko OK. VB sestaví komponentu se zadaným názvem a automaticky ji v systému zaregistruje. Pokud se podíváte do složky, ve které jste uložily projekt, uvidíte, že vytvořená dynamicky linkovaná knihovna vypadá takhle:

 

 

Jestli chcete vědět víc, můžete na ikonu klepnout pravým tlačítkem myši a zvolit položku Vlastnosti.

 

Když máte komponentu vytvořenou, budete ji chtít zajisté otestovat. Vraťte se proto do projektu VB a z menu File zvolte Add Project a v dialogovém okně vyberte možnost Standard EXE. Zobrazení okna Project Explorer by mělo být následovní:

 

 

Na formulář přidejte jedno tlačítko. Aby bylo možné využít možností naší komponenty, musíme do projektu (Project1 v Project Exploreru) přidat na ní odkaz. Zvolte nabídku Project a položku References. V okně zatrhněte volbu Nápověda1DLL, která označuje vytvořenou komponentu a klepněte na OK.

 

 

Dále aktivujte tlačítko Object Browser z panelu nástrojů, nebo stiskněte klávesu F2.   

Z otvíracího seznamu vyberte položku Nápověda1DLL.

 

 

Po selekci knihovny uvidíte v levé části okna Object Browseru jméno třídy a po klepnutí na něj se napravo objeví jednotlivé metody, které jste naprogramovali. Když na metodu klepněte, ve spodní části se objeví její popis. Pojďme však ke „skutečnému“ testování komponenty.

 

Poklepejte na formulář testovacího projektu, čímž se otevře okno s kódem. Dále postupujte takto:

 

1. Deklarujte objektovou proměnnou v deklarační části formuláře.

 

Dim nap As NápovědníTřída1

 

2. V obsluze události Load formuláře vytvořte objekt typu NápovědníTřída1 pomocí příkazu Set a klausule New.

 

Set nap = New NápovědníTřída1

 

3. Do obsluhy události Click tlačítka zadejte jméno proměnné, tečku a všimněte jsi, že VB vám nabídnul sadu metod k použití.

 

 

Ano, jsou to přesně ty metody, které jste zapsali do třídy NápovědníTřída1 při konstrukci komponenty ActiveX DLL. Jak vidíte, VB pracuje s naší komponentou jako s kteroukoli jinou.

 

4. Ze seznamu vyberte třeba metodu ZobrazitObsahNapovedy. Po zadání mezery VB zobrazí okamžitou nápovědu:

 

 

Jako parametr metody zapište soubor nápovědy, který chcete zobrazit:

 

nap.ZobrazitObsahNapovedy "c:\pokus"

 

Aby bylo možné testovací projekt spustit, klepněte v okně Project Explorer na položku Project1 pravým tlačítkem myši a vyberte možnost Set as Start Up. Stiskněte klávesu F5, čímž spustíte projekt. Dále klikněte na tlačítko a soubor nápovědy se zobrazí. Skvělé, že?

 

Samozřejmě, že můžete experimentovat i s dalšími metodami. Např. pro zobrazení tématu s kontextovým číslem 100, použijte tento kód:

 

nap.ZobrazitTemaNapovedy "c:\pokus", 100

 

Když už nebudete nápovědu potřebovat, jednoduše zavolejte metodu UkoncitNapovedu a zlikvidujte vytvořený objekt pomocí příkazu Set nap = Nothing.

 

Takto se tedy vytvářejí a používají komponenty ActiveX DLL. Standardním programátorům a vývojářům by uvedené techniky stačily, no my půjdeme ještě mnohem dále. Jednoduše přidáme nápovědu i k vytvořené komponentě a důsledně jí zakomponujeme do projektu. Že to opravdu jde udělat se přesvědčíte na následujících řádcích.

 

 

Implementace nápovědy do komponenty ActiveX DLL

Pokud uvažujeme o zařazení nápovědy do projektu s komponentou, musí být splněny určité podmínky. Předně musí existovat samotný nápovědný soubor (pro naše potřeby klasický hlp soubor). Soubor musí obsahovat témata a těmto musejí být přiřazeny jedinečné kontextové identifikátory. Když váš soubor nápovědy vyhovuje všem uvedeným požadavkům, můžeme přikročit k práci.

 

1. Spusťte VB a otevřete náš projekt ActiveX DLL.

2. Z nabídky Project vyberte poslední položku Nápověda1DLL Properties.

3. V dialogovém okně vyberte nápovědný soubor pro projekt.

4. Nyní zaměřte svou pozornost na okno Project Explorer a poklepejte na položku NápovědníTřída1.

5. V modulu třídy vyberte proceduru ZobrazitObsahNapovedy. Aktivujte menu Tools a volbu Procedure Attributes.

 

Objeví se toto okno:

 

 

V šedém poli Project Help File je již vybrán soubor nápovědy, který jsme určili ve třetím kroku tohoto postupu. Do textového pole Description napište stručnou charakteristiku metody a do pole Help Context ID zadejte číselnou hodnotu, která byla přiřazena nápovědnému tématu v procesu mapování. Výsledek může být jako na obrázku dole.

 

 

Po vykonaných změnách klepněte na tlačítko Apply, čímž se změny uloží. Okno zavřete třeba kliknutím na OK.

 

V okně Project Explorer poklepejte na ikonu formuláře testovacího projektu. Stiskněte klávesu F2, nebo spusťte Object Browser z panelu nástrojů. Vyberte nápovědní třídu a metodu ZobrazitObsahNapovedy. Všimněte jsi popis ve spodní části okna.

 

  

 

Pokud byste aktivovali tlačítko Help, mohl by se zobrazit i soubor s nápovědou. Třeba takto:

 

 

Stejným způsobem se přidávají odkazy na nápovědné témata i u dalších procedur. Jediným problémem by snad mohlo být přiřazení nápovědy k položce NápovědníTřída1, která se nachází v sekce Classes v levé části okna aplikace Object Browser. Postup řešení je poměrně komplikovaný, avšak tady je:

 

1. V projektu klepněte na položku NápovědníTřída1 v okně Project Exploreru.

2. Spusťte Object Browser.

3. Klepněte na položku NápovědníTřída1 pravým tlačítkem myši a zvolte položku Properties.

 

 

4. Objeví se toto okno:

 

 

Do pole Description napište stručný popis třídy a do pole Help Context ID zase kontextové číslo tématu, které se má zobrazit. Nakonec klepněte na tlačítko OK.

 

Uskutečněné změny můžete otestovat tak, že v okně Project Exploreru poklepete na formulář testovacího projektu, stiskněte klávesu F2, označíte položku NápovědníTřída1 a klikněte na ikonu s otazníkem.

 

Na závěr ještě pár slov ohledně použití a distribuce komponenty ActiveX DLL. Jak jsem se již zmínil, VB komponentu při kompilaci automaticky zaregistruje v systému. Podobná je situace, když komponentu přidáte ke samostatnému projektu a instalační disky vytvoříte pomocí aplikace Package&Deployment Wizard. Při instalaci na klientský počítač je komponenta automaticky zaregistrována. Jinak je to ovšem tehdy, když se rozhodnete vytvořenou komponentu jenom tak přenést (zkopírovat) na jiný počítač. Tato by nepracovala správně, protože pouhým zkopírováním komponenty do cílové složky hostitelského počítače by ještě nedošlo i k samotné registraci. V těchto situacích vám pomůže jednoduchý program s názvem RegSvr32, který má na starosti zaregistrování komponenty v systému, nebo naopak její odstranění z počítače. Uvedený program lze obvykle najít v systémové složce Windows, nebo na instalačních discích k VB. Program je nutné spouštět z příkazového řádku s platnými parametry. Pro zaregistrování komponenty použijte tento zápis (cestu k programu a komponentě upravte dle potřeby):

 

c:\windows\system\regsvr32 c:\NápovědníTřída1.dll

 

Pro odstranění registrace pak:

 

c:\windows\system\regsvr32 /u c:\NápovědníTřída1.dll

 

Na shledanou příště.

 

 Ján Hanák