Внедрение мышиного ввода в приложениях WPF
Я работал над внедрением ввода в приложение WPF. Что делает этот проект сложным, так это то, что мне нужно иметь возможность вводить данные в приложение, даже если оно работает в фоновом режиме (то есть фокус фокусируется на другом приложении). Поэтому использование функции SendInput() исключено.
Пока у меня работает клавиатурный ввод, но у меня проблемы с вводом мышью.
Я использовал Spy++ для наблюдения за сообщениями окна, которые отправляются в окно WPF, когда я физически нажимаю кнопку мыши. Затем я просто создаю эти же сообщения мыши (такие как WM_LBUTTONDOWN
а также WM_LBUTTONUP
) вручную и отправьте их явно в окно WPF для эмуляции ввода с помощью мыши.
К сожалению, это не работает должным образом (даже когда я для целей тестирования установил окно WPF в качестве окна переднего плана).
Я добавил кнопку в мое тестовое окно WPF, которое при нажатии отображает окно сообщения. Впрочем, введение соответствующих сообщений мыши, когда я вручную расположил курсор над кнопкой, не вызывает нажатия кнопки (т.е. событие clicked не запускается платформой WPF).
Если я добавлю обработчик для щелчков мыши в реальном диалоговом окне (клиентской области), этот обработчик будет вызван, если я наведу курсор на само диалоговое окно и вставлю те же оконные сообщения, что и раньше:
this.MouseLeftButtonDown += WndMouseDown;
public void WndMouseDown(object sender, EventArgs e)
{
...
}
Как ни странно, если я изменяю режим нажатия кнопки на "Нажатие" (то есть считается, что нажатие на кнопку мыши нажато, а не на мышь вверх по умолчанию), событие нажатия кнопки теперь вызывается, когда я внедряю те же сообщения, что и раньше. (Стоит упомянуть, что обработчик из приведенного выше примера корректно запускает как нажатия, так и падения мыши, поэтому кажется, что среда WPF успешно обрабатывает оба сообщения.)
Кажется, что есть некоторые другие критерии, которые должны быть выполнены для того, чтобы событие щелчка мыши было запущено платформой WPF. Кто-нибудь знает, как ввод мышью внутренне обрабатывается в WPF, или почему он не интерпретирует мои сообщения мыши вверху и вниз как нажатие кнопки?
(Стоит отметить, что этот подход [отправка оконных сообщений] отлично работает на обычных окнах Win32, таких как диалоговое окно "Пуск"> "Выполнить". Разница здесь в том, что WPF имеет только одно физическое окно Win32, а остальное зависит от WPF, что означает, что все оконные сообщения отправляются в это окно верхнего уровня, а не на фактическую кнопку.)
Я искал ответ на этот вопрос, и был бы признателен за любые мысли или идеи.
3 ответа
Я настоятельно рекомендую пойти по маршруту автоматизации МАУ. Вы создаете AutomationElement по дескриптору окна. Подойдите к кнопке и вызовите ее. Я просто хотел бы знать, как вам удалось заставить работать клавиатуру. В настоящее время я пытаюсь решить проблему обратного. Как получить окно WPF (мне удалось получить его с помощью вызовов Win32), чтобы отвечать на сообщения виртуальной клавиатуры. Я зарегистрировал ++ шпионские сеансы в рассматриваемом окне и повторил его ввод без успеха.
Для этого используйте UI Automation - попытка вручную имитировать ввод с помощью оконных сообщений является ошибкой из учебника, как попытка начать сухопутную войну против России.
Ваша стратегия в основном разумна, но чтобы отправить сообщение в окно, принадлежащее другому процессу, вы должны сначала зарегистрировать сообщение.
Вот статья, объясняющая весь бизнес. Пример кода, к сожалению, в VB, но я уверен, что это не остановит вас.