Geeks With Blogs
Johan's Blog Perspectives on Software Engineering

From time to time I play around with some graphics programming. One thing that have trobled me several times is how to detect if the cursor is over a line (or even something more complicated like a bezier curve).  For instance, if you would want to drag the curve in figure 1 (below) you would first have to know when the mouse is over the curve.

Figure 1. A bezier curve

It turned out that it wasn't that tricky at all. Instead of using direct drawing using methods like Graphics.DrawLine or Graphics.DrawBezier the GraphicsPath comes to rescue. The following code demonstrates how to use a GraphicsPath both for drawing and for hit detection. Create a new Form in Visual Studio and paste in the following code (don't forget to hook up the MouseMove eventhandler);

public Form1()
{
    InitializeComponent();
    bgColor = this.BackColor;
}

private Color bgColor; // Original background
private GraphicsPath path = null; // Saved path for hit testing
private const float penWidth = 25;

protected override void OnResize(EventArgs e)
{
    // Enforce form to redraw the whole client area
    Invalidate();
}

protected override void OnPaint(PaintEventArgs e)
{
    // Points for a bezier
    Point[] bz = {
        new Point(50, ClientRectangle.Height-15),
        new Point(ClientRectangle.Width/8, -35),
        new Point(ClientRectangle.Width*5/8, ClientRectangle.Height - 45),
        new Point(ClientRectangle.Width*4/5, ClientRectangle.Height/2)
    };

    using (Pen p = new Pen(Color.Blue, penWidth))
    {
        p.EndCap = LineCap.ArrowAnchor;

        path = new GraphicsPath();
        path.AddBezier(bz[0], bz[1], bz[2], bz[3]);
        e.Graphics.DrawPath(p, path);
    }
}

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    if (path == null)
        return;

    Color bgOld = BackColor;
    using (Pen p = new Pen(Color.Blue, penWidth))
    {
        p.EndCap = LineCap.ArrowAnchor;
        if (path.IsOutlineVisible(e.Location, p))
        {
            BackColor = Color.Magenta;
        }
        else
        {
            BackColor = bgColor;
        }
    }

    if (bgColor != BackColor)
        Invalidate();
}

 

Posted on Thursday, June 28, 2007 2:24 AM Windows Client , Fundamentals | Back to top


Comments on this post: Mouse over line or bezier in Windows Forms

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Johan Sundström | Powered by: GeeksWithBlogs.net