我想捕获我的主窗体中的鼠标移动事件。尽管我可以为主窗体连接MouseEventHandler
,但当光标位于UserControl或其他任何控件上时,事件不再触发。我如何确保我始终拥有鼠标位置。如何捕获鼠标移动事件
回答
您可以使用低级别的鼠标钩子。请参阅this示例,并检查HookCallback中的WM_MOUSEMOVE消息。
您也可以使用IMessageFilter类抓老鼠事件和触发事件,以获得位置(注意:这只会位置在窗口,它不是外面):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace GlobalMouseEvents
{
public partial class Form1 : Form
{
public Form1()
{
GlobalMouseHandler gmh = new GlobalMouseHandler();
gmh.TheMouseMoved += new MouseMovedEvent(gmh_TheMouseMoved);
Application.AddMessageFilter(gmh);
InitializeComponent();
}
void gmh_TheMouseMoved()
{
Point cur_pos = System.Windows.Forms.Cursor.Position;
System.Console.WriteLine(cur_pos);
}
}
public delegate void MouseMovedEvent();
public class GlobalMouseHandler : IMessageFilter
{
private const int WM_MOUSEMOVE = 0x0200;
public event MouseMovedEvent TheMouseMoved;
#region IMessageFilter Members
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == WM_MOUSEMOVE)
{
if (TheMouseMoved != null)
{
TheMouseMoved();
}
}
// Always allow message to continue to the next filter control
return false;
}
#endregion
}
}
这很好,谢谢。我使用了您在此处发布的来源。不过,我注意到,即使鼠标没有移动,MouseMoved函数也会不断调用。当鼠标不在应用程序上时,它停止发射。 – 2013-05-28 21:10:25
@ SwDevMan81人们如何找出查找消息ID的十六进制代码的位置?我看到所有这些导入调用与User32 dll调用,我真的想知道在哪里可以找到有关此信息 – Dbl 2014-08-01 13:35:41
@AndreasMüller - [键盘通知](http://msdn.microsoft.com/en-us/library/windows/desktop/ ff468861(v = vs.85).aspx)和[鼠标通知](http://msdn.microsoft.com/en-us/library/windows/desktop/ff468877(v = vs.85).aspx) – SwDevMan81 2014-08-01 14:27:44
这是解决方案。尽管我可以用类似的方法看到另一个答案。但是自从我写了它以后,我想发布它。这里MouseMessageFilter有一个静态事件调用MouseMove,你可以从应用程序中的任何地方订阅。
static class Program
{
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.AddMessageFilter(new MouseMessageFilter());
MouseMessageFilter.MouseMove += new MouseEventHandler(OnGlobalMouseMove);
Application.Run(new MainForm());
}
static void OnGlobalMouseMove(object sender, MouseEventArgs e) {
Console.WriteLine(e.Location.ToString());
}
}
class MouseMessageFilter : IMessageFilter
{
public static event MouseEventHandler MouseMove = delegate { };
const int WM_MOUSEMOVE = 0x0200;
public bool PreFilterMessage(ref Message m) {
if (m.Msg == WM_MOUSEMOVE) {
Point mousePosition = Control.MousePosition;
MouseMove(null, new MouseEventArgs(
MouseButtons.None, 0, mousePosition.X, mousePosition.Y,0));
}
return false;
}
}
只有当wm_mousemove发送给你的应用程序(当它的一个窗口的活动状态或它的鼠标光标下),如果只有单一表单感兴趣,那么你需要检查该表单是否有效。 .btw它会在其他窗口处于活动状态时触发。并且在运行应用程序之前,您不必添加过滤器。 – TakeMeAsAGuest 2015-07-09 19:32:21
public partial class frmCaptureMouse : Form
{
[DllImport("user32.dll")]
static extern IntPtr SetCapture(IntPtr hWnd);
public frmCaptureMouse()
{
InitializeComponent();
}
private void frmCaptureMouse_MouseMove(object sender, MouseEventArgs e)
{
try
{
lblCoords.Text = e.Location.X.ToString() + ", " + e.Location.Y.ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnCapture_Click(object sender, EventArgs e)
{
try
{
SetCapture(this.Handle);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
我试图通过@ SwDevMan81提供上述solutoution。虽然它的效果很好,但我也遇到了@Randy Gamage的问题,“即使鼠标没有移动,MouseMoved函数也会被连续调用,当鼠标不在应用程序时它会停止触发。 在这无论如何是我想出了:
在窗体的构造函数:
的事件处理程序:
private void GlobalMouseHandler_MouseMovedEvent(object sender, MouseEventArgs e)
{
try
{
//Do whatever ...
}
catch { }
}
而且我稍微改变GlobalMouseHandler类:
public class GlobalMouseHandler : IMessageFilter
{
private const int WM_MOUSEMOVE = 0x0200;
private System.Drawing.Point previousMousePosition = new System.Drawing.Point();
public static event EventHandler<MouseEventArgs> MouseMovedEvent = delegate { };
#region IMessageFilter Members
public bool PreFilterMessage(ref System.Windows.Forms.Message m)
{
if (m.Msg == WM_MOUSEMOVE)
{
System.Drawing.Point currentMousePoint = Control.MousePosition;
if (previousMousePosition != currentMousePoint)
{
previousMousePosition = currentMousePoint;
MouseMovedEvent(this, new MouseEventArgs(MouseButtons.None, 0, currentMousePoint.X, currentMousePoint.Y, 0));
}
}
// Always allow message to continue to the next filter control
return false;
}
#endregion
}
我希望有人可以使用它。
这有一个很好的答案,但它调用方法两次 – 2016-08-16 08:53:44
我弄清楚为什么它调用该方法两次,因为当第一次触发事件'previousMousePosition'有一个值'x = 0; y = 0',当程序跳转到'if(previousMousePosition!= currentMousePoint)'它返回true,我只是添加一个条件来检查'previousMousePosition'是否有一个默认值并在'if'语句之前退出函数。这解决了这个问题 – 2016-08-19 01:57:38
- 1. 如何用python捕获鼠标移动?
- 2. 捕获鼠标移动SVG
- 3. 鼠标移动捕获
- 4. 捕获鼠标事件
- 5. 鼠标移动过快,以捕获事件
- 6. 如何在Dashcode小部件中捕获鼠标拖动事件?
- 7. 鼠标移动捕获(鼠标离开和鼠标输入)
- 8. 如何将鼠标移动事件转换为鼠标滚动/拖动事件
- 9. JQuery:鼠标移动事件?
- 10. X11鼠标移动事件
- 11. 鼠标移动事件
- 12. 获取鼠标坐标不断,而鼠标移动onmousedown事件
- 13. Qt鼠标移动事件没有被事件过滤器捕获
- 14. 如何在C++ Win32中捕获鼠标移动过标题栏?
- 15. Skin UIComponents如何捕捉鼠标事件?
- 16. JOGL不捕获Java鼠标事件
- 17. ç诅咒不捕获鼠标事件
- 18. Cocoa - 捕获NSStatusItem鼠标悬停事件
- 19. 捕获鼠标松开事件/窗口
- 20. 捕获鼠标事件在Python
- 21. 在C(linux)中捕获鼠标事件
- 22. Pyside QgraphicsScene无法捕获鼠标事件
- 23. 停止从水平移动鼠标光标,但仍然要捕获MouseMove事件
- 24. 鼠标向下,鼠标移动和鼠标事件的图像?
- 25. 捕捉鼠标事件
- 26. 捕捉鼠标事件
- 27. 如何捕获WindowsFormsHost控件中的鼠标单击事件?
- 28. 如何捕获控件上的所有鼠标事件?
- 29. 如何捕获C#表单应用程序的鼠标移动?
- 30. 如何在按钮上捕获鼠标移动
按照dup线程中的说明使用IMessageFilter。 – 2010-01-14 12:46:30