Základy programování Microoft | | | -+- | | +--+ +--+ | | | +----+ | | | | +-+ | | ++ ++ ++ | | | | | | | | | ++ | | | | | | | | +----+ | | | | | ++| | | | | | | | | ++ +++ ++ | | ++ | ++ ++ ++ ++ +++ ++ | | +-+ +-+ -+- + + +--+ +--+ +-+ +-+ +----+ část 0 Tak. A je to tady. Něco, bylo mnohdy považováno za nemožné, se stalo skutečností. Právě čtete první článek o programování pro Microsoft Windows, který se kdy ve Výhni objevil. Doufejme, že to nebude na škodu. Mnozí z nás nemají rádi Microsoft. K těm patří zřejmě všichni redaktoři Výhně včetně mne. Je pochopitelné, že nemáme rádi Microsoft, vždyť kdo by měl rád monopolní společnosti... Mnozí nemají rádi Windows. K těm rovněž patřím. Někteří Windows dokonce přímo nenávidí a existují i tací, kteří pro ně dokonce odmítají programovat. Takových je mezi redaktory a zřejmě i čtenáři Výhně také dost. K těm ale já nepatřím. Jednak proto, že programování pro Windows bude asi brzo nutnost, a také proto, že na některé programy se Windows i hodí. A poslední a nejdůležitější je ten, že pomocí služeb a driverů Windows se můžu dostat k takovým funkcím hardwaru, které je v DOSu často nemožné úspěšně používat. Mám na mysli zejména grafické 2D i 3D akcelerátory, s nimiž jsou v DOSu a i v lepších systémech než Windows často obrovské problémy. Tím neříkám, že ve Windows je vše bez problémů, spíše naopak, ale podpora hardwaru je asi největší výhoda, kterou tento systém nabízí. Možná nebudete souhlasit, ale spousta věcí, které jsou Windows vytýkány, neodpovídá skutečnosti... Mám na mysli například tvrzení, že Windows odeberou procesoru obrovské množství výkonu a pro program ho již mnoho nezůstane. Každý program ve Windows si ale může zavolat jednu funkci jádra a přidělit si času více, třeba i tolik, že bude téměř jediným běžícím procesem, dokonce i swapování paměti na disk ustane. Nebo tvrzení, že program v DOSu je vždy rychlejší, protože přistupuje přímo na hardware a není ničím omezován. Ale v DOSu je například 32bitový program velmi omezován tím, že používá stále 16bitové služby DOSu, díky čemuž musí pořád přepínat z protected do real mode. Třeba demo v DOSu ztrácí spoustu času také kopírováním z offscreen-bufferu do videopaměti. S grafickým akcelerátorem ve Windows to jde mnohem rychleji. Můžete namítnout, že při použití linear framebufferu se nic kopírovat nemusí, avšak velice často se po každém framu maže pozadí nebo se kresli obrázek a na něj pak nějaký efekt, a mazání a kreslení obrázku lze taky pod Windows mnohem urychlit. Jistě, i v DOSu lze použít grafické akcelerátory, ale program musí pak umět ovládat spoustu různých grafických chipů a v případě nového má prostě smůlu. Lze sice použít urychlovací služby VESA VBE, nyní ve verzi 3.0, ale implementace VBE obsahují snad ještě víc chyb než Windows, a navíc pořád většina nových BIOSů umí pouze VBE 1.2 a 3.0 se tak musí někde pirátsky shánět nebo kupovat za obrovské částky od Scitechu... Sakra, zdá se, že to vyznělo jako obrovská obhajoba Windows. Omlouvám se. Myslím, že systémy jako Linux jsou určitě lepší, škoda jen, že nepodporují tolik hardwaru jako Windows. Vážně, věřte mi, opravdu nemám Windows příliš v lásce... Zkrátka: "Nedá se nic dělat, ale asi budeme muset programovat pro Windows." Ale dost už řečí. Původně jsem se chtěl zabývat DirectX. Omlouvám se všem, kterém jsem to slíbil, ale když jsem napsal jednoduchý program používající DirectDraw, který přepnul do rozlišení 320x200x256 a krslil výbuchy jako jsou ty, které můžete vidět v intru k této Výhni a prohlížel jsem si zdroják, usoudil jsou, že pro člověka, který nezná ani základy programování Windows, je to velice nesrozumitelné. A proto jsem DirectX nechal až pro příští Výheň. Pokud se nemůžete dočkat, najdete zdroják k zmíněnému efektu a brzy i příspěvek do další Výhně na mojí stránce na WWW (adresa je na konci článku.) Ten, kdo programuje pro DirectX, sice o programování pro Windows nemusí vědět moc, ale alespoň základy znát musí. A tak vznikl tento článek. Přiložen je opravdu jednoduchý program pro Windows psaný v C, testovaný ve WATCOM C (RSXNT z DJGPP a ani GNU-WIN32 se mi zatím nepodařilo plně zprovoznit, do vydání další Výhně to ale jistě stihnu a pak budou programy testovány i v těchto kompilátorech.) Program by měl jít bez problémů zkompilovat ve většině kompilátorů Cčka pro Windows, a to v 16bitových i 32bitových. Zdrojový text je tady! Pokud se vám program nepovedlo zkompilovat, nebo nemáte čím, tak funguje takto: na obrazovce se objevi normalni okno, stejné jako spousta jiných. Uprostřed je nápis "Vyhen #8" a při změně velikosti okna stále zůstává uprostřed. Při zavření okna se prográmek zeptá, zda má opravdu okno zavřít a v případě kladné odpovědi skonči, jinak pokračuje dál. Jestli jste si zdroják prohlídli, patrně jste zjistili, že není ani příliš dlouhý, ani příliš složitý, zkrátka vypadá spíše jako program pro DOS nebo jiný systém. Není ani objektově orientovaný, to nejsou ani Windows, přestože si to mnoho lidí nesprávně myslí. Programek nepoužívá žádné pomůcky tapu ObjectWindows od Borlandu nebo MFC od Microsoftu, je to zkrátka úplně obyčejný a nic neskrývající program pro Windows. Nyní vysvetlím, jak funguje. Nebudu se zabývat podrobnostmi, jako co přesně který parametr v které funkci znamená a podobně. Budu se snažit vysvětlit to, co je opravdu důležité a hlavně to, jak program funguje (to už jsem o tři řádky víš jednou řekl, už mi to psaní nějak nejde...) Při spuštění programu se začne funkcí WinMain. Tedy ne funkcí main jako asi ve všech ostatních systémech. Její parametry jsou instance programu (to znamená zhruba kopie programu - program může být spuštěn výckrát najednou, a přitom sdílí kód a každý z těch několika stejných programů je jedna instance,) předchozí běžící instance spouštěného programu a pak parametry obsahující parametry z příkazové řádky. Potom program zaregistruje svojí Window Class, tj. jaké kurzory myši chce standardně používat, kdy se má okno znovu vykreslovat, jakou má mít ikonu a podobně. Ihned poté se pokusí o vytvoření okna a v případě neúspěchu skončí. Když se vše povede, nechá program okno nakreslit a začne smyčka zpráv. Ve smyčce zpráv program čte události (events) - zprávy které Windows posílají oknům programů. Smyčka je součástí této činnosti. Nejdříve přečte zprávu, a v případě nenulového návratového kódu funcke GetMessage napřed zavolá TranslateMessage, která něco provádí se zprávami z klávesnice, a pak zprávu pošle oknu, kterému je určena. V případě nulového návratového kóhu funkce GetMessage program pozná, že jeho okno skončilo, a ukončí se. Ještě k těm zprávám - systém Windows je řízený událostma. Událost vzniká jako reakce na činnost uživatele nebo pomocí ní systém komunikuje s aplikací, nebo si ji může každá aplikace sama vyvolat. Všechny zprávy se posílají přislušným "Procedurám Okna", které vlastně celou aplikaci řídí. Jedna taková procedura (nebo správně funkce) je WindowProc z našeho příkladu. Má čtyři parametry: hwnd = handle okna, ke kterému procedura patří message = kód zprávy (unsigned int) wParam = první parametr zprávy (word) lParam = druhý parametr zprávy (long int) Málokdy jsou využity wparam i lparam, některé zprávy dokonce nevyužívají ani jeden z nich. Procedura z našeho příkladu reaguje jenom na tři různé události, všechny ostatní přenechá funkci DefWindowProc, která na ně reaguje standardním způsobem. Různých událostí existují stovky. Jejich názvy začínají WM_ (tj. Window Message.) V praxi jich je potřeba méně, ale o dost více než jen uvedené tři. Jejich seznam je například v helu k Borland Pascalu 7 a jistě i u jiných programovacích jazyků, je rovněž v SDK k Win32 i jinde. Jak fungují a k čemu slouží uvedené tři zprávy? WM_PAINT posílají Windows vždy, když je potřeba znova nakreslit okno nebo jeho část. Aplikace si totiž nemusí pamatovat, jaký jejich pixel má jakou barvu, stačí, když se umí na požádání zobrazit. Tím, čím naše okno reaguje na WM_PAINT, se také zde nebudu příliš zabývat. Zjistí si handle k Device Contextu (DC) okna - to je způsob, jakým aplikace Windows obvykle zobrazují, co potřebují. A to pomocí GDI - graphics device interface. Ale třeba aplikace používající DirectX nemusí device contexty ani GDI vůbec používat. Vetšinu aplikací ale zobrazuje pomocí DC. A co zpráva WM_CLOSE ? Tu systém pošle vždy, když se má okno zavřít a skončit, třeba když uživatel klikne na zavření okna. Běžná reakce na WM_CLOSE je volání funkce DestroyWindow, která již opravdu začíná s "ničením" okna (narozdíl od WM_CLOSE.) Aplikace si ale napřed může ověřit, zda uživatel opravdu chce skončit nebo ne, a pak až vyvolá ničení okna. A samotřejmě WM_CLOSE si může poslat i sama aplikace, stejně jako jakoukoliv jinou zprávu pomocí funkce SendMessage. WM_DESTROY je událost vyvolaná použitím DestroyWindow. Zde okno zpravidla provede již jen jediné - vyvolá událost WM_QUIT. Ta se ani nedostane k provedení do WindowProc, protože nejdřív prochází jako většina událostí smyčkou zpráv ve funkci WinMain, a když funkce GetMessage zjistí ve frontě zpráv WM_QUIT, vrátí nulovou hodnotu a aplikace ihned úplně skončí. Jak je vidět, je ukončení programu na rozdíl od DOSu celkem věda. Některé z dalsích zpráv jsou třeba reakce na kliknutí na scrollovací lišty okna, výběr položky z menu, dále na požádání pravidelně posílané zprávy timeru, a také třeba události jako WM_ACTIVATE, která se vyvolá při přepnutí okna na oktivní okno nebo přepnutí aktivního okna na jiné okno. To je pro tentokrát vše. Jestliže jste dočetli až sem, tak děkuji za pozornost. A omlouvám se za trošku zmatené používání některých výrazů jako program, proces, aplikace nebo zpráva, událost. Snad jste pochopili co jsem tím kdy myslel. A můžete mi dát vědět, jestli se vám přiložený zdroják povedlo zkompilovat a pomocí jakých kompilátorů. Na závěr - jestlipak dokážete spočítat, kolikrát se v tomto článku vyskytuje slovo Windows? Shakul / MovSD (a.k.a. Lukáš Pokorný) email: shakul@iname.com pokornylukas@bbs.infima.cz www: http://shakul.home.ml.org mail: Lukáš Pokorný Pomněnková 545 25243 Průhonice výheň