Wstęp
Kiedyś długo zastanawiano się jak przyspieszyć pracę przy komputerze, czyniąc ją bardziej efektywną a zarazem ergonomiczniejszą. Wiele nowoczesnych programów umożliwia użytkownikowi interakcje za pomocą standardu (czy raczej technologii) Drag&Drop. Pewnie nie od początku wiedzieliśmy jak nazywa się technologia, którą wykorzystujemy zupełnie nieświadomie 😉
Termin Drag&Drop pojawił się podczas projektowania pierwszych systemów operacyjnych z graficznym interfejsem użytkownika (tzw. GUI od ang. Graphics User Interface). Był to naprawdę bardzo dobry pomysł. Łączył w sobie prostotę i dużą ergonomię. Jednym słowem, od tej chwili, kursor stał się przedłużeniem naszej własnej graby.
W tym artykule nauczę Was obsługiwać technologię wirtualnej łapy w Delphi. Zobaczycie jak to wszystko działa i co musi uczynić komponent docelowy aby przeciągany „ładunek” mógł zostać upuszczony. Artykuł zawiera jedynie podstawy kierowane do średnio-zaawansowanych programistów.
Aby zrozumieć podstawowe zagadnienia związane z techniką Drag&Drop należy wspomnieć iż komponent nie może przyjąć przeciąganej „paczki danych” dopóki nie wyrazi na to zgody. Analogicznie, kontrolka nie może rozpocząć operacji Drag&Drop bez przygotowania się do niej za pomocą specjalnej instrukcji.
Za operację Drag&Drop odpowiadają tak właściwie jedynie dwa zdarzenia. Są nimi OnDragOver oraz OnDragDrop . Pierwsze z nich (OnDragOver) wywoływane jest gdy użytkownik, podczas operacji przeciągania, najedzie kursorem na dany komponent. Drugie zdarzenie (OnDragDrop) jest wywoływane wtedy gdy użytkownik upuści przeciągany element na kontrolkę.
Praktycznie, wykorzystuje się jeszcze jedno zdarzenie – OnMouseMove. Napiszmy zatem przykładowy program.
Piszemy program
Uruchom Delphi’ego.
Na formularzu umieść komponent ListBox oraz komponent Edit. Oba znajdują się na palecie Standard.
Zaznacz komponent ListBox i w Inspektorze Obiektów odszukaj pole Items. Kliknij na nie. Kliknij następnie na przycisk „…” (trzy kropki), który się pojawi.
Do okna które się pojawi wpisz jakieś bzdury. Podaje przykładowe bzdury 😉 :
Jan Kowalski
Piotr Najsztub
Wojtek Pręgała
Aleksy Dajkiewicz
Mirosław Tremn
Witold Dółkowski
Irena Zawada
Zamknij okno, klikając na OK. Właśnie taaak 😉
Przypis 1.0: Zbieżność nazwisk przypadkowa
W Inspektorze Obiektów przejdź do zakładki Events (zdarzenia) i dwukrotnie kliknij w pole znajdujące się po prawej od OnMouseMove. Zostanie wygenerowana procedura, która wywoływana będzie wtedy, kiedy kursor myszy poruszy się nad komponentem (w tym wypadku jest nim zaznaczona kontrolka ListBox). Procedurę tą uzupełniamy następująco:
1 2 3 4 5 6 7 8 9 10 11 |
procedure TForm1.ListBox1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if ssLeft in shift Then ListBox1.BeginDrag(False); end; |
Pierwsza linijka: To warunek. Jeśli podczas przesuwania kursora nad komponentem jest wciśnięty lewy (ssLeft) przycisk myszy to…
Druga linijka: Komponent ListBox1 ma rozpocząć operację Drag&Drop (instrukcja BeginDrag() ). Parametr instrukcji BeginDrag oznacza, czy operacja Drag&Drop ma rozpocząć się:
False gdy natychmiast (wartość pierwszego parametru False, drugiego parametru nie wpisujemy)
True gdy z opóźnieniem (po przejechaniu przez mysz kilku pikseli) (wartość pierwszego parametru True, drugi parametr oznacza ilość pikseli po których ma rozpocząć się operacja przeciągania)
Przechodzimy do widoku formularza (naciskając klawisz F12).
Zaznaczamy komponent Edit i w Inspektorze Obiektów, na zakładce Events odnajdujemy zdarzenie OnDragOver. Klikamy nań dwukrotnie, analogicznie jak poprzednio.
Zostaje wygenerowana nowa procedura wywoływana wtedy, gdy użytkownik trzyma kursor (wraz z przeciąganym elementem) nad komponentem. Treść procedury uzupełniamy następująco:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
procedure TForm1.Edit1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin if source is TListBox Then accept := True else accept := False; end; |
Powyższy zapis jest bardziej czytelny dla początkujących. Można również zastosować równoważny zapis:
1 2 3 4 5 6 7 8 9 |
procedure TForm1.Edit1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin accept := (source is TListBox); end; |
Należy wspomnieć w tym miejscu iż przypisanie do zmiennej accept wartości True spowoduje zaakceptowanie przeciąganej paczki. Oba zapisy akceptują paczkę jedynie wtedy kiedy pochodzi z komponentu typu TListBox. Jeżeli paczka pochodzi z komponentu innego typu wówczas nie będzie możliwe jej upuszczenie (charakterystyczny kursor w postaci zakazu).
Przechodzimy do widoku formularza (klawisz F12).
Zaznaczamy komponent Edit i w Inspektorze Obiektów, na zakładce Events odnajdujemy zdarzenie OnDragDrop. Klikamy nań dwukrotnie, analogicznie jak w poprzednich krokach.
Zostaje wygenerowana nowa procedura, która wywoływana będzie wtedy, gdy użytkownik upuści przeciągany obiekt na komponent. Treść procedury uzupełniamy następująco:
1 2 3 4 5 6 7 |
procedure TForm1.Edit1DragDrop(Sender, Source: TObject; X, Y: Integer); begin TEdit(Sender).Text := TListBox(Source).Items.Strings[TListBox(Source).Itemindex]; end; |
Powyższa instrukcja powoduje przypisanie do komponentu (docelowego) typu TEdit aktywnej (zaznaczonej) pozycji komponentu (źródłowego) typu TListBox.
Tak, wiem – nieco skomplikowane. Takie coś: TEdit(Sender) oznacza, że komponent docelowy (ten do którego przeciągamy dane) jest typu TEdit, czyli zwykłą kontrolką tekstową. Dzięki takiemu „trikowi” możemy przykładowo skorzystać z jego właściwości Text, która jest charakterystyczna jedynie dla kontrolek tekstowych.
Gdybyśmy napisali samo Sender i postawili kropkę, w liście która by się rozwinęła nie spostrzeglibyśmy właściwości Text, gdyż tak naprawdę kompilator nie wiedziałby jakiego dokładnie typu jest parametr Sender.
To już koniec. Możesz uruchomić program i sprawdzić czy działa, przeciągając pozycję z komponentu ListBox do komponentu Edit.
Zakończenie
Dzięki wszystkim za uwagę. Oczywiście do artykułu dołączam kod pisanej aplikacji. Technika Drag&Drop kojarzy się użytkownikom z rozbudowanymi i poważnymi aplikacjami. W tym artykule dowiedziałeś się, iż niewiele potrzeba do jej implementacji. Życzę wszystkim udanych projektów.
Artykuł pochodzi ze strony http://www.lukas-home-page.ovh.org
—
Łukasz „Lukas” Wyporek
wyporek{at}poczta.onet.pl