Подтвердить что ты не робот

Что делает WPF для захвата ввода мыши и клавиатуры?

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

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

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

Пример

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Update:

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

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