Kai kalba eina apie Borland programavimo terpę, dauguma atsimena labai patogią programą, kurioje per kelias minutes galima sukurti paprastą tektinį tekstinį redaktorių, muzikinį grotuvą ir pan.
labai greitai pakeitė programą Turbo (nors ji dar tebėra viena pagrindinių mokymo priemonių įvairiose mokymo įstaigose). Nuo trečiosios versijos pradėjo labai keistis į gerąją pusę ir dabar jau galime įsigyti aštuntąją versiją (kurios dauguma kol kas nepripažįsta). Teoriškai naujoji versija reiškia daugiau galimybių, daugiau patogumų, mažiau klaidų ir pan., tačiau taip yra tik teoriškai. Su naujom versijom vis rimtėja ir du pagrindiniai programavimo su ja minusai: greitis ir dydis. Deja, su pagalba rašomos programos labai atsilieka savo greičiu ir dydžiu, lyginant su C++ programomis ir ilgainiui “rimti” programuotojai tai pradeda gerai pastebėt. Tačiau yra viena išeitis.

bėda ta, kad į kuriamas programas „prikiša“ daug nereikalingo kodo. Pripažinkime, juk didžiąja dalimi formos savybių mes net nesinaudojam! Tačiau jos yra ir jų atsikratyti neina. Taip pat visi komponentai turi savo modulius, kurie nemažai „sveria“. Kiekvienas prijungtas modulis prideda prie kuriamos programos papildomus kilobaitus „svorio“. Kai kurie moduliai – po šimtą ir daugiau! Visi dažnai naudojasi standartiniu mygtuku „TButton”, tačiau jo modulyje aprašyti net keli skirtingi mygtukai, kurie programoje nenaudojami ir visai nereikalingi. Taigi jau paprastos programos, kurios susidaro tik iš savo lango, užima kompiuterio diske nuo ~0,5 iki ~1Mb vietos ir veikia gan lėtai (ypač jei naudojamas permatomumas).
Kaip išspręsti šią problemą? Reikia visad stengtis programos kode valyti „šiukšles“, t.y. nenaudoti jokių papildomų, nereikalingų modulių. Daugiausia vietos programai prideda „SysUtils“ ir „Dialogs“ moduliai. Norint atsikratyt kai kuriais moduliais, galima tiesiog į savo programą nusikopijuoti jame esantį naudojamos funkcijos aprašą. Tačiau tai ne visada labai padeda. Ką tokiu atveju daryti? Naudoti konsolines programas? Nešiuolaikiška… Iš naujo išradinėti dviratį? Būtent!
Konsolinių programų beveik niekas nebevartoja, tačiau ir Windows programos gali būti tokios pat greitos ir užimti labai mažai vietos, dėl to reikia viską kurti iš pradžių. Prie to labai dažnai grįžta programuotojai. Čia naudojamos jau ne standartinės Object funkcijos, o . Paprastas programos langas kurtas vizualinės aplinkos pagalba užima apie 500Kb, o pagalba – 20Kb.
programavimas – ne kiekvienam, kadangi reikalauja nemažai žinių ir darbo. Aš jus šiek tiek supažindinsiu su ir sukursiu paprastą langą.
programos (taip jas vadinsiu, nors tai nėra geras variantas) naudoja pagrinde du modulius – Windows ir Messages. Windows modulio pagalba bus kuriamas langas, o Messages pagalba bus “gaudomos” operacinės sistemos žinutės. Taigi jungiame File->New->Other ir renkamies Console Application. Beliko viską ištrint ir pradėt savo kodą.
Kiekvienoje programoje turi būti lango procedūra. Lango procedūra – tai funkcija, kurioje vykdomos programos reakcijos į įvairias jai siunčiamas žinutes. Funkcijos grąžinamas tipas yra LResult. Ši funkcija privalo turėti keturis parametrus, o atrodo viskas taip:

function WndProc(wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): lResult;
begin
 
end;

Pirmasis parametras – rodyklė į langą. Jis labai svarbus, kadangi programa gali turėti kelis langus. Antrasis parametras – žinutė, t.y. kintamasis, kuris laiko žinutę vėliau perduodamą pačiai programai, kad ta galėtų sureaguoti į ją. Trečias ir ketvirtas parametrai priklauso nuo žinutės. Visos žinutės prasideda priešdėliu „WM“ (Windows Message), ir dabar kaip tik vieną pridėsim.

function WndProc( wnd: HWND; Msg: UINT;
                 wParam: WPARAM; lParam: LPARAM ): lResult; stdcall;
begin
 if Msg = WM_DESTROY 
  then
   begin
    PostQuitMessage( 0 ); 
    Result:= 0; 
   end
  else 
    Result:= DefWindowProc(wnd, Msg, wParam, lParam);
end;

Žinutė vadinasi WM_DESTROY ir yra naudojama, kai programą reikia „sunaikinti“ (kitaip tariant, uždaryti). Kaip veikia ši visa funkcija? Ji gauna rodyklę į langą, su kuria reikia atlikti veiksmus, ir žinutę, į kurią reikia sureaguot. Jei ši žinutė bus WM_DESTROY, tada mes sėkmingai uždarysime programą PostQuitMessage pagalba. Kadangi įvairių žinučių yra šimtai, likusių mes nenagrinėsime ir programa į jas reaguos default būdu. Tam tereikia iškviesti DefWindowsProc funkciją (Default Window Procedure), kuri į likusias žinutes reaguoja pagal nutylėjimą.
programos kūrimas susideda iš šių keturių dalių:

  • 1. Lango savybių nustatymas
  • 2. Lango kūrimas
  • 3. Lango registravimas operacinėje sistemoje
  • 4. Lango rodymas ekrane

Programa turi daug savybių, tokių kaip lango stilius, ikona, lango spalva, kursorius ir t.t. Visa tai aprašoma programos klasėje, kuriai sukūriau kintamąjį Wc (ne nuo „WC“, o nuo „Window Class“ ;). Nurodžius visas savybes, programą reikia užregistruoti operacinėje sistemoje RegisterClassEx pagalba. Klasė nurodo pagrindines programos savybes, bet šiai programai langas kuriamas atskirai CreateWindowEx pagalba, taip pat nurodant lango savybes (dydis, antraštė ir pan). Sukūrus langą, jį reikia parodyti ekrane ShowWindow pagalba ir kaskart atnaujinti UpdateWindow pagalba. Atnaujinimas reikalingas, kad langas būtų perpiešiamas, keičiant jo dydį ir pan. Tada jau prasideda ciklas, kuriame yra gaudomos ir perduodamos žinutės. Pačioje pabaigoje – išėjimas iš programos.
Tai programos kūrimo principai. Į patį kodavimą nesileisiu, tad štai visas kodas.

uses
  Windows, // Darbui su langu
  Messages; // Darbui su žinutėmis
 
const WndClass = 'WndApi'; // Programos klasės pavadinimas
      WndCaption = 'Sveiki!'; // Lango antraštė
 
var
  Wc: TWndClassEx; // Kintamasis klasės apibūdinimui
  Wnd: HWND; // Rodyklė į langą
  Msg: TMsg; // Čia bus laikomos žinutės
function WndProc( wnd: HWND; Msg: UINT;
                 wParam: WPARAM; lParam: LPARAM ): lResult; stdcall;
begin
 if Msg = WM_DESTROY
  then
   begin
    PostQuitMessage( 0 ); // Programos uždarymas
    Result:= 0;
   end
  else
    Result:= DefWindowProc(wnd, Msg, wParam, lParam);
end;
 
begin
 with Wc do
  begin
   Style:= CS_VREDRAW or CS_HREDRAW; // Lango stilius
   hIcon:= LoadIcon( 0, IDI_APPLICATION ); // Programos ikona
   hIconSm:= LoadIcon( 0, IDI_APPLICATION ); // Mažoji ikona (esanti antraštėje)
   hCursor:= LoadCursor( 0, IDC_ARROW ); // Kursorius
   hInstance:= hInstance; // Programos pavyzdys
   cbSize:= SizeOf( WndClassEx ); // Struktūros dydis
   cbClsExtra:= 0; // Papildoma atmintis, naudojama Windows
   cbWndExtra:= 0; // Papildoma atmintis, naudojama Windows
   hbrBackground:= HBRUSH( COLOR_BACKGROUND ); // Fonas
   lpszMenuName:= nil; // Meniu pavadinimas (dabar meniu nėra)
   lpszClassName:= WndClass; // Klasės pavadinimas
   lpfnWndProc:= @WndProc; // Rodyklė į lango procedūrą
  end;
 
 RegisterClassEx( Wc ); // Klasės registravimas
 
 Wnd:= CreateWindowEx( 0, WndClass,
                      WndCaption, WS_OVERLAPPEDWINDOW,
                      10, 10, // Lango pozicija
                      640, 480, // Lango dydis
                      0, 0,
                      hInstance, nil );
 
 ShowWindow( Wnd, CmdShow ); // Rodome langą
 UpdateWindow( Wnd ); // Atnaujinam langą
 
 // Darbo su žinutėmis ciklas
 While GetMessage( Msg, 0, 0, 0 )
  do
   begin
    TranslateMessage( Msg );
    DispatchMessage( Msg );
   end;
 
 Halt( Msg.wParam ); // Išėjimas
end.

Programa tikrai veikianti ir diske užima 15Kb.

Panašūs straipsniai


“Back to Basics (WinAPI programavimas)” komentarų: 5

  1. BSS

    uoj vargas su tuom winapi. kai buvo dalykas univere po keletos pirmu paskaitu supratau,kad bergzdzias su tuom reikalas,nes reikia skirt begale laiko ir pastangu

  2. JudicatorMX

    Taciau dazniausiai visa tai pasiteisina, kadangi taip igyjama visiska programos kontrole.

  3. Evaldas

    visiška programos kontrolė - ir vėžliška programos kūrimo eiga.. :)

  4. nesakysiu

    Nors ir vėlokai rašau, bet gal kas dar pamatys šį kometarą :)

    Kaip šį reikalą pritaikyti prktiškai, ta prasme, kaip toliau delphi’je programuoti turint šį šabloną? Tarkim, kaip kūriami mygtukai, koks formos pavadinimas ? Ar čia jau skaitosi nebe delphi o WinApi?

  5. Algerdas

    tik nereikia lialia apie stulbinanti c++ pranasuma pries delphi. pats ilga laika programinau assembler/pascal/delphi ir kazkiek bovinaus po c/c++ tai kodo ilgis tose pat salygose yra +/- 20-30% (neretai i pascal nauda), o greiciu tikrai neatsilieka 20 kartu. aisku jei lygint su iline/macros tai c/c++ laimi, bet ne kodo ilgiu. o jei lygint assembler ir c/c++ tai cia assembler is vis tada dievas.
    P.S. teisingiausia butu sakyt: tie, kas nepatyre programavimo ZX Spectrum/Micro 80/IBM PC x88 tai nesugeba rasyt greito ir kokybisko kodo/formu po delphi/c++builder/m$ visualc/visual basic ir t.t.

Rašyti komentarą

Jūs privalote prisijungti jeigu norite rašyti komentarą.