.net - tutorial - ¿Qué usa WPF para capturar la entrada del mouse y el teclado?
wpf vs windows forms (2)
WH_MOUSE_LL
globalmente (en todo el sistema) ciertos clics del mouse usando SetWindowsHookEx
y WH_MOUSE_LL
. El problema es que no funciona para las aplicaciones WPF (todas las aplicaciones WPF detectan los clics del mouse, ya sea que haya indicado o no al sistema que ignore estos clics). Ya hice una pregunta similar aquí , pero asumí que WPF usa DirectInput
lugar de los mensajes estándar de Windows para detectar la entrada. Pero lo hace?
He podido encontrar un código que pudo inyectar clics del mouse en aplicaciones WPF usando SendMessage
. Si eso es posible, entonces creo que de alguna manera significa que WPF no usa DirectInput
para la entrada del mouse. Pero entonces, ¿por qué no es posible evitar que las aplicaciones WPF detecten clics del mouse con SetWindowsHookEx
?
Aunque esta pregunta es principalmente sobre la entrada del mouse, también me gustaría saber cómo funciona para la entrada del teclado.
Ejemplo
Rápidamente he creado la siguiente solución para reproducir el extraño comportamiento de WPF. Consta de 3 proyectos:
HookTester
El proyecto de inicio, inicia automáticamente otros 2 proyectos, por lo que debe preocuparse principalmente por este. Instala el enlace del mouse cuando se inicia, y desinstala el enlace cuando cierra el formulario.WinFormsTest
Contiene un cuadro de texto con el menú contextual predeterminado donde puede probar el botón derecho del ratón. Cuando el HookTester se está ejecutando, no debería poder invocar el menú contextual con el botón derecho del ratón.Prueba de Wpf
También contiene un TextBox, con un menú contextual personalizado (aunque también podría usar el menú predeterminado), por lo que este es el lugar para probar el botón derecho del ratón. No debe poder invocar el menú de contexto (con el botón derecho del ratón) mientras se ejecuta HookTester, pero por alguna razón, el menú se mostrará de todos modos (¿Por qué?).
ADVERTENCIA: Cuando ejecute la solución, el proyecto HookTester se iniciará e instalará de inmediato el enlace para rechazar cualquier clic del botón derecho (todo el sistema). Puede desinstalar fácilmente el gancho simplemente cerrando el formulario HookTester. Prueba con precaución.
Incluso si intenta establecer el filtro, .NET Framework puede tener alguna API no documentada para poner el filtro de WPF en prioridad alta, lo que no permite que su filtro se ejecute para asegurarse de que WPF funciona correctamente.
Las ventanas WPF son las mismas que las ventanas normales y se supone que funcionan correctamente con las API de entrada preexistentes, así como con las nuevas API para que WPF funcione con el escritorio remoto y otro software similar.
Actualizar:
Windows Hook se proporcionó en la API de Windows anterior porque en ese momento los conceptos como Event Bubbling y Preview of events no estaban disponibles y para tales implementaciones, los enlaces eran útiles. WPF ya proporciona filtrado de eventos con Vista previa de eventos y una gran cantidad de eventos, y esa es la razón por la cual los ganchos no son compatibles.
Los ganchos no son una parte muy estándar de la API porque solo muy pocas aplicaciones los usan. Puede ser que pueda publicar un error en Microsoft que su filtro no permite su filtro de enlace.
- La ventana de WPF crea HwndSource (Window.CreateSourceWindow).
- HwndSource crea HwndWrapper (HwndSource.Initialize).
- HwndWrapper crea una ventana de Win32 con un procedimiento de ventana que delega los mensajes de Windows a los enlaces, especificados por HwndSource.
- Un gancho es el HwndSource.InputFilterMessage que delega los mensajes de Windows a cuatro proveedores de entrada: lápiz, mouse, teclado, comando de aplicación.
- El proveedor analiza el mensaje de Windows apropiado e invoca a InputManager para generar eventos de entrada en los elementos.
HwndMouseInputProvider procesa mensajes como WM_MOUSEMOVE, WM_LBUTTONDOWN, etc. Así que creo que no se utiliza DirectInput para manejar la entrada del mouse y el teclado.