0
votes

I'm writing a "quick 'n dirty" image editor. The user can load an image into pbOriginal, drag a cropping square in it, and have it displayed in pbAltered. The functionality works well for my purposes.

However I'm having problems coding when the user mouses into the picturebox with the mouse button down. (Kind of like a drag event, but I'm not trying to drag anything in; I just want to capture the enter with the mouse down.) Ideally I'd like to have it start the selection process as soon as it detects entry and detects the active LMB, but nothing I've thrown at it so far seems to work.

Here are two code snippets I have. The first detects the MouseDown event, the second detects the MouseMove event. I'm looking to have something mimicking the actions of the MouseDown function with MouseEnter. (The second function is irrelevant, but I'm including it for the sake of completeness.)

Private Sub pbOriginal_MouseDown(sender As Object, e As MouseEventArgs) Handles pbOriginal.MouseDown

         If e.Button = Windows.Forms.MouseButtons.Left Then
            cropX = e.X
            cropY = e.Y
            cropPen = New Pen(Color.Red, 2)
            cropPen.DashStyle = DashStyle.DashDotDot
            Altered = Nothing
        End If
        pbOriginal.Refresh()

End Sub

Private Sub pbOriginal_MouseMove(sender As Object, e As MouseEventArgs) Handles pbOriginal.MouseMove

    Cursor = Cursors.Cross

    If pbOriginal.Image Is Nothing Then Exit Sub
    If cropX < 0 Or cropY < 0 Then Exit Sub

    If e.Button = Windows.Forms.MouseButtons.Left And e.X <= pbOriginal.Right - pbOriginal.Left And e.X >= 0 And e.Y <= pbOriginal.Bottom - pbOriginal.Top And e.Y >= 0 Then

        pbOriginal.Refresh()

        Dim OldWidth As Integer = cropWidth
        Dim OldHeight As Integer = cropHeight

        cropWidth = e.X - cropX
        cropHeight = e.Y - cropY

        'Verify that we're maintaining a square
        If cropWidth > cropHeight Then
            If cropWidth > OldWidth Then
                cropWidth = cropHeight
            Else
                cropHeight = cropWidth
            End If
        End If
        If cropHeight > cropWidth Then
            If cropHeight > OldHeight Then
                cropHeight = cropWidth
            Else
                cropWidth = cropHeight
            End If
        End If

        If cropWidth <= 0 Or cropHeight <= 0 Then
            Altered = Nothing
            btnCropNext.Enabled = False
            Exit Sub
        End If


        pbOriginal.CreateGraphics.DrawRectangle(cropPen, cropX, cropY, cropWidth, cropHeight)
        If cropWidth <> 0 And cropHeight <> 0 Then
            Dim WRatio As Double = Original.Width / pbOriginal.Width
            Dim HRatio As Double = Original.Height / pbOriginal.Height
            Dim rect As Rectangle = New Rectangle(cropX * WRatio, cropY * HRatio, cropWidth * WRatio, cropHeight * HRatio)
            'First we define a rectangle with the help of already calculated points
            Dim OriginalImage As Bitmap = New Bitmap(Original, Original.Width, Original.Height)
            'Original image
            Dim _img As New Bitmap(CInt(cropWidth * WRatio), CInt(cropHeight * HRatio)) ' for cropinf image
            Dim g As Graphics = Graphics.FromImage(_img) ' create graphics
            g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
            g.PixelOffsetMode = Drawing2D.PixelOffsetMode.Default
            g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
            'set image attributes
            g.DrawImage(OriginalImage, 0, 0, rect, GraphicsUnit.Pixel)
            Altered = _img
            btnCropNext.Enabled = True

            OriginalImage.Dispose()
        Else
            Altered = Nothing
            btnCropNext.Enabled = False
        End If

    End If
End Sub
1
That depends on what the user clicked on. Almost any control, including the form, will capture the mouse so it can reliably tell when the mouse is released again and generate the MouseUp event. The picture box is totally unaware of the mouse being moved inside of its window. You need to think this through a bit, what exactly is supposed to happen when the user clicks on something. If nothing at all then set the control's Capture back to False in the MouseDown event. - Hans Passant
The problem is that your code works after the pbOriginal_MouseDown event has fired and both cropX, cropY values are set. When the mouse down event was triggered elsewhere you can not set cropX, cropY even if you release the capture and set it to picturebox - γηράσκω δ' αεί πολλά διδασκόμε
If you want to detect when the mouse pointer enters the PictureBox then it should be fairly obvious that you need to handle the MouseEnter event. When that event is raised, you test whether the the left button is down and, if it is, you then do as you would if the MouseDown event was raised at the same location. - jmcilhinney

1 Answers

0
votes

Why dont you use MouseEnter Event , and test if the LMB if its clicked, if so make your selection progress, other wise neglect. More Info About MouseEnter http://msdn.microsoft.com/en-us/library/system.windows.forms.control.mouseenter(v=vs.110).aspx

if you dont want to use MouseEnter , in MouseMove test each picture if MouseOver and the LMB . but i think the first easier and faster to handle