Okno jak w Winampie

Adam Boduch

Ostatnio dostałem ze dwa e-maile, którego autorzy prosili mnie o rozwiązanie następującego problemu. Chcieli oni bowiem zrobić coś takiego jak jest w Winampie, czyli podczas przesuwania okna jeżeli jest ono blisko "przykleić" je do krawędzi drugiego okna.

Ja w swoim przykładzie nie zastosowałem drugiego okna, a jedynie krawędz obrazu. Jeżeli Ty chcesz to zrobić z oknem musisz zdobyć do niego uchwyt (FindWindow), a następnie jego pozycje (okna :)) przy pomocy GetWindowRect, no i postępować jak ja w tym gotowcu...

Wykrywanie procesu przesuwania okna odbywać się będzie za pomocą komunikatów. Z tego też powodu radzę się zapoznać z artykułem Komunikaty.

Podczas przesuwania okna do aplikacji przesyłany jest komunikat WM_WINDOWPOSCHANGING i to on będzie odgrywał kluczową rolę w naszym programie. Najpierw w sekcji private zadeklaruj taką procedurę:

procedure WndPosChanging(var Msg : TWMWINDOWPOSCHANGING); message WM_WINDOWPOSCHANGING;

Teraz w sekcji Implementation będziesz musiał wpisać kod tej procedury:

procedure TMainForm.WndPosChanging(var Msg: TWMWINDOWPOSCHANGING);
begin
{ wyswietl na komponencie pozycje okna }
  lblWndPos.Caption := 'X: ' + IntToStr(Left) + ' Y: ' + IntToStr(Top);
  
  if Msg.WindowPos.x < 100 then   // jezeli pozycja X jest mniejsza od 100 - przyklej do lewej krawedzi
    Msg.WindowPos.X := 0;

  if Msg.WindowPos.y < 100 then // jezeli pozycja Y bedzie mniejsza od Y przyklej na sama gore okna
    Msg.WindowPos.Y := 0;

    { przyklej do dolu obrazu }
  if Msg.WindowPos.y + height > (Screen.Height - Height + 100) then
    Msg.WindowPos.y := Screen.Height - Height;

  if Msg.WindowPos.x > (Screen.Width - Width - 100) then
    Msg.WindowPos.x := Screen.Width - Width;
end;

To jest cały program! Tak, o to Ci chodziło... gotowe :) Wszystko w tej procedurze to sprawdzanie pozycji okna - WindowPos.X i WindowPos.Y to pozycje okna. Teraz następuje sprawdzenie, czy pozycje te zawierają odpowiednie wartości i w zależności od tego zareagować zmieniając wartość WindowPos. to wszystko! Powodzenia...

5 komentarzy

Proponuję zobaczyć artykuł http://programistakuty.pl/przyciaganie-okna-aplikacji/. Tam jest rzeczowo wytłumaczone jak zastosować przyciąganie okna aplikacji. Ten wyżej przykład niestety nie pozwala na przesuwanie okna poza granice widocznego ekranu. Ja proponuję zastosować algorytm z linku. Dodatkowo jest obsługa przyciągania do wybranych okien własnego programu o jaki McAron prosił:)

Do krawędzi ekranu... a co jeżeli mi przyciągnie do krawędzi na której mam pasek zadań windows? Połowa aplikacji mi wtedy wypada ;D Proponuję użyć screen.WorkArea{..} width top height i right zamiast samych tych bez WorkArea.

Nie wiem czy to u każdego działa tak jak u mnie, ale wtedy aplikacja przylega mi do paska, nie uciekając za niego ;D

Moze lepiej poprawic linki z Delphi do WinAPI? Bo co ma FindWindow czy GetWindowRect do Delphi? Wiem, ze Adam umieszcza te funkcje rowniez w kategorii Delphi, ale mysle, ze linki powinny prowadzic od razu do prawidlowego dzialu.

A mi się podoba :P
Sam sobie zrobie okna...będzie satysfakcja

phi... do krawdzi ekranu? latwizna! Zrobmy przyklejanie do wybranych okien wlasnego programu!!!