5

Próbuję wykryć komunikaty Enter/Leave myszy CM_MOUSEENTER i CM_MOUSELEAVE, ale nie jest to przechwytywanie. Co ja tu robię źle?Mysz Enter/Leave messages nie działa?

type 
    TMyControl = class(TCustomControl) 
    private 
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER; 
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE; 
    procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST; 
    end; 

procedure TMyControl.CMMouseEnter(var Message: TMessage); 
begin 
    //Handle mouse entering 
    //Breakpoint never reached, procedure never called 
end; 

procedure TMyControl.CMMouseLeave(var Message: TMessage); 
begin 
    //Handle mouse leaving 
    //Breakpoint never reached, procedure never called 
end; 

procedure TMyControl.WMNCHitTest(var Message: TWMNCHitTest); 
var 
    Ch: Bool; 
begin 
    if csDesigning in ComponentState then 
    Message.Result := HTCLIENT 
    else begin 
    Ch:= False; 

    //Do checks and pass `Ch:= True;` if something changed... 

    if Ch then Invalidate; 
    end; 
end; 
+1

Mój pierwszy komentarz to brak punktów przerwania do monitorowania takich rzeczy. Interakcja interfejsu użytkownika jest zawsze pomieszana po przełączeniu się do debuggera. Użyj czegoś podobnego do Codesite, aby wysłać wiadomość do innego okna i nie zmieniaj fokusa podczas monitorowania. – mj2008

Odpowiedz

7

zorientowali się mój problem: Używam również WM_NCHITTEST, gdzie nie byłem przechodzącej inherited;. Dodałem to i teraz działa dobrze.

+0

'Wm_NCHitTest' tak czy inaczej wydaje się być niewłaściwym miejscem. Jest to komunikat, który system operacyjny wysyła, gdy chce się dowiedzieć, jaka część kontrolki reprezentuje dany punkt. Nie oznacza to nawet, że mysz jest aktualnie * włączona * w tym punkcie. Co to ma wspólnego z sprawdzeniem, czy coś się zmieniło? Może chcesz "wm_MouseMove"? Lub po prostu wywołaj "Invalidate", gdy tylko coś się zmieni, więc nie będziesz miał później kontroli. –

+0

To jest moje wewnętrzne sprawdzanie, to około 30 linii kodu, które sprawdza pozycję, czy jest ponad prawidłową pozycją - dokładnie to, co ma zrobić. Uznałem, że ta część jest nieistotna, więc wykluczyłem ją i zastąpiłem komentarzem. –

+0

Jeśli robisz coś innego niż decydowanie o wartości przypisanej do 'Message.Result', robisz to w niewłaściwej procedurze obsługi wiadomości. Pamiętaj też, że ze zmianą, którą opisałeś w swojej odpowiedzi, system wyświetli prawidłową wartość tylko wtedy, gdy nic się nie zmieni. Powinieneś rozważyć proste wywołanie "dziedziczenia" bezwarunkowo u góry funkcji. Następnie możesz usunąć specjalne zadanie po sprawdzeniu "ComponentState" i po prostu wyjść z niego. –