ATNEL tech-forum
https://forum.atnel.pl/

[Delphi] OnMouseMove - problem
https://forum.atnel.pl/topic18318.html
Strona 1 z 1

Autor:  Gaek [ 3 maja 2017, o 14:43 ]
Tytuł:  [Delphi] OnMouseMove - problem

Witam

Chciałbym napisać program, w którym mógłbym kolorować panele (komponent TPanel) za pomocą kliknięcia i przytrzymania (prawego lub lewego) przycisku myszy.
W tym celu dla każdego panelu przygotowałem zdarzenie OnMouseMove, które sprawdza stan przycisków (funkcja przekazuje parametr Shift: TShiftState).
Mimo, że instrukcje sprawdzające dla lewego i prawego przycisku myszy są takie same to zachowanie ich jest inne.

Składnia: [ Pobierz ] [ Ukryj ]
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Zachowanie programu:
*Prawy przycisk myszy - klikniecie i przytrzymanie w dowolnym obszarze okna i przemieszczenie kursora na jeden z paneli powoduję zmianę koloru - reakcja prawidłowa.
*Lewy przycisk myszy - klikniecie i przytrzymanie w dowolnym obszarze okna i przemieszczenie kursora na jeden z paneli nie powoduję zmianę koloru - reakcja nieprawidłowa. Zmiana koloru następuje jedynie po kliknięciu w obszarach paneli i przemieszczenie kursora o jeden pixel(?).
W załączniku umieściłem projekt programu.
Czy ktoś borykał się już z takim problemem? Czy jest prostszy sposób na realizację takiej funkcji?

Autor:  Adam12 [ 4 maja 2017, o 22:03 ]
Tytuł:  Re: [Delphi] OnMouseMove - problem

Dzieje się tak dlatego, że kliknięta kontrolka lub forma powoduje przetrzymanie komunikatu myszy tylko dla siebie. Można to łatwo sprawdzić odczytując na bieżąco parametry X,Y w zdarzeniu OnMouseMove. Po wciśnięciu lewego klawisza można jeździć kursorem po innych kontrolkach a i tak działa tylko kod zdarzenia kontrolki na której został wciśnięty lewy klawisz myszy. Zachowanie jest inne dla prawego klawisza, ale tak to już jest urządzone w Windowsie i ma to prawdopodobnie związek z Drag&Drop.

Są na to różne sposoby. Najprościej dla każdej kontrolki oraz głównej formy w zdarzeniu OnMouseMove wywołać procedurę ReleaseCapture lub SetCaptureControl(nil). Powoduje to zwolnienie tego przetrzymania. Dla tej drugiej procedury parametr (nil) oznacza brak przetrzymującej kontrolki. Jeśli zmienimy to np. na SetCaptureControl(Button1) to nastąpi przejęcie komunikatów przez Button1.

Drugi sposób to usunięcie flagi csCaptureMouse ze zbioru ControlStyle danego komponentu:
Składnia: [ Pobierz ] [ Ukryj ]
język delphi
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Działa to jednak chyba tylko dla "nieklikalnych komponentów" jak forma, panel. Dla przycisku i tak trzeba stosować ReleaseCapture. Jeśli jednak założymy, że wciśnięcie klawisza nastąpi w obrębie formy lub jednego z paneli to ten sposób może być wystarczający.
Przy większej ilości kontrolek najlepiej zastosować oba sposoby, a wywołanie ReleaseCapture umieścić w osobnej procedurze np:
Składnia: [ Pobierz ] [ Ukryj ]
język delphi
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

którą podpinamy pod zdarzenie OnMouseMove każdej pozostałej kontrolki na formie o ile nie wymaga ona jakiejś specjalnej obsługi tego zdarzenia.

W załączniku poprawiony program w wersji z csCaptureMouse i procedurą ReleaseCaptureMouse podpiętą do OnMouseMove Buttona1. Przy okazji trochę się pobawiłem i dodałem obsługę wciśnięcia dwóch klawiszy na raz. :)

Strona 1 z 1 Strefa czasowa: UTC + 1
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/