如何控制鼠标指针?

19

我有一个表单,其中有几个按钮,我想知道当前鼠标下面是哪个按钮。

注:也许这是重复的问题,但我找不到答案。

5个回答

32

2
+1 对于 Control.PointToClient - Rafik Bari

23

也许 GetChildAtPointPointToClient 是大多数人的第一想法。我也先用了它。但是,GetChildAtPoint 在处理不可见或重叠控件时无法正常工作。这里提供一个良好的代码,可以处理这些情况。

using System.Drawing;
using System.Windows.Forms;

public static Control FindControlAtPoint(Control container, Point pos)
{
    Control child;
    foreach (Control c in container.Controls)
    {
        if (c.Visible && c.Bounds.Contains(pos))
        {
            child = FindControlAtPoint(c, new Point(pos.X - c.Left, pos.Y - c.Top));
            if (child == null) return c;
            else return child;
        }
    }
    return null;
}

public static Control FindControlAtCursor(Form form)
{
    Point pos = Cursor.Position;
    if (form.Bounds.Contains(pos))
        return FindControlAtPoint(form, form.PointToClient(pos));
    return null;
}

这将使您在光标正下方获得控制权。


1
你可以将 GetChildAtPointSkip.Invisible 作为第二个参数添加到...中,以忽略不可见的控件。 - Adassko

5
// This getYoungestChildUnderMouse(Control) method will recursively navigate a       
// control tree and return the deepest non-container control found under the cursor.
// It will return null if there is no control under the mouse (the mouse is off the
// form, or in an empty area of the form).
// For example, this statement would output the name of the control under the mouse
// pointer (assuming it is in some method of Windows.Form class):
// 
// Console.Writeline(ControlNavigatorHelper.getYoungestChildUnderMouseControl(this).Name);


    public class ControlNavigationHelper
    {
        public static Control getYoungestChildUnderMouse(Control topControl)
        {
            return ControlNavigationHelper.getYoungestChildAtDesktopPoint(topControl, System.Windows.Forms.Cursor.Position);
        }

        private static Control getYoungestChildAtDesktopPoint(Control topControl, System.Drawing.Point desktopPoint)
        {
            Control foundControl = topControl.GetChildAtPoint(topControl.PointToClient(desktopPoint));
            if ((foundControl != null) && (foundControl.HasChildren))
                return getYoungestChildAtDesktopPoint(foundControl, desktopPoint);
            else
                return foundControl;
        }
    }

3
您可以通过以下几种方式实现:
  1. 监听窗体控件的 MouseEnter 事件。使用 "sender" 参数可知道哪个控件引发了该事件。

  2. 使用 System.Windows.Forms.Cursor.Location 获取鼠标指针位置,并使用 Form.PointToClient() 将其映射到窗体坐标系中。然后,将该点传递给 Form.GetChildAtPoint() 查找该点下方的控件。

安德鲁


1
在每个按钮中定义一个on-Mouse-over事件,将发送者按钮分配给一个公共的按钮类型变量,你觉得怎么样?

其实这不是按钮,而是第三方插件 ;) - Poma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接