2017-06-15 2 views
2

Win32アプリケーションで非モーダルウィンドウとして表示するWPFダイアログがあります。 window.Show()を呼び出すとウィンドウが正しく表示され、すべてのマウスイベントが正しく処理されますが、すべてのキーボードイベントは親のWin32ウィンドウによって処理されるため、ユーザーがテキストボックスにフォーカスを移動しても、親のWin32ウィンドウに表示されます。Win32アプリケーションでホストされる非モーダルWPFダイアログはキーボードイベントを受け取りません

これはWinForms/WPF interopの既知の問題であると思われ、その場合はダイアログを表示する前にElementHost.EnableModelessKeyboardInteropを呼び出すことで修正されます。これにより、キーボードイベントがインターセプトされ、WPFダイアログに適切にルーティングされるように、新しいメッセージフィルタがWinFormsメッセージループに追加されます。

残念ながら私のホストアプリケーションはWinFormsアプリケーションではないため、EnableModelessKeyboardInteropを呼び出すオプションはありません。 Win32アプリケーションで同様のことをする方法はありますか?

答えて

1

キーボードメッセージは転送できますが、自分で処理する必要があります。

次のように基本的な考え方は次のとおりです。

  1. あなたのWPFウィンドウが作成され、示されていたら、そのHwndSource取得:あなたのメッセージループで

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

  2. を、あなたが取得するたびにキーボードメッセージの場合はHwndSourceIKeyboardInputSinkにキャストし、適切な方法を呼び出します。

基本的に、あなたがWM_KEYDOWNを取得する場合、あなたはTranslateAccelerator()を呼び出す必要があります、またはあなたがWM_CHARを取得する場合、あなたはTranslateChar()を呼び出す必要があります。 IKeyboardInputSinkのドキュメントは素晴らしいわけではありませんが、どのメソッドがどのメッセージを扱うかを指定します。このメソッドはメッセージを処理した場合はtrueを返します。したがって、Win32側でメッセージを処理する必要があるかどうかを知ることができます。

+0

そのお返事ありがとうございます。私はそれが必要なようなものを考え出した。私の問題は、Win32ホストが実際にはExcelであることです:(つまり、残念ながら私はメッセージループを制御できません... – ndeslandes

+0

あなたのWPFウィンドウがいつ作成され、閉じられたか知っていれば、自分で作ることができるかもしれませんWPFウィンドウが開かれている間にWin32のメッセージループが発生します。これにより、独自のフィルタリングを追加することができます。これが残りのExcelにどのように影響するかわかりません。 – Andy

+0

ありがとうございます。危険なので、私はExcelがそれにどのように反応するかはわかりません。今のところ私はWPF Dialogモーダルを維持しています... – ndeslandes

関連する問題