0
votes

I am drawing a rectangle setting x,y,width,height but seems that rectangle is drawn at different position than set. Annoying issue is that, on mouse click, I get cursor position and set a new mouse position from that. Then, mouse remains at same position like expected... However, rectangle doesn't start at same one! It is placed at another position quite far from set!

    pictureBoxImageViewer.Invalidate()

    Using g As Graphics = Graphics.FromImage(pictureBoxImageViewer.Image)

        Dim myPen As New System.Drawing.Pen(System.Drawing.Color.Red)
        myPen.DashStyle = Drawing2D.DashStyle.DashDot

        Dim testPoint As Point = New Point(Control.MousePosition)

        g.DrawRectangle(myPen, testPoint.X, testPoint.Y, 50, 50)
        'here rectangle is drawn quite far from testPoint  

        myPen.Dispose()

        Windows.Forms.Cursor.Position = New Point(Control.MousePosition)
        'here mouse has no position change like expected. Why rectangle not if is same point??

    End Using

    pictureBoxImageViewer.Refresh()

UPDATE: tested different methods using pointToClient and pointToScreen but not a solution... Focused on mouse, when I set

Windows.Forms.Cursor.Position = New Point(Control.MousePosition)

cursor remains at same position. Then, pointToScreen should do the same, right? and is not! cursor is been repostioned at another coordinates. Weird...

Windows.Forms.Cursor.Position = New Point(Me.PointToScreen(Control.MousePosition))

UPDATE 2: I made a simple exercise to explain the problem...

Private Sub PictureBox1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.Click

        Dim testPoint As Point = New Point(Cursor.Position)

        Dim testPointScreen As Point = New Point(Me.PointToScreen(Cursor.Position))

        Dim testPointClient As Point = New Point(Me.PointToClient(Cursor.Position))

        MsgBox(testPoint.X.ToString + " " + testPoint.Y.ToString + " " + Control.MousePosition.X.ToString + " " + Control.MousePosition.Y.ToString)

        MsgBox(testPointScreen.X.ToString + " " + testPointScreen.Y.ToString + " " + testPointClient.X.ToString + " " + testPointClient.Y.ToString)

    End Sub

then I'd got from first MsgBox: "367 265 367 265" second MsgBox: "525 347 209 143"

so, pointToScreen or pointToClient should be the same as Cursor.Position and returns different coordinates. Getting more points, y can assume that offset is always the same between pointToScreen (113 50), pointToClient (-113 -50) and expected point.

1
look at the PointToClient and PointToScreen Methods. Not sure if this is your problem but give it at tryMark Hall

1 Answers

1
votes

In looking at your code I see that you are using Control.MousePosition this will give you the Mouse Position in Screen Coordinates

from MSDN Documentation

The MousePosition property returns a Point that represents the mouse cursor position at the time the property was referenced. The coordinates indicate the position on the screen, not relative to the control, and are returned regardless of whether the cursor is positioned over the control. The coordinates of the upper-left corner of the screen are 0,0.

In order to draw to your rectangle in the proper position you will need to use the Control.PointToClient Method of your PictureBox, So you will need to do something like this

Dim testPoint As Point = New Point(pictureBoxImageViewer.PointToClient(Control.MousePosition))
g.DrawRectangle(myPen, testPoint.X, testPoint.Y, 50, 50)

per my comment below you are using the form's PointToClient Method which will still be wrong since it is using the x,y coordinates from the form. The PointToClient Method is part of the Control Class therefore the PictureBox has one also. That is one that you need to be using.

Modified example based on OP's update.

Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
    Dim testPoint As Point = New Point(Cursor.Position)
    Dim testPointScreen As Point = New Point(Me.PointToScreen(Cursor.Position))
    'Note the fact that I am using the PictureBox's PointToClient Method since that is the
    'Control that you are wanting to draw in.
    Dim testPointClient As Point = New Point(PictureBox1.PointToClient(Cursor.Position))


    MsgBox(testPoint.X.ToString + " " + testPoint.Y.ToString + " " + Control.MousePosition.X.ToString + " " + Control.MousePosition.Y.ToString)

    MsgBox(testPointScreen.X.ToString + " " + testPointScreen.Y.ToString + " " + testPointClient.X.ToString + " " + testPointClient.Y.ToString)
End Sub