P R O G R A M U J E M EObr. 3 Prípad 1 Obr. 4 Prípad 2 Obr. 5 Prípad 3 Obr. 6 Prípad 4Obr. 7 Vlastné Menu aj ToolBarBOOL ReplaceBitmap(HBITMAP hBitmap, UINT nCommandID)BOOL ReplaceIcon(HICON hIcon, UINT nCommandID)BOOL RemoveImage(int nCommandID)BOOL RemoveAllImages()BOOL TrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, LPTPMPARAMSlpParams = NULL)// Poznámka: Obmedzená podpora pre MDI – iadne ikony alebo tlaèidlá min/max/close.BOOL SetMDIClient(HWND hWndMDIClient) Implementácia – ownerdraw metódvoid DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)void DrawMenuText(CDCHandle& dc, RECT& rc, LPCTSTR lpstrText, COLORREF color)void DrawBitmapDisabled(CDCHandle& dc, int nImage, POINT point)BOOL Draw3DCheckmark(CDCHandle& dc, const RECT& rc, BOOL bSelected,BOOL bDisabled, BOOL bRadio, HBITMAP hBmpCheck)void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) Implementácia – hook procsstatic LRESULT CALLBACK CreateHookProc(int nCode, WPARAM wParam, LPARAMlParam)static LRESULT CALLBACK MessageHookProc(int nCode, WPARAM wParam, LPARAMlParam) Implementácia – menuvoid DoPopupMenu(int nIndex, bool bAnimate)BOOL DoTrackPopupMenu(HMENU hMenu, UINT uFlags, int x, int y, LPTPMPARAMSlpParams = NULL)int GetPreviousMenuItem() constint GetNextMenuItem() constvoid GetSystemSettings() Implementácia – alter<strong>na</strong>tívnej podpory focus móduvoid TakeFocus()void GiveFocusBack() Implementácia – interných pomocných správstatic UINT GetAutoPopupMessage()static UINT GetGetBarMessage()Na obrázkoch 3, 4, 5 a 6 môete vidie štyri z moných stavov komponentu ReBar. Prvýprípad – Rebar1 – obsahuje štandardné Win<strong>do</strong>ws Menu, ReBar2 obsahuje rozdielne me−nu. Obidva komponenty ReBar sú umiestnené <strong>na</strong> jednom riadku. Druhý prípad – kompo−nent Rebar môeme pomocou drag&drop presunú <strong>na</strong> samostatný ria<strong>do</strong>k a opaène. Tretíprípad <strong>na</strong>stane, keï v súbore stdafx.h urobíte <strong>na</strong>sledujúce zmeny:...// Change these values to use different versions#define WINVER 0×0400//#define _WIN32_WINNT 0×0400#define _WIN32_IE 0×0400#define _RICHEDIT_VER 0×0100...Po úprave hodnôt WINVER a _WIN32_IE sa zobrazí z<strong>na</strong>k "o" (pozri príklad 3). Tentoz<strong>na</strong>k sa zobrazí vdy, keï prekryjete jeden ReBar druhým. Po kliknutí <strong>na</strong> tento z<strong>na</strong>k sazobrazí pop−up menu skrytej èasti komponetu ReBar. Štvrtý prípad ukazuje, e <strong>na</strong> ReBarmono umiestni aj ToolBar (pozri obrázok 7) a, samozrejme, aj iné prvky (o tom však nie−kedy <strong>na</strong>budúce)....// Change these values to use different versions#define WINVER 0×0500#define _WIN32_IE 0×0501#define _RICHEDIT_VER 0×0100#define _WIN32_WINNT 0×0500...Peter GašparovièAko <strong>na</strong> Visual Basic .NET / 4. èasPre programátorov, ktorí boli <strong>do</strong>posia¾ zvyknutí <strong>na</strong> prácu vo Visual Basicu 6, môe by pre−chod <strong>na</strong> novú .NET verziu tohto programovacieho jazyka zo zaèiatku z<strong>na</strong>ène komplikova−ný. Je pravda, e Visual Basic .NET je v porov<strong>na</strong>ní so svojím predchodcom predsa lenrobustnejší a aj mnohí profesionálni programátori, ktorí poz<strong>na</strong>li všetky „tajomné“ zákutiaVB 6, zostanú po prvých skúsenostiach s novou platformou <strong>na</strong> pochybách. Keïe jednýmz hlavných cie¾ov tohto seriálu je maximálne vám u¾ahèi prechod <strong>na</strong> novú verziu VisualBasicu, budeme vdy, keï to bude moné, aplikova filozofiu „známych skutoèností“. Toz<strong>na</strong>mená, e <strong>na</strong>jskôr budeme vychádza z tých skutoèností a faktov, ktoré sú vám, akostredne pokroèilým programátorom vo VB 6, známe, a následne poukáeme <strong>na</strong> nové po−òatie skúmanej problematiky z poh¾adu jazyka VB .NET.PREMENNÉ VO SVETE .NET. Základnou stavebnou jednotkou kadého programu sú(popri iných programových entitách) premenné. Premenné sú schopné uklada rôzne typy úda−jov v závislosti od špeciálnej charakteristiky, ktorú im priraïuje deklaraèný príkaz so špecifiká−ciou platného dátového typu. Visual Basic 6 vám umoòoval deklarova premenné z<strong>na</strong>ènéhomnostva dátových typov. VB .NET ïalej modifikuje mnoinu vstavaných dátových typov, takesa pravdepo<strong>do</strong>bne stretnete i so zástupcami dátových typov, s ktorými ste ešte nepracovali.Nové dátové typy môeme rozdeli <strong>do</strong> troch základných kategórií: Dátové typy <strong>na</strong> ukladanie celých èísel (Byte, Short, Integer, Long) Dátové typy <strong>na</strong> ukladanie èísel s pohyblivou desatinnou èiarkou (Single, Double,Decimal) Ostatné dátové typy (Boolean, Char, String a Object)Aby sme mohli vyui monosti príslušného dátového typu, musíme <strong>na</strong>jskôr deklarovapremennú tohto dátového typu. Deklarácia premennej sa uskutoèní po<strong>do</strong>bne ako vo VB 6pouitím deklaraèného príkazu Dim:Dim premenná As IntegerZa príkazom Dim <strong>na</strong>sleduje meno premennej, k¾úèové slovo As a názov platného dáto−vého typu (v <strong>na</strong>šom prípade typ Integer). V reime behu aplikácie deklaraèný príkaz za−bezpeèí alokáciu <strong>do</strong>statoène ve¾kého pamäového miesta <strong>na</strong> to, aby sa <strong>do</strong> neho mohlaneskôr uloi urèitá hodnota, ktorá spåòa poiadavky týkajúce sa rozsahu pouitého dáto−vého typu. Deklaraèný príkaz teda sprístupòuje <strong>do</strong>statoène ve¾ký pamäový priestor, alezatia¾ tento priestor ponecháva prázdny. Na to, aby bolo moné vytvorený pamäovýpriestor vyplni, je potrebné premennú inicializova. Pod pojmom inicializácia premennejsa rozumie priradenie istej hodnoty <strong>do</strong> tejto premennej pomocou priraïovacieho príkazus pouitím operátora <strong>na</strong> priradenie. Keby sme teda chceli deklarovanú premennú iniciali−zova, <strong>na</strong>písali by sme tento ria<strong>do</strong>k programového kódu:premenná = 10000V tomto okamihu je numerická hodnota 10000 priradená <strong>do</strong> premennej. Takisto mô−eme poveda, e spomí<strong>na</strong>né vytvorené pamäové miesto je zaplnené priradenou hodno−tou. Keïe hodnota 10000 spåòa rozsah dátového typu Integer, je všetko v poriadku a pri−raïovací príkaz úspešne realizuje svoju èinnos.Ak ste vo VB 6 chceli deklarova a následne inicializova premenné, postupovali ste vdyv uvedených dvoch krokoch. VB .NET však prichádza s novinkou, ktorá vám umoní spojioba procesy (deklaráciu a inicializáciu premennej) <strong>do</strong> jedného príkazu:Dim premenná As Integer = 10000Programová konštrukcia deklaraèno−inicializaèného príkazu je výhodnejšia, a pokia¾ tobude moné, mali by ste ju vdy vyuíva. Samozrejme, nie vo všetkých prípa<strong>do</strong>ch je mo−né premennú pri deklarácii okamite inicializova (jednoducho nemusíme vdy poz<strong>na</strong> po−trebnú inicializaènú hodnotu). Pokia¾ vo vašej aplikácii pouívate mnostvo globálnychpremenných, je moné, e <strong>na</strong>jskôr deklarujete všetky verejné premenné a potom ich v prí−pade potreby inicializujete.Ak nebudete priamo inicializova premenné jednotlivých dátových typov, VB .NET im implicitne prira−dí tzv. štandardné inicializaèné hodnoty. Tak sú premenné všetkých èíselných dátových typov inicia−lizované <strong>na</strong> nulovú hodnotu, premenné dátového typu Boolean zasa <strong>na</strong> hodnotu False a premennédátového typu Date <strong>na</strong> 12. hodinu 1. januára roku 1. Štandardnú inicializaènú hodnotu dátových typovString a Object (ako aj iných referenèných dátových typov) tvorí špeciál<strong>na</strong> hodnota Nothing.CHARAKTERISTIKA CELOÈÍSELNÝCH DÁTOVÝCH TYPOV. Premenné týchtodátových typov sú schopné uchováva celoèíselnú hodnotu. Ich technický opis môetenájs v tab. 1.Tab. 1Názov dátového typu Opis Rozsah .NET ekvivalentByte 8−bitové èíslo bez z<strong>na</strong>mienka System.ByteShort 16−bitové èíslo so z<strong>na</strong>mienkom System.Int16Integer 32−bitové èíslo so z<strong>na</strong>mienkom System.Int32Long 64−bitové èíslo so z<strong>na</strong>mienkom System.Int647/2003 PC REVUE 119
P R O G R A M U J E M ERozsah kadého celoèíselného dátového typu je uvádzaný v bitoch. Bit, ako základnájednotka informácie, môe disponova iba dvoma monými hodnotami, a to nulou alebojednotkou. Postupnos zvyèajne ôsmich po sebe idúcich bitov je oz<strong>na</strong>èovaná ako jedenbajt (byte). Bajt predstavuje základnú jednotku kapacity. Rozsah dátového typu je monécharakterizova aj ako definièný obor tohto dátového typu. Ide teda o mnoinu prípust−ných hodnôt, ktoré môu by priradené <strong>do</strong> premennej daného dátového typu. Všetky dá−tové typy (okrem typu Byte), ktoré sú uvedené v tab. 1, môu uchováva èísla so z<strong>na</strong>mien−kom. Z<strong>na</strong>mená to, e pouitím priraïovacieho príkazu je moné <strong>do</strong> premenných týchtodátových typov uloi okrem kladných aj záporné èíselné hodnoty (opä v závislosti odplatne definovaného rozsahu príslušného dátového typu). Celoèíselné dátové typy (alenielen tie) majú svoje .NET ekvivalenty, èo je názov systémových dátových typov, ktoré sapouívajú v exekuènom prostredí .NET Frameworku.Pretoe kadá .NET aplikácia je pred reimom exekúcie preloená <strong>do</strong> MSIL, sú všetky pouité dátovétypy <strong>na</strong>hradené ich .NET ekvivalentmi. Tak sa <strong>na</strong>príklad z dátového typu Integer stáva System.Int32.Pouitie .NET ekvivalentov dátových typov umoòuje zabezpeèi úplnú typovú kompatibilitu (tú má <strong>na</strong>starosti Common Type System). Z tohto dôvodu je moné prenáša údaje medzi komponentmi a prog−ramovými súèasami, ktoré boli vytvorené v rozlièných jazykoch platformy .NET (<strong>na</strong>pr. vo VB .NET a VisualC# .NET). Proces bezproblémového prenosu dát je jedným zo základných prvkov interoperability prog−ramovacích jazykov podporujúcich štandard .NET.Pri poh¾ade <strong>na</strong> rozsah celoèíselných dátových typov si iste všimnete, e v porov<strong>na</strong>ní spredchádzajúcou verziou Visual Basicu bola táto pri mnohých typoch z<strong>na</strong>ène rozšírená.Vezmime si <strong>na</strong>príklad typického zástupcu celoèíselných dátových typov, ktorým je dátovýtyp Integer. Vo VB 6 bol jeho rozsah ove¾a menší, presnejšie bol porov<strong>na</strong>te¾ný s rozsahomdátového typu Short vo VB .NET. Pri podrobnejšom štúdiu by sme mohli prís <strong>na</strong> ïalšiuzaujímavos: Rozsah dátového typu Long vo VB 6 je totoný s rozsahom dátového typuInteger vo VB .NET.Skutoènos, e definièný obor dátových typov je vo Visual Basicu .NET iný, ako to bolopri VB 6, by ste mali ma odteraz vdy <strong>na</strong> pamäti. Najmä ak budete chcie vola z VB .NET<strong>na</strong>tívne funkcie API operaèného systému Win<strong>do</strong>ws, je ve¾mi pravdepo<strong>do</strong>bné, e budetemusie poui špecifikáciu iných dátových typov parametrov funkcií a ich potenciálnychnávratových hodnôt.CHARAKTERISTIKA DÁTOVÝCH TYPOV PRE UKLADANIE ÈÍSEL S POHYB−LIVOU DESATINNOU ÈIARKOU. Ak budete chcie vo vašom programovom kódeuskutoèòova matematické operácie s poa<strong>do</strong>vanou presnosou, urèite vám prídu vhoddátové typy, ktoré sú schopné pracova s èíslami s pohyblivou desatinnou èiarkou. A<strong>na</strong>ly−tický poh¾ad <strong>na</strong> tento segment dátových typov poskytuje tab. 2 a tab. 3.Tab. 2Názov dátového typu Opis Presnos .NET ekvivalentSingle 32−bitové èíslo s pohyblivou 7 desatinných miest System.Singledesatinnou èiarkouDouble 64−bitové èíslo s pohyblivou 15 – 16 desatinných miest System.Doubledesatinnou èiarkouDecimal 128−bitové èíslo s pohyblivou 28 desatinných miest System.Decimaldesatinnou èiarkouTab. 3Názov dátového typuRozsahSingle Double Decimal Kadý zástupca predstavenej mnoiny dátových typov je schopný pracova so skutoè−ne obrovskými èíselnými hodnotami. Pre dátové typy <strong>na</strong> uchovávanie èísel s pohyblivoudesatinnou èiarkou však nie je determinujúcim parametrom ani tak samotný rozsah prí−slušného dátového typu, ale presnos daného dátového typu. Termín presnos je vyjadre−ný poètom signifikantných miest za desatinnou èiarkou èísel, ktoré Visual Basic berie <strong>do</strong>úvahy pri matematických operáciách.Hoci je dátový typ Single charakteristický <strong>na</strong>jmenšou presnosou, môete ho výhodnepoui vo chví¾ach, keï budete potrebova pracova s desatinnými èíslami, ale presnosuskutoèòovaných operácií nebude pre vás hra hlavnú úlohu. Maximalizáciu presnosti<strong>do</strong>siahnete pouitím dátového typu Decimal. Je to nový dátový typ, ktorý istým spôsobom<strong>na</strong>hrádza dátový typ Currency z VB 6 (dátový typ Currency sa pouíval <strong>na</strong>jèastejšie priuskutoèòovaní peòaných kalkulácií). Na druhej strane, ak vaša práca nebude vya<strong>do</strong>vazloité fi<strong>na</strong>nèné operácie, pravdepo<strong>do</strong>bne nebudete ma prive¾a moností <strong>na</strong> to, aby stepremenné dátového typu Decimal vo svojej aplikácii pouívali. Tretím kandidátom je dá−tový typ Double, ponúkajúci svojich 64 bitov <strong>na</strong> uloenie èísel s pohyblivou desatinnouèiarkou. V prípade, keï budete optimalizova svoj zdrojový kód z h¾adiska poa<strong>do</strong>vanejrýchlosti a <strong>do</strong>stupnej presnosti, je moné, e práve dátový typ Double sa stane vaším ob−¾úbencom.CHARAKTERISTIKA OSTATNÝCH DÁTOVÝCH TYPOV. Hoci som zostávajúcedátové typy zaradil <strong>do</strong> kolónky „ostatné“, v iadnom prípade nejde o dátové typy, ktoréby ste vyuívali len príleitostne alebo vôbec nie. Práve <strong>na</strong>opak. V ïalšom texte sa obo−známime s mnostvom zaujímavých dátových typov a nájdu sa aj novinky, s ktorými smeešte nemali tú èes stretnú sa pri programovaní v jazyku Visual Basic. Dátový typ Boolean (.NET ekvivalent: System.Boolean)Po<strong>do</strong>bne ako vo VB 6 i vo VB .NET sa dátový typ Boolean pouíva pri deklaráciách pre−menných, ktorých hodnoty reprezentujú dva pravdivostné stavy: True (Pravda) a False (Ne−pravda). Vo všeobecnosti môeme poveda, e premenné tohto dátového typu vdy pra−cujú s práve špecifikovanými pravdivostnými hodnotami (aj keï je <strong>do</strong> premennej typuBoolean priradená numerická hodnota, automaticky sa konvertuje <strong>na</strong> jednu z monýchpravdivostných hodnôt). So zástupcami premenných dátového typu Boolean sa môetestretnú <strong>na</strong>jèastejšie pri cykloch alebo rozho<strong>do</strong>vacích programových konštrukciách (<strong>na</strong>pr.kód cyklus sa opakuje <strong>do</strong>vtedy, kým je pravdivostná hodnota riadiacej premennej True, apod.). Na záver treba <strong>do</strong>da, e premenné dátového typu Boolean sú interne ukladanéako 16−bitové èísla. Dátový typ Char (.NET ekvivalent: System.Char)Prostredníctvom dátového typu Char je moné pracova so symbolmi Unicode v roz−sahu . Premenné tohto dátové typu je moné poui <strong>na</strong> uchovanie jedinéhosymbolu, resp. z<strong>na</strong>ku. Keby sme <strong>na</strong>príklad chceli deklarova premennú písmeno typuChar a následne <strong>do</strong> tejto premennej priradi z<strong>na</strong>k „M“, postupovali by sme takto:Dim písmeno As Charpísmeno = „M“cAko si môete všimnú, písmeno M je v priraïovacom príkaze umiestnené <strong>do</strong> dvojitýchúvodzoviek, za ktorými sa <strong>na</strong>chádza sufix v po<strong>do</strong>be písme<strong>na</strong> c. Prítomnos sufixu vravíVisual Basicu .NET, aby <strong>na</strong> text v úvodzovkách <strong>na</strong>hliadal ako <strong>na</strong> symbol dátového typuChar. Pouitie tohto sufixu je povinné vtedy, ak pri programovaní pouívate vo¾bu OptionStrict <strong>na</strong>stavenú <strong>na</strong> hodnotu On.Vo¾ba Option Strict je vo Visual Basicu .NET nová. Jej aktivácia zamedzuje priamu realizáciu konverziíhodnôt dátových typov, ak by pri týchto konverziách mohlo dôjs k strate dát. Štandardne je táto vo¾bavypnutá (teda Option Strict Off), a to z dôvodu spätnej kompatibility s VB 6. Ak ju budete chciezapnú, musíte zada ria<strong>do</strong>k kódu s príkazom Option Strict On ešte pred programový kód triedy for−mulára (štandardne Form1). Ako sme si u povedali, hlavným zmyslom zavedenia tejto vo¾by je s<strong>na</strong>hao zachytenie neelate¾ného výskytu chýb pri automaticky uskutoèòovaných konverziách hodnôt dáto−vých typov. So zapnutou vo¾bou bude zakázaná taká konverzia, ktorá by mohla spôsobi stratu úda−jov, ale konverzie, ktoré neohrozia stratu údajov, budú i <strong>na</strong>ïalej uskutoèòované implicitne. Ak všakbudete chcie výslovne <strong>na</strong>riadi uskutoènenie konverzie medzi hodnotami rozlièných dátových typov,pri ktorej by mohlo dôjs k strate dát, budete musie poui funkciu CType.Ïalšou uitoènou vo¾bou je Option Explicit. Tá vám je pravdepo<strong>do</strong>bne známa z predchádzajúcejverzie jazyka Visual Basic. Ak je táto vo¾ba aktivovaná (Option Explicit On), budete musie vo vašomprogramovom kóde deklarova všetky pouívané premenné. Zápis vo¾by Option Explicit sa musí <strong>na</strong>−chádza po<strong>do</strong>bne ako zápis vo¾by Option Strict pred akýmko¾vek iným programovým kó<strong>do</strong>m. Dátový typ String (.NET ekvivalent: System.String)Vo chví¾ach, keï budete potrebova pracova s textovými reazcami, vám VB .NET podápomocnú ruku v po<strong>do</strong>be tohto dátového typu. Textový reazec, ktorý budete chcie pri−radi <strong>do</strong> premennej dátového typu String, musí by uzatvorený <strong>do</strong> dvojitých úvodzoviek.Premenné tohto dátového typu si môete predstavi aj ako postupnos 16−bitových èíselbez z<strong>na</strong>mienka z intervalu . Kadé èíslo si ïalej môete predstavi ako sym−bol z<strong>na</strong>kovej súpravy Unicode. Na základe týchto indícií môeme <strong>na</strong>pokon dôjs k poz<strong>na</strong>−niu, e dátový typ String je sekvenciou inštancií dátového typu Char. Dátový typ Date (.NET ekvivalent: System.DateTime)Premenné dátového typu Date disponujú schopnosou uklada dátum v rozsahu od1. januára roku 1 a <strong>do</strong> 31. decembra roku 9999. Zaujímavosou je, e <strong>do</strong> premennýchtohto dátového typu môete uloi aj èas, a to od polnoci (0:00:00) a <strong>do</strong> konca celéhodòa (23:59:59). Dátový typ Object (.NET ekvivalent: System.Object)Nový dátový typ Object <strong>na</strong>hrádza vo VB .NET dátový typ Variant, ktorý poznáte z VB6. Tak ako premenné dátového typu Variant vo VB 6 i premenné nového dátového typuObject môu obsahova hodnoty ktoréhoko¾vek iného dátového typu.Formulácia, e premenné dátového typu Object môu obsahova hodnoty akéhoko¾vek dátového ty−pu, nie je z technického h¾adiska celkom presná. Objektové premenné v skutoènosti obsahujú lenodkaz, resp. ukazovate¾ <strong>na</strong> miesto, <strong>na</strong> ktorom sa <strong>na</strong>chádzajú hodnoty iných dátových typov. Z tohto dô−vodu sú premenné dátového typu Object ukladané ako 32−bitové èísla, ktoré reprezentujú adresyobjektov, <strong>na</strong> ktoré ukazujú.Starý typ Variant u nie je podporovaný, aj keï textový reazec „Variant“ je stále rezer−vovaným slovom Visual Basicu .NET.Keby ste sa náho<strong>do</strong>u zmýlili a deklarovali by ste premennú dátového typu Variant vo VB .NET, VisualBasic .NET by okamite zmenil názov zapísaného dátového typu (Variant) <strong>na</strong> názov nového ekviva−lentu (Object).POUÍVATE¼SKY DEFINOVANÉ DÁTOVÉ TYPY. Okrem toho, e môete pouimnostvo implementovaných dátových typov, vám Visual Basic .NET poskytuje monosvytvori si vlastné, pouívate¾sky definované dátové typy. Samozrejme, nepôjde o tvor−bu ekvivalentných <strong>na</strong>tívnych dátových typov, ako je <strong>na</strong>príklad Integer alebo Decimal. Po−mocou príkazu Structure si však <strong>na</strong>priek tomu môete vytvori svoj vlastný dátový typ, ato jednoduchou kombináciou u vstavaných dátových typov.Príkaz Structure vytvára štruktúru, v ktorej tele musia by deklarované èleny štruktúryso špecifikáciou dátových typov všetkých pouitých èlenov. Keby sme <strong>na</strong>príklad chcelivytvori nový dátový typ Automobil, pouijeme príkaz Structure s <strong>na</strong>sledujúcim zápisom:Structure AutomobilDim VýkonMotora As ShortDim PoèetDverí As ByteEnd StructureProgramový kód pouívate¾sky definovaného dátového typu, teda kód s príkazom Structure musí byumiestnený <strong>na</strong> úrovni modulu alebo triedy. Ak je kód pouívate¾sky definovaného dátového typu120 PC REVUE 7/2003