Click here to Skip to main content
15,918,516 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Good afternoon everyone, the truth I've made head to this, but I do not know what to do. You see, I'm trying to create a control to draw with GDI + Engineering graphics (I'm a Civil Engineer), and everything went fine until the following happens:

* When trying to make Zoom or Pan with respect to the current position of the Mouse, the first time I want to do it in the control, it somehow fails, since it always does so with respect to (0,0) of the control, to which Graphics I do a transformation of its axes, and its origin I have it in the lower left corner of the control, and with the positive Y AXIS up. However, after I have the first interaction of Zoom (MouseWheel) or Pan (MouseDown and MouseMove), it works wonders.

The code is somewhat long, so if a person could help me solve it, I'd appreciate it, it's easier if I pass the Visual Studio solution, I'm happy to help you get the solution, because it's easier if I passed them, or some contact that they give me, so we can exchange knowledge.

I know it is something short, it must be a conditional or something like that that fails, and do not need much time to find the error, because I could not.

Please, I appreciate that someone can give me a hand.

God bless you.

What I have tried:

I tried to verify in the OnPaint if when doing the TraslateTransform it is (0,0) to make a transfer to the current position of the Mouse, but still it does not work.
I have also tried to change the Order of Scale and Traslate in Paint, but neither.
VB
Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
        '
        'The current position of the Mouse is obtained.
        Me._mousePositionMove = e.Location

        'Check that you have pressed the left mouse button.
        If e.Button = MouseButtons.Left Then
            '
            'It is verified that there is no saved in the variable, a data
            'which indicates that the mouse has been pressed in the control.
            If Not Me._mousePress = True Then
                '
                'The mouse button was pressed.
                Me._mousePress = True
                '
                'Obtiene las coordenadas del puntero del Mouse cuando se presionó el Mouse.
                Me._mouseDown_Location = e.Location
                'Traslation Old Axis X.
                Me._TraslationX_Graphics_old = Me._TraslationX_Graphics
                'Traslation Old Axis Y.
                Me._TraslationY_Graphics_old = Me._TraslationY_Graphics
                '
                'In this case the drawing is only being adjusted with its Pan and Zoom.
                IsZoomPan_MouseEvent = True

                'I indicate in False the variable that indicates that the drawing fits
                'to the current screen.
                IsFitDrawingToControl_ClikButtonEvent = False

            End If
            '
        End If
        '
        'I also indicate that the reference lines of the Mouse must be drawn.
        LineasReferenciaMouse_Dibujar = True
        '        
        'The control is redrawn in your Paint event.
        Me.Invalidate()
        '
        'Invokes the MouseDown event of the control.
        MyBase.OnMouseDown(e)

    End Sub
Posted
Updated 17-Feb-18 6:06am
v3
Comments
phil.o 17-Feb-18 10:21am    
Can you at least show the method in which the actual zoom/pan takes place?

Wild guess: you could try to set the focus to the control before the first pan/zoom.
VB.NET
yourControl.Focus()
 
Share this answer
 
Comments
Harold Quintero Pineda 17-Feb-18 11:03am    
Hi friend. Nothing, not work.

I appreciate your response.

It would be too much to ask, if I send you the Visual Studio solution and the tests? Believe me it is some small thing, but I still do not solve it.

Please help me.
phil.o 17-Feb-18 11:36am    
Nope, sorry, I wouldn't accept receiving any file. As I stated in my comment to your question, could it be possible to at least see the part where you are doing the actual pan/zomm, along with the one where you do the corrdinates transform?
Harold Quintero Pineda 17-Feb-18 11:50am    
Friend, I append the code that you request.
phil.o 17-Feb-18 11:53am    
PLease never put code in comments, they are not meant for that and make it kind of unreadable. I pasted it into your question by using the green "Improve question" widget; next time, please, think about using it to qualify your question :)
Harold Quintero Pineda 17-Feb-18 12:09pm    
Sorry, I've already uploaded the most important code to verify, because the MouseWheel event is similar, but I upload it anyway so please can you help me. I know it is difficult because it is a part of the code, but if that could help me magnificently.

I think, I'm not contemplating something in the MouseDown and MouseWheel Event.
I hope you can help me.

Event MouseDown

VB
<pre>  ''' <summary>
    ''' Overwrites the MouseDown event of the base class of the control.
    ''' </summary>
    ''' <param name="e"></param>
    Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
        '
        'The current position of the Mouse is obtained.
        Me._mousePositionMove = e.Location

        'Check that you have pressed the left mouse button.
        If e.Button = MouseButtons.Left Then
            '
            'It is verified that there is no saved in the variable, a data
            'which indicates that the mouse has been pressed in the control.
            If Not Me._mousePress = True Then
                '
                'The mouse button was pressed.
                Me._mousePress = True
                '
                'Obtiene las coordenadas del puntero del Mouse cuando se presionó el Mouse.
                Me._mouseDown_Location = e.Location
                'Traslation Old Axis X.
                Me._TraslationX_Graphics_old = Me._TraslationX_Graphics
                'Traslation Old Axis Y.
                Me._TraslationY_Graphics_old = Me._TraslationY_Graphics
                '
                'In this case the drawing is only being adjusted with its Pan and Zoom.
                IsZoomPan_MouseEvent = True

                'I indicate in False the variable that indicates that the drawing fits
                'to the current screen.
                IsFitDrawingToControl_ClikButtonEvent = False

            End If
            '
        End If
        '
        'I also indicate that the reference lines of the Mouse must be drawn.
        LineasReferenciaMouse_Dibujar = True
        '        
        'The control is redrawn in your Paint event.
        Me.Invalidate()
        '
        'Invokes the MouseDown event of the control.
        MyBase.OnMouseDown(e)

    End Sub


Event MouseMove

VB
''' <summary>
''' Overwrites the MouseMove event of the base class of the control.
''' </summary>
''' <param name="e"></param>
Protected Overrides Sub OnMouseMove(e As MouseEventArgs)
    '
    'The current position of the Mouse is obtained.
    Me._mousePositionMove = e.Location

    'Check that you have pressed the left mouse button.
    If e.Button = MouseButtons.Left Then
        '
        'Change cursor icon.
         Me.Cursor = Cursors.SizeAll
        '
        'Current position of the mouse pointer
        Dim mousePosNow As PointF = e.Location
        '
        Dim deltaX, deltaY As Single
        deltaX = mousePosNow.X - Me._mouseDown_Location.X
        deltaY = (mousePosNow.Y - Me._mouseDown_Location.Y) * -1 'Change Axis Y sense.

        Me._TraslationX_Graphics = (Me._TraslationX_Graphics_old + (deltaX / Me._zoom))
        Me._TraslationY_Graphics = (Me._TraslationY_Graphics_old + (deltaY / Me._zoom))
        '
        IsZoomPan_MouseEvent = True

        IsFitDrawingToControl_ClikButtonEvent = False

    End If

    LineasReferenciaMouse_Dibujar = True

    Me.Invalidate()

    MyBase.OnMouseMove(e)

End Sub


Evento MouseWheel

VB
<pre>    ''' <summary>
    ''' Se produce cuando la rueda del mouse se mueve mientras el control tiene el foco.
    ''' Overwrites the MouseWheel event of the base class of the control.
    ''' </summary>
    ''' <param name="e"></param>
    Protected Overrides Sub OnMouseWheel(e As MouseEventArgs)

        Me._zoom_old = Me._zoom

        If e.Delta > 0 Then
            '
            Me._zoom = Math.Min((Me._zoom + _zoom_increment), _zoom_max)

        Else
            '
            Me._zoom = Math.Max((Me._zoom - _zoom_increment), _zoom_min)

        End If
        '
        Dim mousePosNow As PointF = e.Location
        '
        Dim deltaX, deltaY As Single
        deltaX = mousePosNow.X - 0
        '
        deltaY = Me.ClientRectangle.Height - mousePosNow.Y - 0
        '
        'Variable that save the value considering the zoom immediately
        'previous of the displacements that the Graphics suffered.
        Dim oldGraphicsX As Single
        Dim oldGraphicsY As Single
        oldGraphicsX = ((deltaX / Me._zoom_old))
        oldGraphicsY = ((deltaY / Me._zoom_old))
        '
       'Variable to save the new displacements that the Graphics must suffer,
       'so that the focus center of the Zoom is the current location of the Mouse.
        Dim newGraphicsX As Single
        Dim newGraphicsY As Single
        newGraphicsX = ((deltaX / Me._zoom))
        newGraphicsY = ((deltaY / Me._zoom))
        '
        Me._TraslationX_Graphics = newGraphicsX - oldGraphicsX + Me._TraslationX_Graphics
        Me._TraslationY_Graphics = newGraphicsY - oldGraphicsY + Me._TraslationY_Graphics

        Me._mousePositionMove = mousePosNow
        '
        IsZoomPan_MouseEvent = True
        '
        LineasReferenciaMouse_Dibujar = True

        IsFitDrawingToControl_ClikButtonEvent = False

        Invalidate()
        '
        'Envoca el evento MouseWheel del control.
        MyBase.OnMouseWheel(e)

    End Sub


Event Paint

VB
    ''' <summary>
    ''' Overwrites the Paint event of the base class of the control.
    ''' </summary>
    ''' <param name="e"></param>
    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        '
        Me._graphicsControl = e.Graphics
        '
        Me._graphicsControl.Clear(GraphicsControl_ClearColor)

        Me._graphicsControl.SmoothingMode = If(Me.GraphicsControl_CalidadDibujo = SmoothingMode.Invalid, SmoothingMode.AntiAlias, Me.     GraphicsControl_CalidadDibujo)
        '
        'I check if the user has decided to draw the axes of reference X-Y
        'in the bottom left corner of the control.
        If Me.EjesGlobales_Dibujar = True Then
            '
            Transforms the axes of the graph with its origin in the lower left part of the control and with   the AXIS pointing  upwards (positive)
            TransformarEjesGlobalesGraphics(Me._graphicsControl, Me.ClientRectangle.Height)
            '
            'I call the event in charge of drawing the X-Y axes.
            Me.DibujarEjesControl()
            '
        End If

        '
        'I check if the user has decided to draw the reference lines of the Mousecontrol.
        If Me.LineasReferenciaMouse_Dibujar = True Then
            '
             TransformarEjesGlobalesGraphics(Me._graphicsControl, Me.ClientRectangle.Height)
            '
            Me._graphicsControl.ScaleTransform(Me._zoom, _zoom)
            '
            Me._graphicsControl.TranslateTransform(Me._TraslationX_Graphics, Me._TraslationY_Graphics)
            '
             DibujarLineasReferenciaMouse(Me._mousePositionMove, Me._graphicsControl)
            '
        End If

        'A new instance of the Zapata Class is created.
        Dim myzapata As New MyDrawings.ZapataPlanta(2.5D, 3.5D, e.Graphics) With {
            .Contorno_Color = Color.DarkRed,
            .Contorno_GrosorPen = 0.8D,
            .Relleno_Color = Color.DarkBlue,
            .Relleno_ColorTransparencia = 25
        }

        Dim myPath As GraphicsPath = myzapata.GraphicsPath_Dibujo

        Dim myPointsAll As PointF() = myPath.PathPoints

       'Center of the customer area or the control needed to center the drawing on the screenla.
        Dim centerControl As New PointF With {
            .X = (ClientRectangle.Left + ClientRectangle.Right) / 2.0F,
            .Y = (ClientRectangle.Bottom + ClientRectangle.Top) / 2.0F
        }

'        'First, I verify that the drawing you want to make in the Graphics
         'want to adjust to the current size of the control and in the center of it.
        If Me.IsFitDrawingToControl_ClikButtonEvent = True Then

            TransformarEjesGlobalesGraphics(Me._graphicsControl, Me.ClientRectangle.Height)

            'The coordinates of the World are transformed, for which the Graphics previously has a matrix of Transformation
             'to coordinates of the page, the points that my drawing contains or Path to show.
            _graphicsControl.TransformPoints(CoordinateSpace.Page, CoordinateSpace.World, myPointsAll)

            'Drawing on the X axis and Y, Centro is obtained with the sum of the minimum and maximum coordinate in the
             'axis, divided between two. These coordinates are already converted to page coordinates.
            Dim centerDibujo As New PointF With {
                .X = (myPointsAll.Min(Function(x) x.X) + myPointsAll.Max(Function(x) x.X)) / 2.0F,
                .Y = (myPointsAll.Min(Function(y) y.Y) + myPointsAll.Max(Function(y) y.Y)) / 2.0F
            }

             _graphicsControl.TranslateTransform(-centerDibujo.X, -centerDibujo.Y, MatrixOrder.Append)

            Dim scaleRatioPage As Single
            scaleRatioPage = Math.Min((ClientRectangle.Width - 30) / myPath.GetBounds.Width, (ClientRectangle.Height - 30) / myPath.GetBounds.Height)

        
            _graphicsControl.ScaleTransform(scaleRatioPage, scaleRatioPage, MatrixOrder.Append)


            _graphicsControl.TranslateTransform(centerControl.X, centerControl.Y, MatrixOrder.Append)

      
            _graphicsControl.FillPath(myzapata.Brush_RellenoZapata, myPath)
            _graphicsControl.DrawPath(myzapata.Pen_ContornoZapata(CDec(scaleRatioPage)), myPath)

            '
             'If the user is using Mouse events, he means
             'who is wanting to make Zoom or Pan.
        ElseIf Me.IsZoomPan_MouseEvent = True Then

            '
             TransformarEjesGlobalesGraphics(Me._graphicsControl, Me.ClientRectangle.Height)

            Dim scaleRatioPage As Single
            scaleRatioPage = Math.Min((ClientRectangle.Width - 30) / myPath.GetBounds.Width, (ClientRectangle.Height - 30) / myPath.GetBounds.Height)

            _graphicsControl.TranslateTransform(Me._TraslationX_Graphics * _zoom, Me._TraslationY_Graphics * _zoom)

             _graphicsControl.ScaleTransform(scaleRatioPage * _zoom, scaleRatioPage * _zoom)

            _graphicsControl.FillPath(myzapata.Brush_RellenoZapata, myPath)
            _graphicsControl.DrawPath(myzapata.Pen_ContornoZapata(CDec(scaleRatioPage * _zoom)), myPath)

        End If

        MyBase.OnPaint(e)
        '
    End Sub
 
Share this answer
 
v2
Comments
phil.o 17-Feb-18 14:32pm    
I cannot spot where the culprit could be. At that point, only a torough debugging session could allow spotting it. Have you tried to put a breakpoint in your event handlers and check what the variables hold?
If that does not work on the first interaction, it means that, somehow one or several of your global variables are not set to what it/they should be set. As you set them in your event handlers, I suspect the original value must be zero. Perhaps try to initialize these values to something meaningful? Or, try to emulate a fake interaction straight after the form has been loaded, so that these global variables are set to their proper initial values?
And, please, next time do not bring further details in an answer, but rather improve your question itself with relevant code :)
Harold Quintero Pineda 17-Feb-18 17:22pm    
Thank you very much for your appreciation partner.

I know that the error is in the MouseDown, because the _TraslationX_Graphics and _TraslationY_Graphics variables, always by default, are worth zero (0). Then, when pressing the ButtonLeft in the MouseDown, what it does is that the drawing is run to the origin (0,0), only how much I interact with the drawing for the first time, but later if it works.

Now, how could I take this condition into account in that MouseDown event?
phil.o 17-Feb-18 18:04pm    
It's late now; I'll have a look at that on tomorrow morning.
Kindly.
Harold Quintero Pineda 17-Feb-18 18:24pm    
Magnificent, thank you for your enthusiasm in helping me, I'm really very grateful.
Have a good night.
phil.o 18-Feb-18 5:24am    
Have you tried to put a breakpoint in your mouse down event handler? You say that the variables have default value zero; what should they equal instead? Maybe try to initialize them to the center of the control (control.Width / 2, control.height / 2). This would allow to begin with a default pan/zoom origin at the center of the control rather than at the edge.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900