How can I detect a held down mouse button over a PictureBox?
Asked Answered
B

8

10

I need to fire an event when the mouse is above a PictureBox with the mouse button already clicked and held down.

Problems:

The MouseDown and MouseEnter event handlers do not work together very well.

For instance once a mouse button is clicked and held down, C# will fire the MouseDown event handler, but when the cursor moves over the PictureBox the MouseEnter event does not fire, until the mouse button is realeased.

Breastplate answered 4/10, 2008 at 2:27 Comment(0)
P
13

When the mouse is pressed down most controls will then Control.Capture the mouse input. This means that all MouseMove events are sent to the original control that captured rather than the control the mouse happens to be over. This continues until the mouse loses capture which typically happens on the mouse up.

If you really need to know when the mouse is over your control even when another control has captured mouse input then you only really have one way. You need to snoop the windows messages destined for other controls inside your application. To do that you need add a message filter ...

Application.AddMessageFilter(myFilterClassInstance);

Then you need to implement the IMessageFilter on a suitable class...

public class MyFilterClass : IMessageFilter
{
    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg == WM_MOUSEMOVE)
            // Check if mouse is over my picture box!

        return false;
    }
}

Then you watch for mouse move events and check if they are over your picture box and do whatever it is you want to do.

Poilu answered 4/10, 2008 at 3:15 Comment(0)
M
13

Mouse events

Use the MouseDown event to just detect a down press of a mouse button and set this.Capture to true so that you then get other mouse events, even when the mouse leaves the control (i.e. you won't get a MouseLeave event because you captured the mouse). Release capture by setting this.Capture to false when MouseUp occurs.

Just checking the state of the mouse

This may not be relevant, but you can check System.Windows.Control.MousePosition and see if it is in the PictureBox.ClientRectangle, then check the Control.MouseButtons static property for which buttons might be down at any time.

As in:

if  (pictureBox.ClientRectangle.Contains(pictureBox.PointToClient(Control.MousePosition)))
{
   if ((Control.MouseButtons & MouseButtons.Left) != 0)
   {
     // Left button is down.
   }
}
Megalomania answered 4/10, 2008 at 2:39 Comment(2)
Sooo close!! Clearing this.capture works for MouseLeave, but not MouseEnter ( of another PictureBox)Breastplate
I didn't fully understand what you were trying to achieve, so no, this won't work unfortunately.Megalomania
P
13

When the mouse is pressed down most controls will then Control.Capture the mouse input. This means that all MouseMove events are sent to the original control that captured rather than the control the mouse happens to be over. This continues until the mouse loses capture which typically happens on the mouse up.

If you really need to know when the mouse is over your control even when another control has captured mouse input then you only really have one way. You need to snoop the windows messages destined for other controls inside your application. To do that you need add a message filter ...

Application.AddMessageFilter(myFilterClassInstance);

Then you need to implement the IMessageFilter on a suitable class...

public class MyFilterClass : IMessageFilter
{
    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg == WM_MOUSEMOVE)
            // Check if mouse is over my picture box!

        return false;
    }
}

Then you watch for mouse move events and check if they are over your picture box and do whatever it is you want to do.

Poilu answered 4/10, 2008 at 3:15 Comment(0)
T
5

Set up a MouseMove event within the PictureBox control:

this.myPictureBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.myPictureBox_MouseMove);

Then, within your MouseMove event handler, check to see if the left mouse button (or whatever) is pressed:

private void myPictureBox_MouseMove(object sender, MouseEventArgs e)
{  
     if (e.Button == MouseButtons.Left)
         // Do what you want to do
}
Tootle answered 29/11, 2010 at 16:43 Comment(1)
Note: This is a WinForms API, not a WPF (+1 anyway!)Urethra
G
3

If you're trying to implement a drag-and-drop operation of some sort, the Drag... events (DragEnter, DragDrop etc.) on the receiving picture box are what you want to use. Basically, you start the drag operation using the DoDragDrop method of the source control, and then any control that you drag over will have its Drag... events raised.

Search "DoDragDrop" on MSDN to see how to implement this.

Guido answered 4/10, 2008 at 5:2 Comment(1)
From the sound of things, this is probably the right way to go. If the UI isn't drag-and-drop oriented, then why are we looking for mouse events that began in one control and end in another? :)Schoolhouse
O
1

You can use the Preview Events

For example say I want to detect a mousedown event on my button. The MouseDown event is not going to work because as one of the answers here, the mouse capture is sent to the main control, however what you can do is use the mouse preview event.

Here is a code example

I want to check when the Left Mouse Button is pressed on my Button, hence I use the PreviewMouseLeftButtonDown

    private void MyButton_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        // code here
    }

WPF has preview events for alot of other events, you can read about them here

Preview Events - It particular talks about Buttons and how the mouse events interacts with it, So I highly recommend you read it

Obolus answered 29/11, 2020 at 6:35 Comment(0)
N
0

The best way to move a Form based on mouse position and control relative position is similar to what Ian Campbell posted.

    private void imgMoveWindow_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            Form1.ActiveForm.Left = Control.MousePosition.X - imgMoveWindow.Left - (imgMoveWindow.Size.Width/2);
            Form1.ActiveForm.Top = Control.MousePosition.Y - imgMoveWindow.Top - (imgMoveWindow.Size.Height/2); 
        }

    }

Where imgMoveWindow is a PictureBox Control.

Bruno Ratnieks

Sniffer Networks

Nosology answered 19/5, 2011 at 15:5 Comment(0)
L
0

You should try MouseMove of the picture box instead of MouseEnter, MouseMove will normally fire regardless mouse button state.

Lackadaisical answered 15/9, 2021 at 15:47 Comment(0)
F
-1

set a flag or a state on mouse down. release it on mouse up. When on mouse over fires for the picture box check your state. Now you can detect when a person is dragging something.

Footless answered 4/10, 2008 at 2:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.