jak w obsłużyć OnMouseEnter/ Leave dla komponentów?

0

Mam na formie np. Panel1, Panel2, Panel3. Jeśli nakieruję kursor na Panel1 to chcę, by zmienił się jego kolor (Panel1.Color), a jak opuszczę kursorem ten Panel1 to kolor zmieni się z powrotem na domyślny (Panel1.Color:= ), no i tak dla każdego Panelu ma być.

Mógłbym kliknąć po kolei na każdy Panel i w zdarzeniach (events) wybrać OnMouseEnter, OnMouseLeave, ale to chyba nie jest zbyt dobry pomysł. Zamierzam pliki przeciągać na komponenty na formie, komponentów będzie np. 10, a podczas przeciągania pliku (czyli jesteśmy kursorem np. na Panel1), to wtedy zdarzenie pod względem wizualnym nie jest obsługiwane, choć w kodzie działa dobrze). Możliwe, ze w wątku musiałbym te zdarzenia zrobić lub w czymś. Czy macie jakieś pomysły?

Mam już napisane przeciąganie plików, działa idealnie. Pozostaje mi teraz wykryć nad którym komponentem typu TPanel (lub TImage) jest kursor myszy z plikiem i chodzi o wykonanie przykładowego Panel1.Color:= zanim upuści się plik na tym panelu.

PS. komponenty nie są tworzone dynamicznie więc w razie czego mogę im ręcznie ustawić "Tag" dla ułatwienia w identyfikacji.
Prosiłbym was o jakieś rady.

0

Możesz ustawić wszystkim panelom jedno zdarzenie OnMouseEnter i jedno OnMouseLeave a rozpoznawać poszczególne z nich przez sender'a http://lukashp.pl/Artykul/Programowanie/Delphi/delphi-parametr_sender

0
szopenfx napisał(a):

Możesz ustawić wszystkim panelom jedno zdarzenie OnMouseEnter i jedno OnMouseLeave a rozpoznawać poszczególne z nich przez sender'a http://lukashp.pl/Artykul/Programowanie/Delphi/delphi-parametr_sender

dzięki, ale dałem dla przykładu w OnMouseEnter:

TPanel(Sender).Caption:= IntToStr(TPanel(Sender).Tag);

i działa to tylko wtedy kiedy nie przeciągam plików. Podczas przeciągania plików jest inaczej, nie widać wizualnej zmiany Caption panelu. Jak rozwiązać ten problem?

0

OnDragOver? albo coś z Drag'ami

0

Popróbowałem i nie daję rady. Może ktoś z was znajdzie 3 minuty i spróbuje.

pod private

procedure WMDropFiles(var msg: TWMDropFiles); message WM_DROPFILES;

w kodzie:

procedure TForm1.FormCreate(Sender: TObject);
begin
  DragAcceptFiles(Handle, True);
end;

procedure TForm1.WMDropFiles(var msg: TWMDropFiles);
var
  buffer: array[0..MAX_PATH] of Char;
begin
  DragQueryFile(msg.Drop, 0, @buffer, MAX_PATH);
  Memo1.Lines.Add(buffer);
  DragFinish(msg.Drop);
end;

Na formie jeden komponent TMemo. Możecie dodać np. dwa komponenty TPanel i ustawić im Tag na 1 i 2 i spróbować doklepać kilka linijek kodu i sprawdzić zachowanie Paneli. U mnie w żaden prosty sposób panele nie zmienią mi np. Form1.Caption np. na "aaaa" (oczywiście podczas przeciągania pliku z pulpitu na jakiś Panel, przed upuszczeniem tej rzeczy).
Zanim plik upuszczę na panelu, musi zostać wykonany kod jakiś. Finalnie mam zamiar umieścić kilka TImage i przeciągając plik nad te pola TImage, chcę by na nich rysowała się ramka, dlatego ta ramka musi zostać narysowana zanim plik zostanie gdziekolwiek upuszczony. Problem w tym, że nie potrafię wykonać kodu przed upuszczeniem pliku dlatego do was zwracam się z prośbą o jakieś konkretniejsze wskazówki. Gdyby komuś chciało się to sprawdzić, to bardzo mu dziękuję. Nie oczekuję gotowca, po prostu chcę, by jakiś użytkownik sam sprawdził, czy to co mi chce doradzić, faktycznie działa.

0

Odświeżam i ponownie proszę o pomoc.

Sprawa wygląda tak - zdarzenie OnMouseEnter w panelu nie jest wykonywane w ogóle podczas przeciągania pliku i trzymania go nad panelem. Dopiero gdy upuści się plik, zdarzenie OnMouseEnter zaczyna działać i wykonuje się. Krótko mówiąc - gdy plik trzymamy nad Panelem, zdarzenia OnMouseEnter są spauzowane! czy tak jakby one nie istniały w tym czasie! Jak mam zrobić, by te zdarzenia działały nim upuszczę jakiś plik? Bez sensu jest to zatrzymanie eventów, muszę jakość podświetlać panel zanim upuszczę plik na panelu, bo na co mi kolorowanie panelu dopiero po upuszczeniu pliku?

0

No to koloruj panel w zdarzeniu OnDragOver

0

Nie bawię się w DnDp (co by to miało oznaczać) gdyż zauważyłem, że moim odbiorcom bardziej pasują przyciski (wykonaj to i tamto). Z tego co pamietam, to obie kontrolki (dragana i dropowana - przepraszam za słownictwo - mi też uszy bolały jak to czytałem - nadaje się do perełki?) powinny posiadać możliwość obsłużenia takiego komunikatu. W zawiązku z tym proponowałbym poczytać, zmienić ustawienia komponentu, dodać (powiązać) obsługę zdarzeń i gotowe. Kluczowa jest tu obsługa zdarzeń. Oczywiście daleko od mojego opisu do dokumentacji, ale zdaje się, że tak się to wykonuje? (tu krytycy powiedzą ach, a użytkownicy ojej, albo na odwrót :)

0
pelsta napisał(a):

No to koloruj panel w zdarzeniu OnDragOver

gdzie w OnDragOver? w evencie komponentu? Nawet jak dam w OnDragOver na formie kod Form1.Caption:= 'aaaa'; to i tak nie wykona się ten kod. Widocznie źle coś robię więc skoro masz doświadczenie, proszę o więcej informacji.

0

W zdarzeniu OnDragOver tych paneli oczywiście.

0
pelsta napisał(a):

W zdarzeniu OnDragOver tych paneli oczywiście.

nie działa. Sam sprawdź jak chcesz. Próbowałem to wczoraj nawet.

0

Piszę tutaj wyłącznie sprawdzone porady. Widocznie zły kod napisałeś.

0
trtrtr napisał(a):
pelsta napisał(a):

W zdarzeniu OnDragOver tych paneli oczywiście.

nie działa. Sam sprawdź jak chcesz. Próbowałem to wczoraj nawet.

Dobrze, że próbowałeś, ale jeśli nie zadziałało to wklej ten kod, a podpowie się co jest w nim źle i jak to zmienić; Szczególnie gdy @pelsta ten sposób przetestował i u niego zadziałał, więc poprawnie zakodząc u Ciebie też zadziała.

0
  private
    { Private declarations }
    procedure WMDropFiles(var msg: TWMDropFiles); message WM_DROPFILES;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  DragAcceptFiles(Handle, True);
end;


procedure TForm1.FormDragOver(Sender, Source: TObject; X, Y: Integer;
  State: TDragState; var Accept: Boolean);
begin
  Accept:= True;
  Form1.Caption:= 'la la la';
end;

procedure TForm1.FormMouseEnter(Sender: TObject);
begin
  Form1.Caption:= 'on mouse enter!';
end;

procedure TForm1.WMDropFiles(var msg: TWMDropFiles);
var
  buffer: array[0..MAX_PATH] of Char;
begin
  DragQueryFile(msg.Drop, 0, @buffer, MAX_PATH);
  Memo1.Lines.Add(buffer);
  DragFinish(msg.Drop);
end;

I przeciągam plik na formę i zanim puszczę plik nigdy Caption formy się nie zmienia. Może w ogóle źle to wszystko robię? Na tym przykładzie bez paneli dałem, dla uproszczenia. Po prostu chcę przeciągany plik trzymać nad formą i chcę by Caption Formy się zmienił zanim ten plik upuszczę, niestety nie wiem jak, bo powyższy kod nie działa.

0

A więc FormDragOver nie jest u Ciebie generowane.

0
pelsta napisał(a):

A więc FormDragOver nie jest u Ciebie generowane.

co sugerujesz? (wiesz jaki efekt chcę osiągnąć. Czy mógłbym cię poprosić o udzielenie minimalnie więcej informacji?)

0

Sorry, nie potrafię udzielić więcej informacji na ten temat.

0
pelsta napisał(a):

Sorry, nie potrafię udzielić więcej informacji na ten temat.

to znaczy, że coś u mnie na pc jest nie tak, a kod jest w porządku, czy, że kod jest zły, a ty chcesz, bym sam rozwiązał problem bez wskazówek, czy że nie wiesz jak rozwiązać problem?

0

Niepotrzebne spiskowe teorie :)
To po prostu znaczy, że przeciąganie pliku na formę widocznie nie generuje zdarzenia FormDragOver i nie wiem jak rozwiązać ten problem.

0
pelsta napisał(a):

Niepotrzebne spiskowe teorie :)
To po prostu znaczy, że przeciąganie pliku na formę widocznie nie generuje zdarzenia FormDragOver i nie wiem jak rozwiązać ten problem.

Aha, to dobrze. Dziękuję. :)
Może jutro ktoś z programistów zajrzy do tematu i może miał z tym styczność i udzieli wskazówek.

0

@trtrtr: z kodu jaki wkleiłeś wynika, że chcesz tylko stwierdzić kiedy myszka jest w obszarze formatki lub poza nią. Jeżeli tak, to ja widzę takie rozwiązania. Albo sprawdzanie w nieprzerwanym wątku z krótkim Sleep'em czy kursor myszki jest w/poza obszarem formatki. Druga metoda (może i armata na muchy, może i nieco inawazyjna, ale tę sprawdzałem w przeciwieństwie do wątku) to globalny hook na myszkę i sprawdzanie jej koordynatów oraz funkcja PtInRect. Może ktoś jeszcze coś tutaj doradzi, co będzie lepsze oraz działające poza tymi dwoma wspomnianymi powyżej metodami.

0

Ok, dzięki Olesio. Nawet jest funkcja do uzyskania pozycji X, Y na formie.

var
  p: TPoint;
begin
  p:= ScreenToClient(Mouse.CursorPos);

bez tej funkcji (ScreenToClient), punkty X i Y kursora wskazywałoby pozycję licząc dla całego ekranu (olewałyby formę).

Przy okazji mam nowy problem z rysowaniem czegoś, bo mój Image nie przechowuje bitmapy heh, ale wymyślę coś sam może.

0
olesio napisał(a):

Albo sprawdzanie w nieprzerwanym wątku z krótkim Sleep'em czy kursor myszki jest w/poza obszarem formatki.

Takie sprawdzanie robiłem sobie z Timerem i bardzo dobrze się sprawdzało. Interval ustawiłem na 50ms. Wykorzystywałem funkcję GetCursorPos. Gdy sprawdzanie nie było potrzebne to po prostu Timer wyłączałem.

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