Prenos vízií do reality bolí. - Vitajte na stránkach www.einsty ...

Prenos vízií do reality bolí. - Vitajte na stránkach www.einsty ... Prenos vízií do reality bolí. - Vitajte na stránkach www.einsty ...

einsty.hostujem.sk
from einsty.hostujem.sk More from this publisher
11.07.2015 Views

P R O G R A M U J E M Esia¾ nepotreboval anepouíval. Prob−lém sme vyriešiliObr. 2spoloène pomocoujednej rutiny z inter−netu. Jej funkèný výòatok vám trochu opíšem. Èinné sú dve funkcie: GetMenuItemInfo aSetMenuItemInfo. Pouitím prvej sme dokázali naplni prázdnu premennú Item typuTMenuItemInfo, ktorej fType parameter nadobudol hodnotu MFT_RIGHTJUSTIFY. Druháfunkcia nastavila komponent MainMenu1, respektíve jeho poloku Help1 tak, e po vy−kreslení príkazom DrawMenuBar bude zobrazovaná v pravom rohu.procedure TForm1.FormCreate(Sender: TObject);Var Item:TMenuItemInfo;Buff:Array[0..100] of char;beginZeroMemory(@Item, SizeOf(Item));Item.cbSize:=44;Item.fMask:=MIIM_TYPE;Item.dwTypeData:=Buff;Item.cch:=SizeOf(Buff);if GetMenuItemInfo(MainMenu1.Handle, Help1.MenuIndex, True, Item) then BeginItem.fType:=Item.fType or MFT_RIGHTJUSTIFY;if SetMenuItemInfo(MainMenu1.Handle, Help1.MenuIndex, True, Item) thenDrawMenuBar(MainMenu1.WindowHandle);end;end;Upozoròujem, e uvedený zdrojový kód presunie len tú poloku menu, ktorá je nosi−te¾om názvu Help1. Preto v prípade, ak chcete presunú akúko¾vek inú poloku, môetetak urobi, ale a po zmene druhého parametra funkcií GetMenuItemInfo a SetMenu−ItemInfo. Takisto sa predpokladá, e menu bude pomenované MainMenu1.DYNAMICKÉ PRIDANIE POLOKY DO MENU. Aj keï tento problém v minu−losti rozoberal kolega z Delfinária, opíšeme si ho len v rozsahu potrebnom na pochope−nie. Dynamické pridanie poloky do menu by nebolo pre nikoho problémom, keby taktovytvorená poloka mohla podlieha udalosti. Takto znel problém. Jeho riešenie je celkomjednoduché. Vytvorili sme si procedúru, ktorú musíme zadefinova do bloku public. Naobsluhu udalosti vyuijeme vlastnos OnClick premennej NewItem. Obsluha je totoná spolokami Items kadého druhu, take pridanie nie je nièím výnimoèné ani nièím nové....public{ Public declarations }procedure AddItem(text:String);end;...procedure TForm1.AddItem(text:String);var NewItem:TMenuItem;beginNewItem:=TMenuItem.Create(MainMenu1);NewItem.Caption:=text;// NewItem.OnClick vyuijeme na obsluhu udalostiMainMenu1.Items.Insert(MainMenu1.Items.Count, NewItem);end;end;inheritedend;procedure TForm1.FormCreate(Sender: TObject);beginSysMenu:=GetSystemMenu(Form1.Handle, False);AppendMenu(SysMenu, MF_SEPARATOR, 0, '');AppendMenu(SysMenu, MF_STRING, idSys, '&info');end;Posledným, ale aj najfunkènejším krokom je pridanie poloky do menu, ktoré vykoná−vame príkazom AppendMenu. Ten potrebuje príslušné nasmerovanie, ktoré mu dávaGetSystemMenu (odkazuje ho na handle pre Form1). Mono ste si všimli parameter MF_SEPARATOR. Ten vytvára odde¾ovací pruh. Take je len estetickým doplnkom alebo dopln−kom preh¾adnosti. Na priloenom obrázku vidíme uspokojivý výsledok.NIE JE ENTER AKO ENTER. Na klávesnici máme dva klávesy s rovnakým oznaèe−ním (enter). Zrejme len málokomu by napadlo, e môu by programom rozlišovanéako úplne odlišné klávesy. Kto by bol povedal, e enter nie je poèítaèom chápaný akojediný? Ani nie tak poèítaèom, ale presnejšie softvérovou výbavou, ktorú zhodou náhodtvoríme práve my programátori. Take opä ostáva na nás programátoroch, aby sme siaj s týmto nejako poradili. Budeme vyuíva Windows Message (WM). Vytvoríme si pro−cedúru, ktorú musíme definova v bloku private. Jej telo bude prijíma správy a v prí−pade, ak stlaèený kláves bude zodpoveda klávesu enter, vtedy poloíme podmienku,ktorá rozozná, èi bol enter stlaèený na numerickej èasti klávesnice, alebo nie. Na de−monštráciu opä pouívam ob¾úbený príkaz ShowMessage, ale verím, e všetci vidíte ajiné vyuitie.procedure TForm1.WMKeyDown(var message:TWMKeyDown);begininherited;with message doif CharCode=VK_RETURN thenif KeyData and (1 shl 24)=0 then ShowMessage('Enter') elseShowMessage('Num Enter');end;To bol posledný problém, ktorý sme si v tejto èasti rozobrali. Nabudúce budeme po−kraèova v otázkach a odpovediach, take nezúfajte, pekne si uívajte a neprehrejte sa(ani procesory ☺). Teším sa na ïalšie stretnutie s vami, o mesiac dovidenia.Jozef KOZÁK ml.OBOHATENIE SYSTÉMOVÉHO MENU.Kadý program vytvorený v akomko¾vek objek−tovom programovacom jazyku získa vlastnosti,ktoré sú neovplyvnite¾né, teda sú produktomoperaèného systému. K nim bezpochyby patrísystémové menu, ktoré je dané typom a verziouOS. Operaèný systém Windows má v systémo−vom menu nieko¾ko poloiek: presunú, upravive¾kos, minimalizova, maximalizova, zavrie.Tieto poloky sú nemenné a navonok je totoObr. 3menu statické, ešte raz pripomínam – dané sys−témom. Sèasti je to pravda, ale po pouití nasledujúcej rutiny si ho môeme jemne pri−spôsobi, respektíve prida nejakú poloku. Prv ne zaèneme, musíme si zadefinova kon−štantu. A aj dopísa procedúru do bloku public.constidSys=10;varSysMenu:HMenu;public{ Public declarations }procedure WMSysCommand(var Message:TMessage); message wm_SysCommand;end;...Procedúra spadajúca pod TForm1 len kontroluje, èi bola splnená podmienka (kliknutiena poloku). Ak áno, môeme dotvori udalos, ktorá sa má vykona po kliknutí na dodat−kovú poloku v systémovom menu.Procedure TForm1.WMSysCommand(var Message:TMessage);beginif Message.WParam=idSys then begin// volanie èinnej funkcie alebo procedúry7/2003 PC REVUE 115

P R O G R A M U J E M EDirect Animation6. èas: Nereaktívne objektyDoteraz pri práci s DirectAnimation sme vytvárali objekty rôznych tried, ktoré predstavo−vali 2D grafiku, transformáciu polohy èi tvaru objektu, farbu a pod. Tieto objekty, tzv.objekty správania sa (behaviors), boli buï konštantné, alebo premenlivé v èase. Ak si tedapredstavíme napr. objekt triedy DATransform2, ktorý pre nás uchovával hodnotu o polo−he iného zobrazovaného objektu triedy DAImage, potom tento zobrazovaný objekt bolpo celý èas behu animácie na jednom mieste alebo sa pohyboval urèitou rýchlosou vzávislosti od toho, èi spomínaný objekt transformácie bol konštantný (constant behavior)alebo premenlivý v èase (time−varying behavior). Pozrime sa na nasledujúce dva zápisy. Vprvom je objekt triedy DAImage konštantný, v druhom sa mení – otáèa urèitou rýchlosou(hodnota argumentu násobená hodnotou LocalTime).image1 = image1.Transform(lib.Rotate2Degrees(10));// objekt konštantný;image1 = image1.Transform(lib.Rotate2RateDegrees(10));// objekt premenlivý v èase;V oboch prípadoch však ide o tzv. nereaktívne objekty (non−reactive behaviors),ktoré nereagujú na iadne vyvolávané udalosti (events). Vyvolanou udalosou rozumie−me napr. stlaèenie konkrétneho tlaèidla klávesnice alebo tlaèidla myši, uplynutie neja−kého èasového intervalu a pod. Druhou skupinou sú reaktívne objekty (reactive beha−viors), ktoré, naopak, na vyvolané udalosti reagujú. Vytváranie práve takýchto reaktív−nych objektov a k nim príslušných udalostí pridáva našej animácii prvky interaktivity.Jedným z objektov povaovaných za èasovo závislé je aj objekt známej triedyDAPoint2, ktorý vracia jedna z relevantných vlastností k tejto triede, a to vlastnoslib.MousePosition. Vrátený objekt predstavuje aktuálnu polohu ukazovate¾a myši. Keïtúto hodnotu pouijeme ako parameter pre transformáciu, ktorú následne aplikujemena ¾ubovo¾ný zobrazovaný 2D objekt, dosiahneme, e tento objekt bude kopírovapolohu ukazovate¾a myši. Tento objekt teda bude ma prvky interaktivity, aj keï nie jepovaovaný za reaktívny. Takúto transformáciu vytvoríme napr. nasledujúcim zápisom:image1 = image1.Transform(lib.Translate2Point(lib.MousePosition));REAKTÍVNE OBJEKTY. Ako sme u uviedli, reaktívne objekty ako protiklad k nere−aktívnym sa menia v závislosti od vyvolávaných udalostí a predstavujú pre nás základ−ný prvok pri tvorbe interaktívnych animácií. Vyvolávanú udalos v prostredí Direct−Animation predstavuje objekt triedy DAEvent. Skôr ne zaèneme vytvára reaktívneobjekty reagujúce na konkrétnu vyvolanú udalos, musíme vedie, ako túto udaloszadefinova. Preto sa najprv blišie pozrieme na triedu DAEvent. Pre zaèiatok si všakpredstavíme len funkcie z triedy DAStatics relevantné k triede DAEvent, ktoré námumonia objekty triedy DAEvent vytvára. K ostatným funkciám, teda k funkciám z trie−dy DAEvent, sa vrátime a nakoniec, keï sa oboznámime s jednotlivými druhmi vyvo−lávaných udalostí a ich obsluhou.TRIEDA DAEVENT – FUNKCIE A VLASTNOSTI RELEVANTNÉ K TRIEDEDAEVENT. Vytvorením objektu triedy DAEvent definujeme udalos, ktorá predstavujeurèitý stav, prípadne urèitú akciu od pouívate¾a. Táto udalos potom hovorí, kedy mádôjs k zmene alebo reakcii. Urèite k najèastejšie vyvolávaným udalostiam patrí udalosvyvolaná kliknutím na ¾avé alebo pravé tlaèidlo myši. Takéto udalosti, resp objekty trie−dy DAEvent vytvoríme pomocou týchto relevantných vlastností z triedy DAStatics:lib.LeftButtonDown,lib.RightButtonDown.Ide o read−only vlastnosti predstavujúce udalosti, ku ktorým dôjde v momente stlaèe−nia ¾avého, resp. pravého tlaèidla myši.Vo všeobecnosti kadá udalos (objekt triedy DAEvent), ku ktorej dôjde, vracia urèitédáta. Tieto dáta pre nás môu, ale nemusia ma nejaký význam. Napríklad objekt triedyDAEvent vrátený vlastnosami lib.LeftButtonDown a lib.RightButtonDown neobsahuje ni−jaké pre nás uitoèné údaje. Je len nosite¾om informácií o zmene stavu, v tomto prípadestlaèení jedného z tlaèidiel myši. Naproti tomu iné objekty triedy DAEvent vrátené niektorý−mi inými funkciami, ako napr. lib.AndEvent(ev1, ev2,), obsahujú ïalšie potrebné údaje.Ïalšie vlastnostilib.LeftButtonUp,lib.RightButtonUppredstavujú udalosti, ktoré sú vyvolané v momente uvo¾nenia stlaèených tlaèidiel myši.Jednotlivé prvky animácie ïalej môu reagova aj na stlaèenie klávesu. Funkcielib.KeyDown(KeyCode),lib.KeyUp(KeyCode)vracajú objekt triedy DAEvent, ktorý nastane v momente stlaèenia, resp. uvo¾nenia kláve−su definovaného parametrom KeyCode. Parameter KeyCode je èíselná premenná typulong. Identifikátory klávesov sú odvodené od tzv. scan code, pouívaných funkciamiWin32 API.Hexadecimálne hodnoty parametra KeyCode pre jednotlivé špeciálne klávesy sú vede−né v nasledujúcej tabu¾ke.Tab. è. 1 Hexadecimálne hodnoty parametra KeyCode pre špeciálne klávesykláves keycode kláves keycode kláves keycode kláves keycodePGUP 10021 NUMPAD2 10062 SEPARATOR 1006C F7 10076PGDN 10022 NUMPAD3 10063 SUBTRACT 1006D F8 10077END 10023 NUMPAD4 10064 DECIMAL 1006E F9 10078HOME 10024 NUMPAD5 10065 DIVIDE 1006F F10 10079LEFT 10025 NUMPAD6 10066 F1 10070 F11 1007AUP 10026 NUMPAD7 10067 F2 10071 F12 1007BRIGHT 10027 NUMPAD8 10068 F3 10072 INSERT 1002DDOWN 10028 NUMPAD9 10069 F4 10073 DELETE 1002ENUMPAD0 10060 MULTIPLY 1006A F5 10074NUMPAD1 10061 ADD 1006B F6 10075Udalos vyvolanú napr. stlaèením klávesu PGUP vytvoríme týmto zápisom:keyEvent = lib.KeyDown(0x10021);Pre ostatné klávesy môete poui aj ich ANSI hodnotu. Napríklad znakom a – z zod−povedá decimálna ANSI hodnota 97 – 122.Potom udalos vyvolanú napr. stlaèením klávesu a vytvoríme týmto zápisom:keyEvent = lib.KeyDown(97);Všetky hodnoty Win32 Scan codes, ako aj hodnoty ANSI nájdete napr. na www.msdn.comv èasti Library pod k¾úèovým slovom „scan code“.Úplne inou kategóriou sú udalosti vyvolané po uplynutí stanoveného èasu od spuste−nia animácie. Práve tie budeme èasto vyuíva, aby sme dosiahli urèitú èasovú následnosjednotlivých prvkov animácie. Funkcielib.TimerAnim(timeout),lib.Timer(timeout)vracajú objekt triedy DAEvent, ktorý je spustený po uplynutí èasu stanoveného paramet−rom timeout. Ako zvyèajne v anim variante funkcie je parameter animované èíslo typuDANumber.Pomocou tejto funkcie teda môeme naèasova spustenie konkrétnych animovanýchsekvencií. Pre riadenie a spúšanie jednotlivých sekvencií tie môeme poui ïalšiu za−ujímavú a urèite uitoènú funkciu, a to:lib.ThenEvent(e1, e2).Funkcia vracia objekt triedy DAEvent èie udalos (totonú s udalosou e2), ktorá jevyvolaná, len èo dôjde k vyvolaniu udalosti e1.Posledná skupina funkcií definuje udalosti vyvolávané na základe zmeny stavov výro−kov (predicate) alebo inak tzv. booleovských premenných (v DirectAnimation ide o objek−ty triedy DABoolean) vracajúcich hodnotu True alebo False. Patria sem aj funkcie definu−júce udalosti vyvolávané na základe výsledku základných logických operácií (AND, OR,NOT) nad udalosami. Funkcialib.Predicate(bool)vracia objekt triedy DAEvent, ktorý je vyvolaný v momente zmeny parametra bool (objekttriedy DABoolean) z hodnoty False na hodnotu True.Funkcielib.AndEvent(first, second),lib.OrEvent(first, second),lib.NotEvent(event),definujú udalosti vyvolávané na základe výsledku základných logických operácií (AND, OR, NOT)nad udalosami. Funkcia logického súèinu (AndEvent) definuje udalos, ktorá nastane práve vmomente, keï dôjde k vyvolaniu oboch udalostí first a second súèasne. Funkcia logického súètu(OrEvent) definuje udalos, ktorá nastane práve v momente, keï dôjde k vyvolaniu aspoò jed−nej z udalostí first a second. Nakoniec funkcia negácie (NotEvent) definuje udalos, ktorá jevyvolaná, práve keï udalos event je neaktívna, resp. pokia¾ nedošlo k jej vyvolaniu.Nakoniec ešte dve vlastnosti z funkcie DAStatics, a to:lib.Never,lib.Always.116 PC REVUE 7/2003

P R O G R A M U J E M Esia¾ nepotreboval anepouíval. Prob−lém sme vyriešiliObr. 2spoloène pomocoujednej rutiny z inter−netu. Jej funkèný výòatok vám trochu opíšem. Èinné sú dve funkcie: GetMenuItemInfo aSetMenuItemInfo. Pouitím prvej sme <strong>do</strong>kázali <strong>na</strong>plni prázdnu premennú Item typuTMenuItemInfo, ktorej fType parameter <strong>na</strong><strong>do</strong>bu<strong>do</strong>l hodnotu MFT_RIGHTJUSTIFY. Druháfunkcia <strong>na</strong>stavila komponent MainMenu1, respektíve jeho poloku Help1 tak, e po vy−kreslení príkazom DrawMenuBar bude zobrazovaná v pravom rohu.procedure TForm1.FormCreate(Sender: TObject);Var Item:TMenuItemInfo;Buff:Array[0..100] of char;beginZeroMemory(@Item, SizeOf(Item));Item.cbSize:=44;Item.fMask:=MIIM_TYPE;Item.dwTypeData:=Buff;Item.cch:=SizeOf(Buff);if GetMenuItemInfo(MainMenu1.Handle, Help1.MenuIndex, True, Item) then BeginItem.fType:=Item.fType or MFT_RIGHTJUSTIFY;if SetMenuItemInfo(MainMenu1.Handle, Help1.MenuIndex, True, Item) thenDrawMenuBar(MainMenu1.Win<strong>do</strong>wHandle);end;end;Upozoròujem, e uvedený zdrojový kód presunie len tú poloku menu, ktorá je nosi−te¾om názvu Help1. Preto v prípade, ak chcete presunú akúko¾vek inú poloku, môetetak urobi, ale a po zmene druhého parametra funkcií GetMenuItemInfo a SetMenu−ItemInfo. Takisto sa predpokladá, e menu bude pomenované MainMenu1.DYNAMICKÉ PRIDANIE POLOKY DO MENU. Aj keï tento problém v minu−losti rozoberal kolega z Delfinária, opíšeme si ho len v rozsahu potrebnom <strong>na</strong> pochope−nie. Dy<strong>na</strong>mické pridanie poloky <strong>do</strong> menu by nebolo pre nikoho problémom, keby taktovytvorená poloka mohla podlieha udalosti. Takto znel problém. Jeho riešenie je celkomjednoduché. Vytvorili sme si procedúru, ktorú musíme zadefinova <strong>do</strong> bloku public. Naobsluhu udalosti vyuijeme vlastnos OnClick premennej NewItem. Obsluha je totoná spolokami Items kadého druhu, take pridanie nie je nièím výnimoèné ani nièím nové....public{ Public declarations }procedure AddItem(text:String);end;...procedure TForm1.AddItem(text:String);var NewItem:TMenuItem;beginNewItem:=TMenuItem.Create(MainMenu1);NewItem.Caption:=text;// NewItem.OnClick vyuijeme <strong>na</strong> obsluhu udalostiMainMenu1.Items.Insert(MainMenu1.Items.Count, NewItem);end;end;inheritedend;procedure TForm1.FormCreate(Sender: TObject);beginSysMenu:=GetSystemMenu(Form1.Handle, False);AppendMenu(SysMenu, MF_SEPARATOR, 0, '');AppendMenu(SysMenu, MF_STRING, idSys, '&info');end;Posledným, ale aj <strong>na</strong>jfunkènejším krokom je pridanie poloky <strong>do</strong> menu, ktoré vykoná−vame príkazom AppendMenu. Ten potrebuje príslušné <strong>na</strong>smerovanie, ktoré mu dávaGetSystemMenu (odkazuje ho <strong>na</strong> handle pre Form1). Mono ste si všimli parameter MF_SEPARATOR. Ten vytvára odde¾ovací pruh. Take je len estetickým <strong>do</strong>plnkom alebo <strong>do</strong>pln−kom preh¾adnosti. Na priloenom obrázku vidíme uspokojivý výsle<strong>do</strong>k.NIE JE ENTER AKO ENTER. Na klávesnici máme dva klávesy s rov<strong>na</strong>kým oz<strong>na</strong>èe−ním (enter). Zrejme len málokomu by <strong>na</strong>padlo, e môu by programom rozlišovanéako úplne odlišné klávesy. Kto by bol povedal, e enter nie je poèítaèom chápaný akojediný? Ani nie tak poèítaèom, ale presnejšie softvérovou výbavou, ktorú zho<strong>do</strong>u náhodtvoríme práve my programátori. Take opä ostáva <strong>na</strong> nás programátoroch, aby sme siaj s týmto nejako poradili. Budeme vyuíva Win<strong>do</strong>ws Message (WM). Vytvoríme si pro−cedúru, ktorú musíme definova v bloku private. Jej telo bude prijíma správy a v prí−pade, ak stlaèený kláves bude zodpoveda klávesu enter, vtedy poloíme podmienku,ktorá rozozná, èi bol enter stlaèený <strong>na</strong> numerickej èasti klávesnice, alebo nie. Na de−monštráciu opä pouívam ob¾úbený príkaz ShowMessage, ale verím, e všetci vidíte ajiné vyuitie.procedure TForm1.WMKeyDown(var message:TWMKeyDown);begininherited;with message <strong>do</strong>if CharCode=VK_RETURN thenif KeyData and (1 shl 24)=0 then ShowMessage('Enter') elseShowMessage('Num Enter');end;To bol posledný problém, ktorý sme si v tejto èasti rozobrali. Nabudúce budeme po−kraèova v otázkach a odpovediach, take nezúfajte, pekne si uívajte a neprehrejte sa(ani procesory ☺). Teším sa <strong>na</strong> ïalšie stretnutie s vami, o mesiac <strong>do</strong>videnia.Jozef KOZÁK ml.OBOHATENIE SYSTÉMOVÉHO MENU.Kadý program vytvorený v akomko¾vek objek−tovom programovacom jazyku získa vlastnosti,ktoré sú neovplyvnite¾né, teda sú produktomoperaèného systému. K nim bezpochyby patrísystémové menu, ktoré je dané typom a verziouOS. Operaèný systém Win<strong>do</strong>ws má v systémo−vom menu nieko¾ko poloiek: presunú, upravive¾kos, minimalizova, maximalizova, zavrie.Tieto poloky sú nemenné a <strong>na</strong>vonok je totoObr. 3menu statické, ešte raz pripomí<strong>na</strong>m – dané sys−témom. Sèasti je to pravda, ale po pouití <strong>na</strong>sledujúcej rutiny si ho môeme jemne pri−spôsobi, respektíve prida nejakú poloku. Prv ne zaèneme, musíme si zadefinova kon−štantu. A aj <strong>do</strong>písa procedúru <strong>do</strong> bloku public.constidSys=10;varSysMenu:HMenu;public{ Public declarations }procedure WMSysCommand(var Message:TMessage); message wm_SysCommand;end;...Procedúra spadajúca pod TForm1 len kontroluje, èi bola splnená podmienka (kliknutie<strong>na</strong> poloku). Ak áno, môeme <strong>do</strong>tvori udalos, ktorá sa má vyko<strong>na</strong> po kliknutí <strong>na</strong> <strong>do</strong>dat−kovú poloku v systémovom menu.Procedure TForm1.WMSysCommand(var Message:TMessage);beginif Message.WParam=idSys then begin// volanie èinnej funkcie alebo procedúry7/2003 PC REVUE 115

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!