5

Estoy tratando de detectar los mensajes de entrada/salida del mouse CM_MOUSEENTER y CM_MOUSELEAVE pero no lo está captando. ¿Qué estoy haciendo mal aquí?Ratón Entrar ¿Dejar mensajes que no funcionan?

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

Mi primer comentario es que no use puntos de interrupción para controlar tales cosas. La interacción de la interfaz de usuario siempre está en mal estado cuando se cambia al depurador. Use algo como Codesite para enviar un mensaje a otra ventana, y asegúrese de no cambiar el enfoque durante la monitorización. – mj2008

Respuesta

7

me di cuenta de mi problema: También estoy usando WM_NCHITTEST, en el que no estaba pasando inherited;. Añadí esto, y ahora funciona bien.

+0

'Wm_NCHitTest' parece ser el lugar equivocado para eso de todos modos. Es un mensaje que el sistema operativo envía cuando quiere saber qué parte de un control representa un cierto punto. Ni siquiera significa que el mouse esté actualmente * en * ese punto. ¿Qué tiene eso que ver con verificar si algo cambió? Tal vez quieras 'wm_MouseMove'? O simplemente llame a 'Invalidar' tan pronto como algo cambie, por lo que no tendrá control más adelante. –

+0

Es mi propia verificación interna, son unas 30 líneas de código que comprueban la posición para ver si está sobre una posición válida, exactamente lo que debe hacer. Pensé que esa parte era irrelevante, así que la excluí y la reemplacé con un comentario. –

+0

Si está haciendo algo más que decidir qué valor asignar a 'Message.Result', lo está haciendo en el controlador de mensajes incorrecto. Además, tenga en cuenta que con el cambio que ha descrito en su respuesta, solo devolverá un valor válido al sistema operativo cuando nada haya cambiado. Debería considerar simplemente llamar 'inherited' incondicionalmente en la parte superior de la función. Luego puede eliminar la asignación especial después de verificar 'ComponentState' y simplemente salir en su lugar. –

Cuestiones relacionadas