Hey guys, Im having a problem when trying to detect mouse clicks inside a function.

Heres some code, and hopefully you can see what it's doing as its really confusing trying to explain.

Sub ImageFollow(e As System.Windows.Forms.MouseEventArgs, myImage As System.Drawing.Image)
            Dim pBox As New PictureBox
            While TimerLeft
                pBox.Image = myImage
            pBox.Parent = PictureBox1
                pBox.Size = New System.Drawing.Size(64, 64)
                Me.PictureBox1.SizeMode = PictureBoxSizeMode.CenterImage
                'DebugTest(TimerLeft)
                Select Case MouseButtons
                    Case Windows.Forms.MouseButtons.Left
                        '    Timer = False
                        'Case Else
                        'Call DebugTest("case else")
                        pBox.Top = MousePosition.Y
                        pBox.Left = MousePosition.X
                        Refresh()

                End Select

            End While
    End Sub

TimerLeft is a Global variable, I cant find anyway of not using one.

I also have a TimerTick event that (attempts) to check if mouse button is up or down.

Whats happening is the Form loads, then I try to click/ drag a button, it clicks, then nothing, click again, shows image, it follows but now it wont detect a MouseUp event. So I esentially cant detect when to stop.

Hi Doogledue123, I'm fairly new to all of this but I think you need to handle the event like so:

Sub ImageFollow(e As System.Windows.Forms.MouseEventArgs, myImage As System.Drawing.Image)Handles Me.MouseDown

Hi Doogledue123, I'm fairly new to all of this but I think you need to handle the event like so:

Sub ImageFollow(e As System.Windows.Forms.MouseEventArgs, myImage As System.Drawing.Image)Handles Me.MouseDown

Heey Struugie, I did try that, and although that looks correct, It wont build.

"Method 'Public Sub ImageFollow(e As System.Windows.Forms.MouseEventArgs, myImage As System.Drawing.Image)' cannot handle event 'Public Event MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs)' because they do not have a compatible signature."

I told you exactly what I was trying to accomplish, but for those who dont read it all the way through, or who dont understand it, I will explain further.

When a Button is clicked/held (into a drag), based on the Button, it sends a variable 'myImage' to ImageFollow with the Resource Path to set the image of the PictureBox that gets created on Button click/held. That PictureBox that was just created (pBox) will become visible and follow the mouse, aslong as it is inside PictureBox1. PictureBox1 is created in the form (not programmed in like pBox).

At runtime, to get pBox to become visible and follow the mouse, You need to click the Button twice, its as if it gets into ImageFollow, stops before the While, and then when I click again it enters the While.

After it gets past this step, you can let go of the mouse buttons, and do whatever, but the only way to get pBox to stop following, is to Stop Debugging. I think it's not detecting the MouseUp event, but then again, I tried setting it so that if Right Click was clicked then it would stop, but it wouldnt even detect the right click.

Is that good? If you need more information, lemme know.

I'm not sure about how you select the image to place in "pBox", but I think this will give you the effect you are seeking.

  Private TrackedPB As PictureBox
  Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
     Handles PictureBox1.MouseDown

     If e.Button = Windows.Forms.MouseButtons.Left Then
        ' Left Button Down

        ' Using this function allows you to drag over existing
        ' PictureBoxes added to PictureBox1

        Dim loc As Point = PictureBox1Coord(sender, e)

        ' set the image however you want
        Dim pBox As New PictureBox With {.Image = My.Resources.SomeImage, _
                                         .Location = loc, _
                                         .Size = New Size(64, 64), _
                                         .BorderStyle = BorderStyle.FixedSingle, _
                                         .SizeMode = PictureBoxSizeMode.Zoom, _
                                         .Parent = PictureBox1 _
                                        }
        TrackedPB = pBox
        TrackedPB.BringToFront() 'Make sure this new PB is on top
        ' Need to wire-up the MouseDown and MouseMove Events for the 
        ' added PB to allow drag over and click
        AddHandler TrackedPB.MouseDown, AddressOf PictureBox1_MouseDown
        AddHandler TrackedPB.MouseMove, AddressOf PictureBox1_MouseMove
     End If
  End Sub

  Private Function PictureBox1Coord(ByVal sender As Object, ByVal e As MouseEventArgs) As Point
     If CType(sender, PictureBox).Equals(PictureBox1) Then
        Return e.Location
     Else
        Return PictureBox1.PointToClient(CType(sender, PictureBox).PointToScreen(e.Location))
     End If
  End Function

  Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
     If TrackedPB IsNot Nothing AndAlso e.Button = Windows.Forms.MouseButtons.Left Then
        TrackedPB.Location = PictureBox1Coord(sender, e)
     Else
        TrackedPB = Nothing
     End If
  End Sub

Not quite, It needs to be on Button1.MouseDown, as well it needs to set an image based on which button was clicked... So I click and drag Button1, it creates a picturebox following the mouse, with the image the same as that of the Button and then gets placed on MouseUp

I select the image based on which button was clicked.

Private Sub Button1_MouseDown(sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseDown
        Dim myImage As System.Drawing.Image
        myImage = My.Resources.Computer
        'Call ImageFollow(e, myImage)
    End Sub

Thats essentially how Im doing it.

If I understand correctly, you want a similar effect to that seen in dragging a control from the ToolBox to the the Form in the Visual Studio Designer, but in your case from a button to PictureBox1.

This is probably going to confuse you, but the way I would handle this is to create an application message filter to track the mousemove and LeftMouseUp messages and raise my own events for these. This allows you to move everything to the Form level. "pBox" is initially added to the form and dragged around by the mouse. On releasing the LeftMouseButton, an event is raised. The event handler for this event does a hit test of pBox's rectangle with the client rectangle of PictureBox1. If any point of pBox is in the PictureBox1's client rectangle, pBox is added. If not it is discarded. I gave you an alternate If conditon that you can swap with the one used if you only want to add pBox if the TopLeft corner is in PictureBox1's client rectangle.

  Public Class Form1

     Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        If pBoxFilter IsNot Nothing Then
           Application.RemoveMessageFilter(pBoxFilter)
           pBoxFilter = Nothing
        End If
     End Sub

     Private TrackedPB As PictureBox

     Private Sub Button1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseDown
        pBoxSetup(My.Resources.SomeImage1, e)
     End Sub

     Private Sub Button2_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button2.MouseDown
        pBoxSetup(My.Resources.SomeImage2, e)
     End Sub

     Private WithEvents pBoxFilter As PBDragNDropFilter
     Private Sub pBoxSetup(ByVal ImageToPlace As Image, ByVal e As MouseEventArgs)

        If e.Button = Windows.Forms.MouseButtons.Left Then
           Dim pBox As New PictureBox With {.Image = ImageToPlace, _
                                            .Location = Me.PointToClient(Cursor.Position), _
                                            .Size = New Size(64, 64), _
                                            .BorderStyle = BorderStyle.FixedSingle, _
                                            .SizeMode = PictureBoxSizeMode.Zoom, _
                                            .Parent = Me _
                                           }
           TrackedPB = pBox
           TrackedPB.BringToFront() 'Make sure this new PB is on top

           ' Create and add message filter
           pBoxFilter = New PBDragNDropFilter
           Application.AddMessageFilter(pBoxFilter)
        End If
     End Sub

     Private Sub pBoxFilter_MouseMove(ByVal location As Point) Handles pBoxFilter.MouseMove
        TrackedPB.Location = Me.PointToClient(location)
     End Sub

     Private Sub pBoxFilter_LButtonUp(ByVal Location As System.Drawing.Point) Handles pBoxFilter.LButtonUp
        Dim TrackedLocINPB1Coords As Point = PictureBox1.PointToClient(Location)
        Dim TrackedRectRelative As New Rectangle(TrackedLocINPB1Coords, TrackedPB.Size)

        ' Use this If condition if you only want to add pBox if the TopLeft corner
        ' is in PictureBox1

        'If PictureBox1.ClientRectangle.Contains(PictureBox1.PointToClient(Location)) Then

        If PictureBox1.ClientRectangle.IntersectsWith(TrackedRectRelative) Then
           PictureBox1.SuspendLayout()
              TrackedPB.Parent = Nothing
              TrackedPB.Location = PictureBox1.PointToClient(Location)
              TrackedPB.Parent = PictureBox1
              TrackedPB.BringToFront()
           PictureBox1.ResumeLayout()
        Else
           TrackedPB.Parent = Nothing
           TrackedPB = Nothing
        End If
        ' remove message filter
        Application.RemoveMessageFilter(pBoxFilter)
        pBoxFilter = Nothing
     End Sub

     Private Class PBDragNDropFilter
        Implements IMessageFilter

        Private Const WM_MOUSEMOVE As Int32 = &H200
        Private Const WM_LBUTTONUP As Int32 = &H202

        ''' <summary> Raised On Mouse Move</summary>
        ''' <param name="Location">Mouse Location in Screen Coordinates</param>
        Public Event MouseMove(ByVal Location As Point)

        ''' <summary> Raised On LButtonUp</summary>
        ''' <param name="Location">Mouse Location in Screen Coordinates</param>
        Public Event LButtonUp(ByVal Location As Point)

        Public Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) As Boolean Implements System.Windows.Forms.IMessageFilter.PreFilterMessage
           Select Case m.Msg
              Case WM_LBUTTONUP
                 RaiseEvent LButtonUp(Cursor.Position)
              Case WM_MOUSEMOVE
                 RaiseEvent MouseMove(Cursor.Position)
           End Select
        End Function

     End Class ' PBDragNDropFilter

  End Class
This article has been dead for over six months. Start a new discussion instead.