Что WPF использует для захвата ввода с клавиатуры и мыши? - PullRequest
16 голосов
/ 18 февраля 2011

Я глобально (для всей системы) фильтрую определенные щелчки мыши, используя SetWindowsHookEx и WH_MOUSE_LL.Проблема в том, что он не работает для приложений WPF (все приложения WPF обнаруживают щелчки мыши независимо от того, дал ли я указание системе игнорировать эти щелчки).Я уже задавал подобный вопрос здесь , но я сделал предположение, что WPF использует DirectInput вместо стандартных сообщений Windows для обнаружения ввода.Но так ли это?

Мне удалось найти код, который смог бы вводить щелчки мыши в приложениях WPF, используя SendMessage.Если это возможно, то я думаю, что это как-то означает, что WPF не использует DirectInput для ввода мышью.Но тогда, почему невозможно запретить приложениям WPF обнаруживать щелчки мышью с помощью SetWindowsHookEx?

Хотя этот вопрос в основном касается ввода с помощью мыши, я также хотел бы знать, как он работает для ввода с клавиатуры..

Пример

Я быстро создал следующее решение для воспроизведения нечетного поведения WPF.Он состоит из 3-х проектов:

  • HookTester
    StartUp project, автоматически запускает 2 других проекта, так что вас должен в основном беспокоить этот.Устанавливает ловушку мыши при запуске и удаляет ловушку при закрытии формы.

  • WinFormsTest
    Содержит TextBox с контекстным меню по умолчанию, в котором можно проверитьправая кнопка мыши.Когда HookTester запущен, вы не сможете вызвать контекстное меню, используя правую кнопку мыши.

  • WpfTest
    Также содержит TextBox с пользовательскимконтекстное меню (хотя я мог бы также использовать меню по умолчанию), так что это снова место для тестирования правой кнопки мыши.Вы не сможете вызывать контекстное меню (используя правую кнопку мыши), пока работает HookTester, но по какой-то причине меню все равно будет отображаться (Почему ???).

ПРЕДУПРЕЖДЕНИЕ: Когда вы запустите решение, проект HookTester запустится и немедленно установит ловушку, чтобы отклонить любые щелчки правой кнопкой мыши (для всей системы).Вы можете легко удалить крюк, просто закрыв форму HookTester.Тестируйте с осторожностью.

Загрузить SO5036143.ZIP: зеркало 1 , зеркало 2

Ответы [ 2 ]

11 голосов
/ 01 марта 2011
  • Окно WPF создает HwndSource (Window.CreateSourceWindow).
  • HwndSource создает HwndWrapper (HwndSource.Initialize).
  • HwndWrapper создает окно Win32 с оконной процедурой, которая делегирует сообщения Windows хукам, указанным HwndSource.
  • Одним хуком является HwndSource.InputFilterMessage, который делегирует сообщения Windows четырем поставщикам ввода: стилус, мышь, клавиатура, команда приложения.
  • Поставщик анализирует соответствующее сообщение Windows и вызывает InputManager для создания событий ввода для элементов.

HwndMouseInputProvider обрабатывает сообщения, такие как WM_MOUSEMOVE, WM_LBUTTONDOWN и т. Д. Поэтому я думаю, что DirectInput не используется дляобрабатывать ввод с клавиатуры и мыши.

1 голос
/ 27 февраля 2011

Даже если вы попытаетесь установить фильтр, в .NET Framework может быть какой-то недокументированный API, чтобы поставить фильтр WPF с высоким приоритетом, не позволяя вашему фильтру работать вообще, чтобы убедиться, что WPF работает правильно.

Окна WPF аналогичны обычным окнам и должны корректно работать с уже существующими API ввода, а также с новыми API, чтобы заставить WPF работать с удаленным рабочим столом и другим подобным программным обеспечением.

Обновление:

Windows Hook был предоставлен в более ранних версиях Windows API, потому что в то время такие понятия, как Event Bubbling и Preview событий, были недоступны, и для таких реализаций хуки были полезны. В WPF уже предусмотрена фильтрация событий с предварительным просмотром и всплывающими событиями, поэтому перехватчики могут не поддерживаться.

Хуки не являются стандартной частью API, потому что их используют лишь очень немногие приложения. Возможно, вы можете отправить сообщение об ошибке в Microsoft, что их фильтр не позволяет использовать фильтр хуков.

...