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ň