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ň