窗体和控件(WM_xxx)之间的C#Windows(触摸->单击/焦点)消息 [英] C# Windows (touch -> click/focus) messages between Form and Controls (WM_xxx)

查看:117
本文介绍了窗体和控件(WM_xxx)之间的C#Windows(触摸->单击/焦点)消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个第三方开放源代码控件(真的不重要,但它是CefSharp的Chromium Web浏览器[v 43]).

I have a 3rd party open-source control (not important which one really, but its CefSharp's Chromium Web browser [v 43]).

最初,存在一个问题,如果您在控件内单击时打开了一个窗体菜单,则该菜单不会自行消失(就像控件吞没了click事件一样).

Initially, there was a problem where if a form menu was open when you clicked inside the control, the menu was not dismissing itself (as if the control was swallowing the click event).

为避免这种情况,示例应用程序建议拦截 WM_MOUSEACTIVATE ,并通过发布

To circumvent this, the sample application suggested intercepting the WM_MOUSEACTIVATE message between the form and the control, and reacting by posting a WM_NCLBUTTONDOWN back to an element on the containing form (in my case, a panel bar). This solved that issue.

但是,它创建了另一个.现在,一旦您在控件(触摸屏)内部至少触摸了3次,就无法再触摸该控件之外的元素.您必须用鼠标单击[外部元素]才能恢复重新响应触摸事件所需的焦点级别.

However, it created another. Now, once you touch inside the control (touch screen) at least 3 times, you can no longer touch an element outside of that control. You have to click [the external element] with a mouse to restore the level of focus it needs to respond to touch events again.

我发现,如果我也拦截了 WM_SETCURSOR 消息(发送给控件)并阻塞泵5毫秒(Thread.Sleep()),然后问题就消失了.

I have discovered that if I also intercept the WM_SETCURSOR message (to the control) and block the pump for 5ms (Thread.Sleep()), then the problem magically goes away.

我很想知道发生了什么事.我处于理论之间,这是一个线程/上下文问题,或者是延迟

I would love to know whats happening. I'm in between the theories that it's a threading/context issue, or delaying the WM_SETCURSOR message is allowing an adjacent message in the form to process first (which can't be true as they share the same thread).

因此,我进行了一次测试(没有5毫秒的睡眠时间),并实时记录了控件收到的所有消息和表格.在测试过程中,我用鼠标单击了面板栏(在浏览器控件上方),然后触摸(长和短)控件内部的各个区域,然后再次触摸了该栏(被忽略了).

So, I ran a test (without the 5ms sleep) and recorded all the messages received by the control and form in real time. During the test, I clicked on my panel bar (above the browser control) with the mouse, and then touched (long and short) various areas inside the control, and then touched the bar again (which was ignored).

以下是消息:

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

根据这些,第三和第四触摸打破了焦点.我们可以看到铬控件在586之后停止接收最后一堆消息.我猜想它缺少

According to these, the 3rd and 4th touches broke the focus. We can see the chromium control stopped receiving the last bunch of messages after the 586. I'm guessing its the lack of WM_PARENTNOTIFY back up to the form that's caused the issue.

我找不到有关282、581、582、583、586和587消息的任何信息.我可能会对586消息做出反应,并手动发布 WM_PARENTNOTIFY 到表单吗?我不确定快速接连接受其中两个会有什么影响?

I can't find any information on the 282, 581, 582, 583, 586 and 587 messages. I could maybe react to the 586 message, and manually post a WM_PARENTNOTIFY to the form? I'm not sure what effect receiving two of those in quick succession would do?

有人知道为什么5ms在 WM_SETCURSOR 保持这些消息的畅通吗?

Does anybody know why the 5ms sleep on on WM_SETCURSOR keeps these messages flowing?

关于此修复还有其他更好的主意吗?

Or any better ideas on the fix?

推荐答案

一旦我包含了面板控件,按钮和我能想到的所有鼠标事件,便能够发现一个模式:

Once I included the panel control, button and all mouse events I could think of, I was able to spot a pattern:

这是行之有效的:

....
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_SETCURSOR消息之后,有时会发生WM_NCLBUTTONDOWN事件(作为对WM_MOUSEACTIVATE消息的响应而发布).这似乎给人一种幻觉,即触摸事件在其原始控件的范围之外结束,因此它触发了自己一个WM_MOUSELEAVE消息.

The problem was, the WM_NCLBUTTONDOWN event (being posted as a reaction to the WM_MOUSEACTIVATE message) was sometimes happening after the next scheduled WM_SETCURSOR message. This appears to give the illusion that the touch event finished outside the bounds of its originating control, so it triggered itself a WM_MOUSELEAVE message.

通过延迟WM_SETCURSOR消息,可以确保它们以正确的顺序触发.

By delaying the WM_SETCURSOR message it ensures they fire in correct order.

我仍然对此感到困惑,因为我确定消息泵是一个单线程循环时间,将其切入每个控件的消息队列.因此,当我的Chromium控件收到WM_CURSOR消息时,通过阻止执行,我认为我正在阻止该GUI线程上存在的所有消息队列.

I am still confused by this, as I was sure the message pump is one single threaded loop time slicing its way through every control's message queue. So by blocking execution when my Chromium control received a WM_CURSOR message I thought I was blocking all message queues existing on that GUI thread.

任何人,它回答了为什么这样一个随机的修复程序"绕过了这个问题.

Anywho, it answered the question of why such a random "fix" was bypassing the problem.

这篇关于窗体和控件(WM_xxx)之间的C#Windows(触摸-&gt;单击/焦点)消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆