JudicatorMX
Gegužė 30, 2007

Laužom standartus

Šiais laikais beveik kiekvienos grafinės operacinės sistemos pagrindas (arba vienas pagrindų) – langas. Panagrinėkime langus operacinėje sistemoje.

Profesionalios programos langas yra paprastas keturkampis, kuris gali būti bet kokio aukščio ir pločio. Tokios programos vienas pagrindų – standartinė, neįmantri išvaizda, kurioje vyrauja tik kelios spalvos (dažniausiai ne daugiau kaip trys). Yra ir programų, kurios nesilaiko šių taisyklių: tai dažniausiai yra multimedia-programos, arba įvairios utility-programos. Tačiau nesilaikydamos „profesionalios programos taisyklių“, jos nei kiek nenuvertėja, net atvirkščiai: kuo labiau išvaizda traukia akį, tuo programa profesionalesnė.

Kuo gi jos skiriasi nuo kitų programų? Ogi savo spalvų gausumu, išskirtiniu dizainu, ir kas visų pirma „krenta į akį“, – nestandartinė langų forma. Galima kaip pavyzdį paimti visiems žinomą programą Winamp. Kodėl ji tokia populiari? Ne dėl savo galimybių, o dėl paprastos vartotojo sąsajos ir tuo pačiu langų formų sudėtingumo. Šios programos langų pagrindas – paveikslėliai, bet mes į juos nekreipsim dėmesio. Aš jus supažindinsiu su kitu būdu kurti „nestandartines“ programas, naudojantis Win32 API funkcijomis.

Susipažinkite su regionais. Regionas, kaip daug kas galėjo suprast, yra tam tikras plotas. Kiekvienas langas (taip pat ir kitose) sistemoje užima kažkokį regioną, t.y. plotą ekrane. Šis plotas gali būti didesnis ar mažesnis, tačiau pats langas negali išeiti už nustatyto regiono ribų. Viskas, kas yra regiono ribose, gali būti pakeista, tačiau visa kita – ne (kalbant apie tos pačios programos langą). sistemoje kiekvienas langui duotas plotas yra keturkampio formos, tačiau ne visos šio duoto ploto dalys, ne visa vieta būtinai turi būti užpildyta programos langu. Galima “nukirpti” kampą lango, tada jis jau įgys nestandartinę formą, nors duotas langui plotas ekrane nepasikeis. Dabar mes ir “karpysime” langus.

“Apkarpyti” langą galima keliais būdais, kurių kiekvienas nulemia galutinę lango formą. Kadangi mano tikslas - tik supažindinti su pačia technika, aš nevardinsiu kiekvienos funkcijos ir labai nesigilinsiu į kodą.

Visų pirma reikia susikurti kintamąjį, kurio tipas HRGN (Handle ReGioN). Kas tai per kintamasis? Jame bus duomenys apie lango formą. Kaip vyksta lango “karpymas”? Reikia nurodyti ne regioną, kurį reikia nukirpti, o tą regioną, kurį reikia palikti. Paprasčiau kalbant – reikia nustatyti kokios formos bus langas, o visa kita bus “nukirpta” automatiškai. Viskas nustatoma koordinačių pagalba. Tiems, kas nėra susidūręs su lango koordinatėmis (vargu ar tokių yra), priminsiu, kad jos prasideda viršutiniame kairiąjame kampe. X ašis nukreipta į dešinę, o Y – žemyn. Kordinačių vienetas – pikselis. Pradėkime nuo eliptiškos lango formos.

procedure TForm1.Button1Click(Sender: TObject);
var
  r: HRGN;
begin
  r:= CreateEllipticRgn(0, 0, 500, 500);
  SetWindowRgn(Form1.Handle, r, true);
end;

Funkcija CreateEllipticRgn sukuria eliptišką regioną. Jos pirmieji du parametrai – koordinatės, nuo kur turėtų prasidėti langas. Aš pradėjau viską nuo standartinės formos koordinačių pradžios taško. Sekantys du parametrai – lango plotis ir aukštis. Kadangi jie abu vienodi, tai langas bus jau ne eliptiškas, o apvalus. Funkcija SetWindowRgn nurodytam langui pritaiko nurodyto kintamojo parametrus, t.y. pakeičia lango formą (jį “apkarpo”). Paskutinis parametras visad “true”. Galite išmėginti programą, paspaudus mygtuką langas pasidarys apvalus. Galite “pažaisti” su parametrais, pažiūrėti kas nuo jų keičiasi. Atkreipkite dėmesį į tai, kad per daug padidinus parametrus ne visas langas bus matomas, kadangi jis išeis už jam duoto ploto ribų. Tokiais atvejais langą galima padidint (kaip ir kiekvieną kitą), jeigu jūsų programa tai leidžia. Tačiau dažniausiai kuriant nestandartinės formos langus, jų dydžiai negali būti keičiami. Netyčia (arba tyčia) jūs galite nukirpti lango antraštės juostą, tokiu būdu negalėsit uždaryti programos, tad geriau visada pasidarykite atskirą mygtuką, kuris tą programą uždarytų (su funkcija Close). Taip pat nukirpus antraštę – lango nebegalima “standartiniu būdu” pajudinti, tad tokiose situacijose tenka griebtis vienos gudrybės, bet jos, vėlgi, neminėsiu, kad nenukrypčiau nuo temos.

Yra ir funkcija CreateRectRgn, kuri sukuria stačiakampį regioną (parametrai tie patys, kaip ir CreateEllipticRgn funkcijoje). Bet galima panaudoti ir viduriuką tarp CreateEllipticRgn ir CreateRectRgn. Šis viduriukas vadinasi Round Rectangle, t.y. stačiakampis, suapvalintais kampais. Štai pavyzdys:

procedure TForm1.Button1Click(Sender: TObject);
var
  r: HRGN;
begin
  r:= CreateRoundRectRgn(0, 0, 500, 500, 45, 45);
  SetWindowRgn(Form1.Handle, r, true);
end;

Pirmieji keturi parametrai – tie patys, o likę du – kampai (laipsniais). Kodėl du? Matote, kiekvienas lango kampas iš tikrųjų yra dvigubas. Taigi pirmasis parametras keičia kampą X ašies atžvilgiu, o antrasis – Y. Jeigu abu parametrai vienodi, tada rezultate matome gražius suapvalintus, tolygius kampus. “Pažaiskite” su šiais parametrais, padarykite juos skirtingus, kad pamatytumėt kaip kiekvienas dirba.

Šios funkcijos yra pagrindinės, kuriant lango formą. Taip pat galima padaryti daugiakampio formos langą, tačiau tai jau yra kur kas sudėtingiau, tad neliesime šios funkcijos. Tačiau žvilgtelkite į šį kodą:

procedure TForm1.Button1Click(Sender: TObject);
var
  r1, r2: HRGN;
begin
  r1:= CreateRoundRectRgn(10, 10, 790, 500, 45, 90);
  r2:= CreateEllipticRgn(100, 100, 300, 200);
  CombineRgn(r1, r1, r2, RGN_DIFF);
  r2:= CreateEllipticRgn(700, 100, 500, 200);
  CombineRgn(r1, r1, r2, RGN_DIFF);
  SetWindowRgn(Form1.Handle, r1, true);
end;

Atsirado nauja procedūra – CombineRgn. Pirmasis parametras – regionas, kuriam bus priskirta nauja reikšmė. Antras ir trečias parametrai – regionai, kurie bus “lipdomi” režimu, nurodytu ketvirtame parametre. RGN_DIFF – skirtumas tarp regionų r1 ir r2. Ką reiškia skirtumas? Tai, kad bendros vietos nebus rodomos, t.y. mažesnis regionas bus “iškirptas” iš didesniojo. Galiausiai nauja lango forma bus įrašyta į r1 regioną (nurodytame pirmame parametre). Regionai sulipdyti, viskas įrašyta į r1, reiškia vėl galima dirbt su r2. Sukuriamas vėl naujas regionas ir sulipdomas su pirmuoju. Ką tik programos lange iškirpome akis :)

– protinga programa, kuri gali nuspaudus Ctrl ir Space parodyti visus regionų “lipdymo” būdus, tad aš jų nenagrinėsiu – tiesiog išbandykite skirtingus. Naudodamiesi vien eliptiškais regionais ir jų skritingais jungimo būdais, galite gauti gražias ir sudėtingas figūras (pvz., galite pavaizduoti drugelį). Dėja, dabar neturiu galimybės parodyt pavyzdžių, tad viskas pasilieka jūsų kūrybai. Mėgaukitės.

Panašūs straipsniai


“Laužom standartus” komentarų: 4

  1. Invisible

    Kas yra grafinė operacinė sistema?

  2. JudicatorMX

    Kalbu apie operacine sistema, kurioje yra grafine aplinka, o ne tiesiog juodas ekranas ir tekstas.

  3. Invisible

    Tai tu kalbi apie grafinę aplinką o ne operacinę sistemą.

  4. asterisk

    teisingiausiai būtų išsireikšti - operacinė sistema su grafine aplinka :) Bet tai tik paprasta lietuvybės klaida ;)

Rašyti komentarą

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