He estado trabajando en inyectar entrada en una aplicación WPF. Lo que hace que este proyecto sea difícil es que necesito poder inyectar la entrada en la aplicación aunque se ejecute en segundo plano (es decir, otra aplicación tiene el foco de entrada). El uso de la función SendInput() está por lo tanto fuera de la cuestión.Inyección de entrada de mouse en aplicaciones WPF
Hasta ahora, tengo la entrada del teclado funcionando pero tengo problemas para inyectar el mouse.
Utilicé Spy ++ para observar los mensajes de la ventana que se envían a la ventana de WPF cuando hago clic físicamente en el botón del mouse. Luego simplemente escribo estos mismos mensajes de mouse (como WM_LBUTTONDOWN
y WM_LBUTTONUP
) manualmente y los envío explícitamente a la ventana de WPF para emular la entrada del mouse.
Desafortunadamente, esto no funciona como se esperaba (ni siquiera cuando, para fines de prueba, configuré la ventana de WPF como ventana de primer plano).
He añadido un botón a mi ventana de prueba de WPF que, al hacer clic, muestra un cuadro de mensaje. Sin embargo, inyectar los mensajes apropiados del mouse cuando coloqué manualmente el cursor sobre el botón no hace que se haga clic en el botón (es decir, el evento cliqueado no es activado por el marco WPF).
Si agrego un controlador para clics del ratón en el cuadro de diálogo real (el área de cliente), el manejador del hace se llama si se coloco el cursor sobre el propio diálogo e inyectar los mismos mensajes de ventana como antes:
this.MouseLeftButtonDown += WndMouseDown;
public void WndMouseDown(object sender, EventArgs e)
{
...
}
Por extraño que parezca, si cambio el modo de presionar el botón para presionar (es decir, se considera presionado el mouse hacia abajo en lugar del mouse predeterminado), el evento de clic se dispara cuando inyecto los mismos mensajes que antes. (Vale la pena mencionar que el controlador del ejemplo anterior dispara correctamente tanto para mouse downs y ups, por lo que parece que el marco WPF procesa ambos mensajes con éxito.)
Parece que hay algunos otros criterios que necesitan cumplirse para que el marco de WPF active un evento con el mouse presionado. ¿Alguien sabe cómo se maneja la entrada del mouse de manera interna en WPF, o por qué no está interpretando los mensajes de mi mouse hacia arriba y hacia abajo como un clic en el botón?
(Vale la pena mencionar que este enfoque [enviar mensajes de la ventana] funciona bien en Windows Win32 normales, como el diálogo Inicio-> Ejecutar. La diferencia aquí es que WPF solo tiene una ventana física Win32 y el resto es específico de WPF , lo que significa que todos los mensajes de ventana ir a la ventana de nivel superior en lugar del botón real.)
he estado buscando altas y bajas para una respuesta a esta y apreciaría cualquier pensamientos o ideas.
Dependiendo de su requerimiento, puede valer la pena mirar Automatización de UI en lugar de intentar simular la entrada. Pero esto dependerá mucho de lo que intentes inyectar * para *: tiende a ser un elemento de control en lugar de cosas a nivel de píxel ... – itowlson
Sí, y hay diferentes niveles de Automatización de UI: http : //blogs.msdn.com/ivo_manolov/archive/2008/12/15/9223397.aspx Ya he analizado el uso de TestAPI para inyectar/automatizar la entrada, pero desafortunadamente usan SendInput() debajo del capó que simplemente inyectar la entrada directamente en el marco de WPF. – dreijer
Lo siento por necroposting, pero ahora con la fuente de referencia de .NET disponible, esto se puede consultar más a fondo https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/Primitives/ButtonBase.cs , 414 –