0

私はサードパーティ製のオープンソース コントロールを持っています (どれが重要かは重要ではありませんが、CefSharp の Chromium Web ブラウザー [v 43])。

当初、コントロール内をクリックしたときにフォーム メニューが開いている場合、メニューが閉じられないという問題がありました (コントロールがクリック イベントを飲み込んでいるかのように)。

これを回避するために、サンプル アプリケーションは、フォームとコントロールの間でWM_MOUSEACTIVATEメッセージをインターセプトし、 WM_NCLBUTTONDOWNを含むフォーム (私の場合はパネル バー) の要素に戻すことで対応することを提案しました。これでその問題は解決しました。

しかし、それは別のものを作成しました。これで、コントロール (タッチ スクリーン) の内側を 3 回以上タッチすると、そのコントロールの外側の要素にタッチできなくなります。[外部要素] をマウスでクリックして、タッチ イベントに再度応答するために必要なフォーカス レベルを復元する必要があります。

WM_SETCURSORメッセージ (コントロールへの)もインターセプトし、ポンプを 5 ミリ秒ブロック (Thread.Sleep()) すると、問題が魔法のように解消されることを発見しました。

何が起こっているのか知りたいです。私は、それがスレッド/コンテキストの問題であるか、またはWM_SETCURSORメッセージを遅らせることで、フォーム内の隣接するメッセージを最初に処理できるようにするという理論の中間にいます (同じスレッドを共有するため、これは真実ではありません)。

そこで、(5 ミリ秒のスリープなしで) テストを実行し、コントロールとフォームが受信したすべてのメッセージをリアルタイムで記録しました。テスト中、パネル バー (ブラウザー コントロールの上) をマウスでクリックしてから、コントロール内のさまざまな領域に (長短を問わず) タッチしてから、もう一度バーにタッチしました (これは無視されました)。

ここに画像の説明を入力

メッセージは次のとおりです。

10/13/2015 02:37:00.295 PM  Form: WM_PARENTNOTIFY       1. [Click bar]
10/13/2015 02:37:00.295 PM  Form: WM_MOUSEACTIVATE

10/13/2015 02:37:05.458 PM  Chromium: WM_NCHITTEST      2. [Touch 1 -long]
10/13/2015 02:37:05.458 PM  Chromium: WM_NCHITTEST
10/13/2015 02:37:05.458 PM  Form: WM_PARENTNOTIFY
10/13/2015 02:37:05.458 PM  Form: 587
10/13/2015 02:37:05.458 PM  Chromium: 587
10/13/2015 02:37:05.458 PM  Chromium: WM_MOUSEACTIVATE
10/13/2015 02:37:05.458 PM  Chromium: 585
10/13/2015 02:37:05.458 PM  Chromium: WM_NCHITTEST
10/13/2015 02:37:05.458 PM  Chromium: 716
10/13/2015 02:37:05.458 PM  Chromium: WM_TOUCH  (x23)
10/13/2015 02:37:05.458 PM  Chromium: 582
10/13/2015 02:37:05.458 PM  Chromium: 581       (x22)
10/13/2015 02:37:05.674 PM  Chromium: 583
10/13/2015 02:37:05.674 PM  Chromium: 586
10/13/2015 02:37:05.674 PM  Chromium: WM_NCHITTEST
10/13/2015 02:37:05.674 PM  Chromium: WM_SETCURSOR
10/13/2015 02:37:05.674 PM  Chromium: WM_MOUSEMOVE
10/13/2015 02:37:05.674 PM  Chromium: WM_NCHITTEST
10/13/2015 02:37:05.674 PM  Form: WM_PARENTNOTIFY
10/13/2015 02:37:05.674 PM  Chromium: WM_MOUSEACTIVATE
10/13/2015 02:37:05.674 PM  Chromium: WM_SETCURSOR
10/13/2015 02:37:05.674 PM  Chromium: WM_LBUTTONDOWN
10/13/2015 02:37:05.674 PM  Chromium: WM_NCHITTEST
10/13/2015 02:37:05.674 PM  Chromium: WM_SETCURSOR
10/13/2015 02:37:05.674 PM  Chromium: WM_LBUTTONUP

10/13/2015 02:37:10.509 PM  Chromium: WM_NCHITTEST      3. [Touch 2 -long]
10/13/2015 02:37:10.509 PM  Chromium: WM_NCHITTEST
10/13/2015 02:37:10.509 PM  Form: WM_PARENTNOTIFY
10/13/2015 02:37:10.509 PM  Form: 587
10/13/2015 02:37:10.509 PM  Chromium: 587
10/13/2015 02:37:10.509 PM  Chromium: WM_MOUSEACTIVATE
10/13/2015 02:37:10.509 PM  Chromium: 585
10/13/2015 02:37:10.509 PM  Chromium: WM_NCHITTEST
10/13/2015 02:37:10.509 PM  Chromium: 716
10/13/2015 02:37:10.509 PM  Chromium: WM_TOUCH  (x27)
10/13/2015 02:37:10.509 PM  Chromium: 582
10/13/2015 02:37:10.509 PM  Chromium: 581       (x25)
10/13/2015 02:37:10.755 PM  Chromium: 583
10/13/2015 02:37:10.755 PM  Chromium: 586
10/13/2015 02:37:10.755 PM  Chromium: WM_NCHITTEST
10/13/2015 02:37:10.755 PM  Chromium: WM_SETCURSOR
10/13/2015 02:37:10.755 PM  Chromium: WM_MOUSEMOVE
10/13/2015 02:37:10.755 PM  Chromium: WM_NCHITTEST
10/13/2015 02:37:10.755 PM  Form: WM_PARENTNOTIFY
10/13/2015 02:37:10.755 PM  Chromium: WM_MOUSEACTIVATE
10/13/2015 02:37:10.755 PM  Chromium: WM_SETCURSOR
10/13/2015 02:37:10.755 PM  Chromium: WM_LBUTTONDOWN
10/13/2015 02:37:10.755 PM  Chromium: WM_NCHITTEST
10/13/2015 02:37:10.755 PM  Chromium: WM_SETCURSOR
10/13/2015 02:37:10.755 PM  Chromium: WM_LBUTTONUP

10/13/2015 02:37:25.525 PM  Chromium: WM_NCHITTEST      4. [Touch 3 -short]
10/13/2015 02:37:25.525 PM  Chromium: WM_NCHITTEST
10/13/2015 02:37:25.525 PM  Form: WM_PARENTNOTIFY
10/13/2015 02:37:25.525 PM  Form: 587
10/13/2015 02:37:25.525 PM  Chromium: 587
10/13/2015 02:37:25.525 PM  Chromium: 585
10/13/2015 02:37:25.525 PM  Chromium: WM_NCHITTEST
10/13/2015 02:37:25.525 PM  Chromium: 716
10/13/2015 02:37:25.525 PM  Chromium: WM_TOUCH  (x7)
10/13/2015 02:37:25.525 PM  Chromium: 582
10/13/2015 02:37:25.525 PM  Chromium: 581       (x5)
10/13/2015 02:37:25.586 PM  Chromium: 583
10/13/2015 02:37:25.586 PM  Chromium: 586

10/13/2015 02:37:30.440 PM  Chromium: WM_NCHITTEST      5. [Touch 4 -short]
10/13/2015 02:37:30.440 PM  Chromium: WM_NCHITTEST
10/13/2015 02:37:30.440 PM  Form: WM_PARENTNOTIFY
10/13/2015 02:37:30.440 PM  Form: 587
10/13/2015 02:37:30.440 PM  Chromium: 587
10/13/2015 02:37:30.440 PM  Chromium: 585
10/13/2015 02:37:30.440 PM  Chromium: WM_NCHITTEST
10/13/2015 02:37:30.440 PM  Chromium: 716
10/13/2015 02:37:30.440 PM  Chromium: WM_TOUCH  (x10)
10/13/2015 02:37:30.440 PM  Chromium: 582
10/13/2015 02:37:30.440 PM  Chromium: 581       (x8)
10/13/2015 02:37:30.518 PM  Chromium: 583
10/13/2015 02:37:30.518 PM  Chromium: 586

10/13/2015 02:37:35.324 PM  Form: WM_NCHITTEST          6. [Bar (i button) touch -ignored]
10/13/2015 02:37:35.324 PM  Form: WM_NCHITTEST
10/13/2015 02:37:35.324 PM  Form: WM_PARENTNOTIFY
10/13/2015 02:37:35.324 PM  Form: 587
10/13/2015 02:37:35.324 PM  Form: 282

これらによると、3 回目と 4 回目のタッチでフォーカスが外れました。クロム コントロールが 586 の後に最後の一連のメッセージの受信を停止したことがわかります。問題の原因となったフォームへのWM_PARENTNOTIFYバックアップの欠如が原因ではないかと推測しています。

282、581、582、583、586、および 587 メッセージに関する情報が見つかりません。586 メッセージに反応して、手動でWM_PARENTNOTIFYをフォームに投稿できますか? 2つ続けて受けたらどんな効果があるのか​​わからない?

WM_SETCURSORの 5 ミリ秒のスリープがこれらのメッセージを流し続ける理由を知っている人はいますか?

または、修正に関するより良いアイデアはありますか?

4

1 に答える 1

0

パネル コントロール、ボタン、および考えられるすべてのマウス イベントを含めると、パターンを見つけることができました。

これはうまくいったタッチです:

....
10/14/2015 01:00:10.263 PM  Chromium: WM_NCHITTEST
10/14/2015 01:00:10.263 PM  Chromium: WM_SETCURSOR
10/14/2015 01:00:10.263 PM  Chromium: WM_MOUSEMOVE
10/14/2015 01:00:10.263 PM  Chromium: WM_NCHITTEST
10/14/2015 01:00:10.263 PM  Form: WM_PARENTNOTIFY
10/14/2015 01:00:10.263 PM  Chromium: WM_MOUSEACTIVATE              <--
10/14/2015 01:00:10.263 PM  panelBrowserHeader: WM_NCLBUTTONDOWN    <--
10/14/2015 01:00:10.263 PM  Chromium: WM_SETCURSOR                  <--
10/14/2015 01:00:10.263 PM  Chromium: WM_LBUTTONDOWN
10/14/2015 01:00:10.263 PM  Chromium: WM_NCHITTEST
10/14/2015 01:00:10.263 PM  Chromium: WM_SETCURSOR
10/14/2015 01:00:10.263 PM  Chromium: WM_LBUTTONUP

これはそうではありませんでした:

....
10/14/2015 01:00:15.240 PM  Chromium: WM_NCHITTEST
10/14/2015 01:00:15.240 PM  Chromium: WM_SETCURSOR
10/14/2015 01:00:15.240 PM  Chromium: WM_MOUSEMOVE
10/14/2015 01:00:15.240 PM  Chromium: WM_NCHITTEST
10/14/2015 01:00:15.240 PM  Form: WM_PARENTNOTIFY
10/14/2015 01:00:15.240 PM  Chromium: WM_MOUSEACTIVATE              <--
10/14/2015 01:00:15.240 PM  Chromium: WM_SETCURSOR                  <--
10/14/2015 01:00:15.240 PM  panelBrowserHeader: WM_NCLBUTTONDOWN    <--
10/14/2015 01:00:15.240 PM  Chromium: WM_LBUTTONDOWN
10/14/2015 01:00:15.240 PM  Chromium: WM_MOUSELEAVE     

問題は、WM_NCLBUTTONDOWN イベント (WM_MOUSEACTIVATE メッセージへの反応としてポストされる) が、次にスケジュールされた WM_SETCURSOR メッセージの後に発生することがあるということでした。これは、タッチ イベントが元のコントロールの境界外で終了したように見えるため、それ自体が WM_MOUSELEAVE メッセージをトリガーしたように見えます。

WM_SETCURSOR メッセージを遅らせることで、メッセージが正しい順序で起動されるようにします。

メッセージ ポンプは、すべてのコントロールのメッセージ キューを通過する 1 つのスレッド ループ タイム スライスであると確信していたので、これにはまだ混乱しています。そのため、Chromium コントロールが WM_CURSOR メッセージを受信したときに実行をブロックすることで、その GUI スレッドに存在するすべてのメッセージ キューをブロックしていると考えました。

とにかく、なぜそのようなランダムな「修正」が問題を回避しているのかという質問に答えました。

于 2015-10-14T16:01:14.510 に答える