Hit testing problem
-
I need to write a program which can draw rectangle by mouse. User can draw a rectangle by click left mouse button and drag mouse, when user release left mouse button, rectangle will be drawn. I can draw rectangle, but now I want to check when I move mouse, program can show me the mouse is inside a rectangle or not. I use an RectangleArray which inherits from CollectionBase to store all drawn rectangle. In mouse move method, I loop through this array and use Contains method of Rectangle class to check the mouse inside or not. But I don't understand while I only can check the position of mouse if it is inside the first rectangle I drawn (label4 only change value when I move the mouse inside the first rectangle). If I show a message box, label4 can change its value when I move the mouse inside any rectangle.
private void picImage_MouseMove(object sender, MouseEventArgs e)
{Point mousePoint = new Point(e.X, e.Y); foreach (Rectangle rect in rects) { if (rect.Contains(mousePoint)) { label4.Text = "In rect"; //MessageBox.Show(label4.Text); break; } else { label4.Text = "Not in rect"; } }
}
Can anybody help me? Thanks a lot! I'm ... a fan of Manchester United a fan of Ozzy Osbourne a King of Nothing
-
I need to write a program which can draw rectangle by mouse. User can draw a rectangle by click left mouse button and drag mouse, when user release left mouse button, rectangle will be drawn. I can draw rectangle, but now I want to check when I move mouse, program can show me the mouse is inside a rectangle or not. I use an RectangleArray which inherits from CollectionBase to store all drawn rectangle. In mouse move method, I loop through this array and use Contains method of Rectangle class to check the mouse inside or not. But I don't understand while I only can check the position of mouse if it is inside the first rectangle I drawn (label4 only change value when I move the mouse inside the first rectangle). If I show a message box, label4 can change its value when I move the mouse inside any rectangle.
private void picImage_MouseMove(object sender, MouseEventArgs e)
{Point mousePoint = new Point(e.X, e.Y); foreach (Rectangle rect in rects) { if (rect.Contains(mousePoint)) { label4.Text = "In rect"; //MessageBox.Show(label4.Text); break; } else { label4.Text = "Not in rect"; } }
}
Can anybody help me? Thanks a lot! I'm ... a fan of Manchester United a fan of Ozzy Osbourne a King of Nothing
Windows - including controls (which are client windows) - are only sent messages such as mouse move messages when the mouse is over them or the mouse is captured (I'll get to that in a second). Forms that parent controls such as your label can receive mouse events for their children, which actually happens anyway since the parent control will dispatch messages to their children. This is why the label only knows about mouse movement within its client region. In order to be notified when the mouse moves outside of the control you need to capture the mouse. See http://msdn2.microsoft.com/en-us/library/ms171545(en-US,VS.80).aspx[^] for general information, making note of the following:
Only the foreground window can capture the mouse. When a background window attempts to capture the mouse, the window receives messages only for mouse events that occur when the mouse pointer is within the visible portion of the window. Also, even if the foreground window has captured the mouse, the user can still click another window, bringing it to the foreground. When the mouse is captured, shortcut keys do not work.
Try the following sample:
public class Form1 : Form { private System.Windows.Forms.Label label1; private System.Windows.Forms.CheckBox checkBox1;
public Form1()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// label1
//
this.label1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.label1.Location = new System.Drawing.Point(33, 98);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(221, 33);
this.label1.TabIndex = 0;
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.label1.MouseLeave += new System.EventHandler(this.label1_MouseLeave);
this.label1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.label1_MouseMove);
//
// checkBox1
// -
Windows - including controls (which are client windows) - are only sent messages such as mouse move messages when the mouse is over them or the mouse is captured (I'll get to that in a second). Forms that parent controls such as your label can receive mouse events for their children, which actually happens anyway since the parent control will dispatch messages to their children. This is why the label only knows about mouse movement within its client region. In order to be notified when the mouse moves outside of the control you need to capture the mouse. See http://msdn2.microsoft.com/en-us/library/ms171545(en-US,VS.80).aspx[^] for general information, making note of the following:
Only the foreground window can capture the mouse. When a background window attempts to capture the mouse, the window receives messages only for mouse events that occur when the mouse pointer is within the visible portion of the window. Also, even if the foreground window has captured the mouse, the user can still click another window, bringing it to the foreground. When the mouse is captured, shortcut keys do not work.
Try the following sample:
public class Form1 : Form { private System.Windows.Forms.Label label1; private System.Windows.Forms.CheckBox checkBox1;
public Form1()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// label1
//
this.label1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.label1.Location = new System.Drawing.Point(33, 98);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(221, 33);
this.label1.TabIndex = 0;
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.label1.MouseLeave += new System.EventHandler(this.label1_MouseLeave);
this.label1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.label1_MouseMove);
//
// checkBox1
//Maybe my description has some confusion for you. Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace RFCart
{
public partial class Main : Form
{// picImage is a PictureBox control private int drawMode; private bool mouseIsInShelf; private Shelf currentShelf; private ShelfArray shelfs = new ShelfArray(); private void Main\_Load(object sender, EventArgs e) { drawMode = Constant.SHELF\_MODE; } private void picImage\_MouseDown(object sender, MouseEventArgs e) { switch (e.Button) { case MouseButtons.Left: Point mousePoint = new Point(e.X, e.Y); if (drawMode == Constant.SHELF\_MODE) { // Catch top-left point currentShelf = new Shelf(); currentShelf.StartPoint = mousePoint; } break; } } private void picImage\_MouseUp(object sender, MouseEventArgs e) { switch (e.Button) { case MouseButtons.Left: Point mousePoint = new Point(e.X, e.Y); if (drawMode == Constant.SHELF\_MODE) { // Catch bottom-right point currentShelf.EndPoint = mousePoint; // Add current shelf to array shelfs.Add(currentShelf); // Force to re-draw all shelfs picImage.Invalidate(); } break; } } private void picImage\_MouseMove(object sender, MouseEventArgs e) { Point mousePoint = new Point(e.X, e.Y); foreach (Shelf shelf in shelfs) { if (shelf.Contains(mousePoint)) { mouseIsInShelf = true; break; } else { mouseIsInShelf = false; } } } private void picImage\_Paint(object sender, PaintEventArgs e) { foreach (Shelf shelf in shelfs) { shelf.Draw(e.Graphics,