Немодальное диалоговое окно WPF, размещенное в приложении Win32, не получает события клавиатуры

У меня есть диалоговое окно WPF, которое я хочу отобразить в приложении Win32 как немодальное окно. Вызов window.Show() правильно отображает окно, и все события мыши обрабатываются им должным образом, но все события клавиатуры обрабатываются родительским окном Win32, так что даже если пользователь выделил текстовое поле, любой напечатанный текст показывает в родительском окне Win32!

Кажется, это известная проблема в WinForms/WPF interop, и в этом случае она устраняется путем вызова ElementHost.EnableModelessKeyboardInterop перед отображением диалога. Это приводит к добавлению нового фильтра сообщений в цикл сообщений WinForms, чтобы события клавиатуры могли быть перехвачены и соответствующим образом направлены в диалог WPF.

К сожалению, мое хост-приложение не является приложением WinForms, поэтому у меня нет возможности позвонить EnableModelessKeyboardInterop, Есть ли способ сделать подобное в приложении Win32?

1 ответ

Вы можете пересылать сообщения с клавиатуры, но вам нужно будет выполнить работу самостоятельно.

Основная идея заключается в следующем:

  1. Как только ваше окно WPF было создано и показано, получите его HwndSource:

    HwndSource source = HwndSource.FromVisual(wnd) as HwndSource;

  2. В вашем цикле сообщений, когда вы получаете сообщение клавиатуры, HwndSource в IKeyboardInputSink и вызовите соответствующий метод.

В основном, если вы получаете WM_KEYDOWN позвони TranslateAccelerator() или если вы получите WM_CHAR ты должен позвонить TranslateChar(), Документация для IKeyboardInputSink не велик, но он определяет, какие методы обрабатывают какие сообщения. Метод вернется true если он обработал сообщение, то вы будете знать, нужно ли обрабатывать сообщение на стороне Win32 или нет.

Другие вопросы по тегам