Delphi – „Usidreni“ prozor

Verovatno ste veฤ‡ do sada imali prilike da vidite aplikacije ฤiji se prozori prosto „lepe“ za ivicu ekrana. Tipiฤan predstavnik ovakvog „ponaลกanja“ programa je poznati „WinAmp“. U ovom ฤlanku videฤ‡emo kako moลพemo da postignemo isti efekat. Naravno, u samom Windows API-ju nemamo ugraฤ‘enu moguฤ‡nost za izvoฤ‘enje ovog efekta. Zato ฤ‡emo radi postizanja cilja iskoristiti Windows poruke (messages). Delphi ฤini iskoriลกฤ‡avanje ovih poruka vrlo lakim, preko obrade dogaฤ‘aja. Obiฤno se neki dogaฤ‘aj generiลกe kao odgovor na Windows poruku, odaslatu aplikaciji. Iako veฤ‡i deo ovih poruka obraฤ‘uje sam Delphi, neke od poruka ostaju nama, da ih mi obradimo. Na primer, znamo da ako je promenjena veliฤina forme sa Resize dogaฤ‘ajem – Delphi se upravlja porukom WM_SIZE, ali kako mi moลพemo da saznamo da li se forma recimo premestila? Delphi prihvata sve odaslate poruke, ali inicijalno ne ฤini niลกta na njihovoj obradi.

Ukoliko korisnik premeลกta formu, Delphi-jevoj formi se ลกalje poruka WM_MOVING. Procesiranjem ove poruke, aplikacija moลพe „oฤitavati“ veliฤinu i poziciju forme, i ako je potrebno moลพe je premestiti, ili joj promeniti veliฤinu. Poruka WM_WINDOWPOSCHANGING se ลกalje prozoru (formi), kome su promenjeni veliฤina, pozicija ili redosled (npr. izazvani funkcijom SetWindowPos). U veฤ‡ini sluฤajeva sama poruka nije dovoljna, potrebni su nam i dodatni parametri. Na primer, WM_MOVE poruka nam govori da je formi promenjena pozicija, ali ovde nam parametar LPARAM daje X i Y koordinate. Sa porukom WM_WINDOWPOSCHANGING dobijamo samo jedan parametar – onaj koji ukazuje na WindowPos strukturu, koja sadrลพi informaciju o novoj veliฤini i poziciji forme. Evo kako izgleda WindowPos struktura:


TWindowPos = packed record
hwnd: HWND; {Identifikuje prozor.}
hwndInsertAfter: HWND; {Prozor iznad trenutnog}
x: Integer; {Levi ugao prozora}
y: Integer; {Desni ugao prozora}
cx: Integer; {Sirina prozora}
cy: Integer; {Visina prozora}
flags: UINT; {Opcije za pozicioniranje}
end;

U sledeฤ‡em primeru, videฤ‡emo kako moลพemo da postignemo da se prozor naลกe aplikacije jednostavno „prilepi“ za ivicu ekrana, kada recimo prozor privuฤemo na nekih 20 piksela do ivice ekrana. Pokrenite novi projekt i na praznu formu dodajte jednu Label kontrolu, jednu Edit kontrolu i 4 polja za potvrdu (kao na slici). Promenite nazive poljima za potvrdu u chkLevo, chkDesnoEdit kontrolu ฤ‡emo koristiti za podeลกavanje udaljenosti od ivice ekrana, na kojoj ฤ‡e se najbliลพa ivica prozora primaฤ‡i ivici ekrana. Jedina poruka koja nam treba je WM_WINDOWPOSCHANGING, ali treba nam i parametar SPI_GETWORKAREA koji ฤ‡e nam dati veliฤinu radnog prostora (desktopa). Sledi potreban Delphi kod:



private
procedure WMWINDOWPOSCHANGING
(Var Msg: TWMWINDOWPOSCHANGING);
message WM_WINDOWPOSCHANGING;

procedure TfrMain.WMWINDOWPOSCHANGING
(var Msg: TWMWINDOWPOSCHANGING);
const
Prilepljen: Boolean = FALSE;
var
rWorkArea: TRect;
Usidren : Word;
begin
Prilepi := StrToInt(Edit1.Text);

SystemParametersInfo
(SPI_GETWORKAREA, 0, @rWorkArea, 0);

with Msg.WindowPos^ do begin
if chkLevo.Checked then
if x <= rWorkArea.Left + Prilepi then begin
x := rWorkArea.Left;
Usidren := TRUE;
end;

if chkDesno.Checked then
if x + cx >= rWorkArea.Right – Prilepi then begin
x := rWorkArea.Right – cx;
Usidren := TRUE;
end;

if chkGore.Checked then
if y <= rWorkArea.Top + Prilepi then begin
y := rWorkArea.Top;
Usidren := TRUE;
end;

if chkDole.Checked then
if y + cy >= rWorkArea.Bottom – Prilepi then begin
y := rWorkArea.Bottom – cy;
Usidren := TRUE;
end;

if Usidren then begin
with rWorkArea do
begin
if x < Left then x := Left;
if x + cx > Right then x := Right – cx;
if y < Top then y := Top;
if y + cy > Bottom then y := Bottom – cy;
end;
end;
end;

inherited;
end;
end.

Pratite Krstaricu na www.krstarica.com