user-interface - poner - mi mouse no da click
Detectando un solo clic del mouse en MFC (7)
En MFC un evento de clic de doble mouse desencadena la siguiente secuencia de mensajes
- WM_LBUTTONDOWN
- WM_LBUTTONUP
- WM_LBUTTONDBCLK
- WM_LBUTTONUP
Entonces, responder al mensaje WM_LBUTTONDBCLK le permite detectar un doble clic. Pero si solo quiero detectar un solo clic cómo distinguirlo?
Pero solo mirar el mensaje WM_LBUTTONUP no es suficiente, ya que podría ser un solo clic o podría ser el primer clic de un doble clic.
¿Cómo puedo identificar con éxito solo un clic?
(Permítame llamar a estos eventos Mouse Up y Mouse Down. Mi MFC está un poco oxidado. Y hay algo llamado .NET que ha estado estropeando mi terminología últimamente ;-)
Cuento corto : no solo quiere saber sobre Mouse Click. Necesitas mas.
Larga historia :
Aunque esto no es intuitivo, parece que simplemente querer hacer clic con el mouse es bastante raro. En la mayoría de los casos, querrás realizar algún procesamiento en Mouse Down y realizar un procesamiento adicional en Mouse Up. El truco es que simplemente el seguimiento de los mensajes de Mouse Up no es suficiente: puede que Mouse Down no haya sucedido en su ventana. ¿Lo considera un clic válido entonces? Especialmente teniendo en cuenta que el procesamiento de Mouse Down (como la selección de un elemento) no se produjo.
Yendo más lejos en el razonamiento, no debe confiar en recibir un Mouse Up después de procesar Mouse Down: el usuario puede haber movido el mouse y haber soltado el botón en otro lugar (piense en arrastrar y soltar), en cuyo caso, no lo hace recibe el evento MouseUp ... a menos que capture el mouse en MouseDown para asegurarse de que el evento del mouse llegue a Mouse Up, incluso si el mouse dejó su ventana.
Con todo, terminas rastreando Mouse Down, capturando el mouse y cuando recibes Mouse Up, solo revisa si eres dueño de la captura. Si no, se hizo doble clic en el mouse (no se hizo el 2do mouse hacia abajo) o Mouse Down sucedió en otro lugar, por lo tanto, es muy probable que no te importe este Mouse Up.
En conclusión : no hay mensaje de MouseClick simplemente porque no llegaría muy lejos con él: de todos modos, necesita manejar más mensajes e implementar más mecanismos.
Oh! Y si se trata de un control existente que ya maneja todos estos elementos y elementos de selección, como una vista de lista, es probable que proporcione una notificación personalizada similar, como Activar artículo o Cambiar elemento seleccionado.
Acabo de probar esto en Delphi, el comportamiento es el mismo: incluso cuando se produce un doble clic, se emite un solo clic justo después de la primera de las dos.
Lo resolví usando un temporizador, que funciona así:
- desactivar el temporizador en WM_LBUTTONDBLCLK (y establecer
bDbl
entrue
) - activar temporizador en WM_LBUTTONUP si
bDbl==false
- desactivar en WM_LBUTTONUP si
bDbl==true
(y restablecerbDbl
)
Establecí el intervalo del temporizador en el tiempo devuelto por GetDoubleClickTime
.
MSDN dice:
La función GetDoubleClickTime recupera el tiempo de doble clic actual para el mouse. Un doble clic es una serie de dos clics del botón del mouse, el segundo ocurre dentro de un tiempo especificado después del primero. El tiempo de doble clic es la cantidad máxima de milisegundos que puede ocurrir entre el primer y el segundo clic de un doble clic.
Si el temporizador dispara, entonces tienes el clic real. En mi caso, el intervalo de doble clic es de 500 ms, por lo que cualquier "clic real" se retrasará tanto tiempo.
Por lo general, mira @MLButtonUp y no tendría un solo clic y comportamiento de doble clic en el mismo botón del mouse.
Puede usar PreTranslateMessage () para contar los mensajes tal como aparecen. Si ha recibido solo los mensajes del mouse correspondientes a un solo clic, y la hora configurada por el sistema para hacer doble clic ha expirado, puede suponer con seguridad que se trata de un solo clic.
Hasta donde yo sé, no hay forma de saber que este es el caso, ya que está sucediendo, lo cual tiene sentido, hasta que el tiempo expire, no hay manera de saber que un segundo clic está o no llegando.
Puede verificar que WM_LBUTTONDOWN no haya sido llamado más de una vez antes de WM_LBUTTONUP. En la práctica, Windows hace esto por usted, ya que si obtiene un WM_LBUTTONDBCLK, no suele obtener un WM_LBUTTONUP.
eso es un poco complicado.
Detectaba el combo WM_LBUTTONDOWN y WM_LBUTTONUP, almacenaba ese evento en algún lugar y establecía un tiempo de espera por un segundo más o menos. Si no hay un WM_LBUTTONDBCLK durante ese tiempo de espera, entonces tiene un solo clic.
Esto podría implicar que necesitas tener otro hilo ejecutándose, pero creo que podrías lograrlo con un hilo.
Creo que la solución es iniciar un temporizador después del primer clic y luego verificar el tiempo transcurrido después del próximo clic inmediato, esto le dirá si está a un solo clic o doble clic.