当包装控件设置捕获时,如何接收鼠标事件?
当我按下修饰键(Shift 或 Control)进行单击时,我的 WndProc 没有看到鼠标松开通知。我在没有修饰键的情况下看到它们,并且在使用修饰键时看到鼠标按下通知。
我试图跟踪我没有编写的组件中的用户操作,因此我使用 Windows 窗体 NativeWindow 包装器(包装组件)从 WndProc() 方法获取 Windows 消息。
我尝试跟踪我收到的通知,我看到的唯一线索是 WM_CAPTURECHANGED。我尝试在收到 WM_LBUTTONDOWN 消息时调用 SetCapture,但没有帮助。
不带修饰符(跳过绘制、计时器和 NCHITTEST 消息):
WM_PARENTNOTIFY
WM_MOUSEACTIVATE
WM_MOUSEACTIVATE
WM_SETCURSOR
WM_LBUTTONDOWN
WM_SETCURSOR
WM_MOUSEMOVE
WM_SETCURSOR
WM_LBUTTONUP
使用修饰符(跳过绘制、计时器和 NCHITTEST 消息):
WM_KEYDOWN
WM_PARENTNOTIFY
WM_MOUSEACTIVATE
WM_MOUSEACTIVATE
WM_SETCURSOR
WM_LBUTTONDOWN
WM_SETCURSOR (repeats)
WM_KEYDOWN (repeats)
WM_KEYUP
如果我长时间按住鼠标按钮,通常可以获得 WM_LBUTTONUP 通知,但应该可以使其更具响应性..
编辑:我尝试在感兴趣的组件外部单击control并在释放鼠标按钮之前将光标移动到其中,然后我确实收到了 WM_LBUTTONUP 通知,因此看起来该组件正在捕获鼠标按下时。当另一个窗口捕获鼠标时有什么方法可以接收该通知吗?
谢谢。
My WndProc isn't seeing mouse-up notifications when I click with a modifier key (shift or control) pressed. I see them without the modifier key, and I see mouse-down notifications with the modifier keys.
I'm trying to track user actions in a component I didn't write, so I'm using the Windows Forms NativeWindow wrapper (wrapping the component) to get Windows messages from the WndProc() method.
I've tried tracking the notifications I do get, and I the only clue I see is WM_CAPTURECHANGED. I've tried calling SetCapture when I receive the WM_LBUTTONDOWN message, but it doesn't help.
Without modifier (skipping paint, timer and NCHITTEST messages):
WM_PARENTNOTIFY
WM_MOUSEACTIVATE
WM_MOUSEACTIVATE
WM_SETCURSOR
WM_LBUTTONDOWN
WM_SETCURSOR
WM_MOUSEMOVE
WM_SETCURSOR
WM_LBUTTONUP
With modifier (skipping paint, timer and NCHITTEST messages):
WM_KEYDOWN
WM_PARENTNOTIFY
WM_MOUSEACTIVATE
WM_MOUSEACTIVATE
WM_SETCURSOR
WM_LBUTTONDOWN
WM_SETCURSOR (repeats)
WM_KEYDOWN (repeats)
WM_KEYUP
If I hold the mouse button down for a long time, I can usually get a WM_LBUTTONUP notification, but it should be possible to make it more responsive..
Edit: I've tried control-clicking outside of the component of interest and moving the cursor into it before releasing the mouse button, and then I do get a WM_LBUTTONUP notification, so it looks like the component is capturing the mouse on mouse-down. Is there any way to receive that notification when another window has captured the mouse?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
通常,当在(本机)Windows 控件上单击鼠标时,会进入某种模式跟踪循环来管理“拖动”操作。在模态循环期间,消息直接从消息队列中提取并进行处理 - 鼠标松开通知将是模态循环的终止条件之一,因此通常会在不分派的情况下使用。
您可以单击桌面上的其他位置,将鼠标移到窗口上并释放并看到单击吗?这表明某种模式代码正在被鼠标按下消息触发。
我可以想到四种可以解决这个问题的方法。
所有这些解决方案都是Windows API。不知道它们如何在托管环境中转化。
Frequently, when the mouse is clicked down on a (native) windows control, some kind of modal tracking loop is entered to manage the "drag" operation. During the duration of the modal loop messages are directly extracted from the message queue and processed - the mouse up notification would be one of the terminating conditions for the modal loop and thus typically consumed without being dispatched.
Can you click elsewhere on the desktop, move the mouse over the window and release and see the click? That would indicate some kind of modal code is being triggered on mouse-down messages.
I can think of four ways you can possibly get around this problem.
All these solutions are very windows API. No idea how they translate in the managed environment.
在您的处理程序中,当您收到 WM_LBUTTONUP 消息时,您需要检查 WPARAM 键。
http://msdn.microsoft.com/en-我们/库/ms645608%28VS.85%29.aspx
Within your handler you need to check the WPARAM key when you receive a WM_LBUTTONUP message.
http://msdn.microsoft.com/en-us/library/ms645608%28VS.85%29.aspx
如果组件捕获鼠标消息,则 WM_LBUTTONUP消息可能会绕过您的包装器并直接进入组件。
If the component captures mouse messages, the WM_LBUTTONUP message might bypass your wrapper and go directly to the component.
默认情况下,修改键和导航键保留供操作系统内部使用。默认键盘处理程序解释它们并根据需要根据它们生成适当的消息。如果控件想要直接对它们进行操作,则需要处理
WM_GETDLGCODE
消息,并且可以选择包含适当的DLGC_WANT...
标志的结果,例如DLGC_WANTALLKEYS
和DLGC_WANTARROWS
,因此密钥会作为普通消息传递到消息队列(例如,DLGC_WANTALLKEYS
将生成WM_KEYDOWN/UP
代码>消息)。Modifier and navigation keys are reserved for the OS's internal use by default. The default keyboard handler interprets them and generates appropriate messages based on them as needed. If a control wants to act on them directly, it needs to handle the
WM_GETDLGCODE
message, optionally with a result that includes the appropriateDLGC_WANT...
flags, such asDLGC_WANTALLKEYS
andDLGC_WANTARROWS
, so the keys are delivered to the message queue as normal messages (for instance,DLGC_WANTALLKEYS
will generateWM_KEYDOWN/UP
messages).使用 Application.AddMessageFilter 添加本机消息泵的处理程序。像这样的事情:
该示例并不特定于您的特定目标,但您可以对其进行修改以适应。这恰好是我最近写的一篇。
Use Application.AddMessageFilter to add a handler to the native message pump. Something like this:
That sample isn't specific to your particular goal, but you can modify it to suit. That just happened to be one I've written recently.