Symulacja Drag and Drop

Odpowiedz Nowy wątek
2016-10-25 22:09
Delfin 53
0

Witam
Jak można symulować drag and drop.
Chciałbym wydarzeniem ButtonClick lub uruchomieniem skrótu klawiaturowego spowodować przesunięcie zawartości okna przeglądarki (konkretnie mapy tak jak w google.maps) o pewną odległość (z punktu x1,y1 do x2,y2). Czyli symulacja przesuwania kursora z symulowanym wciśnięciem lewego przycisku i następnie puszczenie.
Czy w mouse_event są odpowiednie polecenia. Znam symulację naciśnięcia i puszczenia lewego przycisku ale przecież pomiędzy nimi ma być przesunięcie- jak wykonać to przesunięcie :)

Pozostało 580 znaków

2016-10-26 05:53
Delfin 53
0

Próbowałem kod:

  CurPos,Pt : TPoint;
begin
  GetCursorPos(CurPos);
  Application.ProcessMessages;
  {Get the point in the center of Button 2}
  Pt.x := CurPos.X ;
  Pt.y := CurPos.Y ;
  {Convert Pt to screen coordinates and Mickeys}
  Pt := ClientToScreen(Pt) ;
  Pt.x := Round(Pt.x * (65535 / Screen.Width)) ;
  Pt.y := Round(Pt.y * (65535 / Screen.Height)) ;

  {Simulate the left mouse button down}
  Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTDOWN, Pt.x, Pt.y, 0, 0) ;;

  {Simulate the mouse move}
  Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, Pt.x+400, Pt.y+400, 0, 0) ;

  {Simulate the left mouse button up}
  Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_LEFTUP, Pt.x+400, Pt.y+400, 0, 0) ;

ALE PRZESUWA TYLKO KURSOR A NIE TO CO POD KURSOREM :(

edytowany 1x, ostatnio: furious programming, 2016-12-13 18:26

Pozostało 580 znaków

2016-10-26 06:07
Delfin 53
0

Nie wiem jak zrobić żeby w czasie przesuwania kursora Lewy Przycisk Myszy pozostawał cały czas wciśnięty........

Pozostało 580 znaków

2016-10-26 10:54
0

Ja mam taką aplikację, która klika w wyznaczony punkt kod wygląda tak:

var
  CurrentPos : TPoint;
  CurrentWindow : HWND;
begin
  CurrentWindow := GetForegroundWindow; // pobierz uchwyt aktywnego okna
  GetCursorPos(CurrentPos); // pobierz tymczasowa pozycje ekranu

  ShowWindow(Foreground, SW_SHOWNA);  // pokaz okno
  BringWindowToTop(Foreground); // dla pewnosci - wysun na wierzch
  SetForegroundwindow(Foreground);  // ustaw aktywne okno

  //Xedt i Yedt to TEdit z zapisanymi współrzędnymi gdzie kliknąć więc u ciebie załatwi to GetCursorPos
  SetCursorPos(StrToInt(Xedt.Text), StrToInt(Yedt.Text));  // ustaw w wybranej pozycji
  { kliknij na pozycje }
  mouse_event(MOUSEEVENTF_LEFTDOWN, StrToInt(Xedt.Text), StrToInt(Yedt.Text), 0, 0);
  //tu dorabiasz mouse move 
...
  //i na końcu up
  mouse_event(MOUSEEVENTF_LEFTUP, StrToInt(Xedt.Text), StrToInt(Yedt.Text), 0, 0);

  ShowWindow(Currentwindow, SW_SHOWNA);  // pokaz okno
  SetForegroundWindow(Currentwindow);  // ustaw aktywne okno
  SetCursorPos(CurrentPos.X, CurrentPos.Y); // ustaw ponownie na poprzedniej pozycji
end;

Pozostało 580 znaków

2016-10-26 13:20
1

Zaposnaj się z tym wątkiem bo też miałem kiedys podobny problem :) Ty po prostu będziesz musiał wyświetlać część mapy albo wczytywac tylko okreslony jej fragment po przesunięciu.

Przesuwanie obrazka po canvas


Kto nigdy nie zrobił var dupa niech pierwszy rzuci kamień.
Ale się w tym wątku opisałem... :P - furious programming 2016-10-26 13:27
Działo się... ;) - karpov 2016-10-26 14:45

Pozostało 580 znaków

2016-10-26 15:55
Delfin 53
0

Karpov, dziękuję za przykład, z tym że mnie chodzi nie o samo drag&drop ale o jego symulację, czyli efekt przesunięcia ma być wywołany nie ruchem myszki z wciśniętym przyciskiem tylko np. skrótem klawiaturowym.

Z klawiatury ma być uruchomiony kod symulujący ruch myszy z wciśnięciem lewego przycisku.

Nie potrzebuję sprawdzać czy obiekt pod kursorem nadaje się do przesuwania, bo wiem że tak (nad takim obiektem ustawiam kursor)

Pozostało 580 znaków

2016-10-26 16:12
0

Podobną zabawę urządziłem sobie ostatnio podczas pisania "sterownika" dla gamepada dla gry agar.io; Program cyklicznie sprawdzał stan D-Pada oraz jego przycisków, na tej podstawie ustawiał kursor w odpowiednim miejscu na ekranie, a także symulował wciskanie i puszczanie klawiszy W, Space, Esc itd.; Program był bardziej skomplikowany, dlatego że dodatkowo umożliwiał obsługę dwóch trybów (gry oraz obsługi menu); W tym drugim trybie, D-Padem możliwe było poruszanie kursorem po ekranie, a przycisk umożliwiał symulację klikania LPM;

Symulacja ruchu kursorem to pobieranie jego pozycji za pomocą GetCursorPos, modyfikacja współrzędnych względem danego kierunku oraz ustawienie kursora na nowej pozycji za pomocą SetCursorPos; Symulacja wciskania przycisków myszy to wywołania mouse_event, a klawiszy klawiatury to wywołania keybd_event;

Jeśli więc potrzebujesz zasymulować drag & drop to wystarczą:

  • GetCursorPos i SetCursorPos do ruchu kursorem,
  • mouse_event do symulacji wciśnięcia i puszczenia LPM;
    Zamiast mouse_event i keybd_event można skorzystać z SendInput; Schemat jest względnie prosty:
  1. ustawienie kursora w miejscu początkowym,
  2. symulacja wciśnięcia LPM,
  3. w pętli, względem kierunku i odległości:
    1. pobranie bieżącej pozycji kursora,
    2. modyfikacja współrzędnych według zadanego kierunku i odległości,
    3. ustawienie kursora w nowej pozycji,
    4. zamrożenie pętli na chwilkę,
  4. symulacja puszczenia LMP;
    Teraz wystarczy to zapisać w postaci kodu;

Przesuwanie kursora poziomo, pionowo oraz po ukosach jest proste, bo wystarczy dodać lub odjąć rozmiar skoku od danej współrzędnej/współrzędnych; Nieco trudniej jest przesuwać kursor dla zadanego kąta, jednak algorytm wyznaczania nowego punktu na podstawie zadanego kąta i odległości jest bardzo prosty; Ten sam algorytm używany jest do rysowania linii - można go znaleźć w sieci bez problemu.


edytowany 6x, ostatnio: furious programming, 2016-10-26 16:17

Pozostało 580 znaków

2016-10-26 16:26
Delfin 53
0

furious programming , tego się nie spodziewałem
muszę to sprawdzić, działa czy nie działa

Pozostało 580 znaków

2016-10-26 17:16
0

Na pewno będzie działać, dlatego że dla systemu to wszystko jedno, czy użytkownik steruje prawdziwą myszą, czy aplikacja ją udaje; Efekt podanego przeze mnie rozwiązania będzie wyglądał tak, jakby kursor sam chodził po ekranie i robił to co mu się podoba :]


edytowany 3x, ostatnio: furious programming, 2016-10-26 17:17

Pozostało 580 znaków

2016-10-26 17:18
Delfin 53
0

urious programming ,jestem w trakcie tworzenia, lecz są małe trudności
1-nie rozumiem dlaczego jest potrzebna pętla , czyżbym musiał przesuwać piksel po pikselu?,
a nie mogę po prostu podać jedynie początkowe a potem końcowe położenie kursora (skoro potrzebuję tylko jedno przesunięcie z punktu a do b po prostej)?
2-po co w trakcie przesuwania pobierać pozycję kursora (przecież ustawiam go poleceniem SetCursorPos więc wiadomo gdzie on jest-przecież nigdzie nie powędrował)
3-a jeśli już konieczna pętla i jej chwilowe zamrożenie to jak wykonać zamrożenie

Pozostało 580 znaków

2016-10-26 17:25
0

1-nie rozumiem dlaczego jest potrzebna pętla , czyżbym musiał przesuwać piksel po pikselu?,
a nie mogę po prostu podać jedynie początkowe a potem końcowe położenie kursora (skoro potrzebuję tylko jedno przesunięcie z punktu a do b po prostej)?

Oczywiście że możesz - to co podałem umożliwi stworzenie animacji ruchu kursora, jednak jeśli nie potrzebujesz ładnego wizualnie efektu to możesz od razu przenieść kursor z punktu źródłowego do docelowego; Powinno bez problemu działać;

2-po co w trakcie przesuwania pobierać pozycję kursora (przecież ustawiam go poleceniem SetCursorPos więc wiadomo gdzie on jest-przecież nigdzie nie powędrował)

To dotyczy animacji, więc punkt ten możesz pominąć; Zresztą nawet przy animowanym ruchu kursora, wystarczy dodatkowa zmienna z bieżacą pozycją, aby wykluczyć pobieranie pozycji przez GetCursorPos w pętli;

3-a jeśli już konieczna pętla i jej chwilowe zamrożenie to jak wykonać zamrożenie

Wystarczy samo Sleep, ew. dodatkowo Application.ProcessMessages, jeśli podczas ruchu kursora kolejka komunikatów ma być przetwarzana "w tle";

Trochę się zagalopowałem z poprzednim opisem, bo miałem w głowie animację i na tej podstawie opisałem rozwiązanie; Jeżeli nie chcesz animacji to schemat będzie dużo prostszy:

  1. ustawienie kursora w punkcie źródłowym, za pomocą SetCursorPos,
  2. symulacja wciśnięcia LPM np. za pomocą mouse_event,
  3. ustawienie kursora w punkcie docelowym, za pomocą SetCursorPos,
  4. symulacja puszczenia LPM np. za pomocą mouse_event;
    Być może mały Sleep będzie potrzebny, aby aplikacja zdążyła zareagować na przeciąganie.

edytowany 6x, ostatnio: furious programming, 2016-10-26 17:29

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0