How to get control under mouse cursor? [duplicate]

2019-01-06 19:44发布

This question already has an answer here:

I have form with few buttons and I want to know what button is under cursor now.

P.S. Maybe it's duplicate, but I can't find answer to this question.

5条回答
孤傲高冷的网名
2楼-- · 2019-01-06 20:10

Have a look at GetChildAtPoint. You will have to do some extra work if the controls are contained in a container, see Control.PointToClient.

查看更多
男人必须洒脱
3楼-- · 2019-01-06 20:11

Maybe GetChildAtPoint and PointToClient is the first idea for most people. I also used it first. But, GetChildAtPoint doesn't work properly with invisible or overlapped controls. Here's my well-working code and it manages those situations.

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;
}

This will give you the control right under the cursor.

查看更多
Emotional °昔
4楼-- · 2019-01-06 20:16
// 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;
        }
    }
查看更多
一夜七次
5楼-- · 2019-01-06 20:16

What about defining an on-Mouse-over event in each button which assigns the sender button to a public variable of a button type

查看更多
爱情/是我丢掉的垃圾
6楼-- · 2019-01-06 20:23

You could do it a number of ways:

  1. Listen to the MouseEnter event of your form's controls. The "sender" parameter will tell you what control raised the event.

  2. Obtain the cursor position using System.Windows.Forms.Cursor.Location and map it to your form's coordinates using Form.PointToClient(). You can then pass the point to Form.GetChildAtPoint() to find the control under that point.

Andrew

查看更多
登录 后发表回答