Mi idea es poder hacer zoom con uso de GDI+ en un dibujo que estoy haciendo de prueba, cuyo centro de enfoque sea la posición del mouse, el cual aplica el zoom por medio de un ScaleTransform en el evento MouseWheel del Picture. Lo que pasa actualmente es lo siguiente:
1. Ubicado en un punto del PictureBox con el cursor, hago uso del Scrool, con el fin de acercar o alejar el dibujo con respecto al punto de posición del mouse.
2. Luego de que se activa el evento MouseWheel, si se aleja o acerca el dibujo, pero lo que hace es alejarse del punto de foco(que corresponde a la posición del mouse).
La idea es, como clos programas CAD por ejemplo, es que se acerque o aleje el dibujo respecto a la posición del mouse, es decir, que la posición del mouse sea el centro de foco de la ampliación o reducción de lo dibujado. ¿Cómo puedo solucionar esto?.
El código que tengo actualmente es el siguiente:
Código
Option Strict On Option Explicit On Imports System.ComponentModel Imports System.Text Imports System.Drawing Imports System.Drawing.Drawing2D Partial Public Class Form1 Shared Sub New() DevExpress.UserSkins.BonusSkins.Register() DevExpress.Skins.SkinManager.EnableFormSkins() End Sub Public Sub New() InitializeComponent() 'Me.pe_dibujo.Properties.AllowZoomOnMouseWheel = DevExpress.Utils.DefaultBoolean.True ' Me.pe_dibujo.Properties.ZoomingOperationMode = DevExpress.XtraEditors.Repository.ZoomingOperationMode.MouseWheel End Sub Private Sub RadioGroup1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles rg_unidades.SelectedIndexChanged 'Se verifica cual es el sistema de unidades seleccionado. Select Case rg_unidades.SelectedIndex 'Caso pixeles. Case 0 'Se describe el dibujo y relación de dibujo. lbl_comentario.Text = "Rectángulo de 50 x 50 pixeles" & Environment.NewLine & "en la posición (50,50)" & Environment.NewLine & "La regla mayor es de 50 pixeles." 'Caso pulgadas. Case 1 'Se describe el dibujo y relación de dibujo. lbl_comentario.Text = "Rectángulo de 1 x 1 pulgada" & Environment.NewLine & "en la posición (1,1)" & Environment.NewLine & "La regla mayor está cada pulgada." 'Caso centímetros. Case 2 'Se describe el dibujo y relación de dibujo. lbl_comentario.Text = "Rectángulo de 1 x 1 centímetro" & Environment.NewLine & "en la posición (1,1)" & Environment.NewLine & "La regla mayor está cada centìemtro." End Select 'Se actualiza el dibujo. pe_dibujo.Invalidate() End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 'Al cargar el formulario se selecciona el sistema de unidades en Pixel por defecto. 'Se envìa la selecciòn activando el control. rg_unidades.SelectedIndex = 1 rg_unidades.Select() End Sub Private Sub pe_dibujo_Paint(sender As Object, e As PaintEventArgs) Handles pe_dibujo.Paint ' 'Variables para trabajar con el dibujo. Dim Rectangulo, Rectangulo2 As Rectangle Dim pincel_ancho_mm As Pen Dim pincel_acotar_mm As Pen Dim largo_linea_regla As Decimal Dim tickStep As Single Dim tickSize As Single Dim counter As Integer Dim marcas_principales_regla As Single Const ticks As String = "1424142414241" ' Se limpia el contenido dibujando previamente en el control. e.Graphics.Clear(Color.White) '---Se verifica que el sistema de unidades sea el Pixel. If (rg_unidades.SelectedIndex = 0) Then ' 'Se dibuja un rectángulo de 50 x 50 pixeles. Ubicado en las coordenadas de ' la pàgina a 50 pixeles a la derecha e inferior de la parte superior izquierda del control. Rectangulo = New Rectangle(50, 50, 50, 50) Rectangulo.Offset(50, 50) ' 'Se dibuja un rectángulo de 50 x 50 pixeles. Ubicado en las coordenadas de ' la pàgina a 50 pixeles a la derecha e inferior de la parte superior izquierda del control. Rectangulo2 = New Rectangle(100, 50, 50, 50) 'El largo de la lìnea de la regla se harà siempre de 5 mm. Se convierte asì: '--- Largo = 5 mm*(a.Pix/Pulg)*(1 Pulg/25.4 mm) largo_linea_regla = CDec(CSng(5.0F * e.Graphics.DpiX / 25.4F)) 'Las marcas principales de la regla se haràn cada 50 pixeles de separamiento. marcas_principales_regla = 50.0F ' Se crea un pincel de dibujo de color determinado con un grosor en mm. pincel_ancho_mm = New Pen(Color.Black, CSng(0.1 * e.Graphics.DpiX / 25.4) / scale_zoom) ' ' Se crea un pincel de dibujo de color determinado con un grosor en mm para las cotas. pincel_acotar_mm = New Pen(Color.Black, CSng(0.1 * e.Graphics.DpiX / 25.4) / scale_zoom) ' '---Se verifica que el sistema de unidades sea la Pulgada. ElseIf (rg_unidades.SelectedIndex = 1) Then ' ' Se escala a unidades de página en Pulgadas. e.Graphics.PageUnit = GraphicsUnit.Inch ' ' Se crea un rectángulo de 1"x 1"( 1 pulgada cuadrada). Ubicado en las coordenadas de ' la pàgina a 1 pulgada a la derecha e inferior de la parte superior izquierda del control. Rectangulo = New Rectangle(1, 1, 1, 1) ' ' Se crea un rectángulo de 1"x 1"( 1 pulgada cuadrada). Ubicado en las coordenadas de ' la pàgina a 1 pulgada a la derecha e inferior de la parte superior izquierda del control. Rectangulo2 = New Rectangle(2, 1, 1, 1) 'El largo de la lìnea de la regla se harà siempre de 5 mm. Se convierte asì: '--- Largo = 5 m * (1 Pulg/25.4 mm) largo_linea_regla = CDec((5 / 25.4)) 'Las marcas principales de la regla se haràn cada 1 pulagada de separamiento. marcas_principales_regla = 1.0F ' ' Se crea un pincel de dibujo de color determinado con un grosor en mm. pincel_ancho_mm = New Pen(Color.Black, CSng(0.1 / 25.4) / scale_zoom) ' ' Se crea un pincel de dibujo de color determinado con un grosor en mm para las cotas. pincel_acotar_mm = New Pen(Color.Black, CSng(0.1 / 25.4) / scale_zoom) ' '---Se verifica que el sistema de unidades sea el Centímetro. Else ' ' Se usa escala unidades de la página a milímetros. Debe convertirse para centíemtros. e.Graphics.PageUnit = GraphicsUnit.Millimeter ' 'Se crea un rectángulo de 1cmx 1cm( 1 centímetro cuadrado). Ubicado en las coordenadas de ' la pàgina a 1 centímetro a la derecha e inferior de la parte superior izquierda del control. ' '***Nota: 10 mm hacen 1 cm. ' Rectangulo = New Rectangle(1 * 10, 1 * 10, 1 * 10, 1 * 10) ' ' Rectangulo2 = New Rectangle(2 * 10, 1 * 10, 1 * 10, 1 * 10) ' 'El largo de la lìnea de la regla se harà siempre de 5 mm. largo_linea_regla = 5 ' 'Las marcas principales de la regla se haràn cada 1 centímetro de separamiento. marcas_principales_regla = 1 * 10.0F ' ' Se crea un pincel de dibujo de color determinado con un grosor en mm. pincel_ancho_mm = New Pen(Color.Black, 0.1F / scale_zoom) ' ' Se crea un pincel de dibujo de color determinado con un grosor en mm para las cotas. pincel_acotar_mm = New Pen(Color.Black, 0.1F / scale_zoom) End If ' ' 'Escalamos el dibujo de acuerdo al Zoom. e.Graphics.ScaleTransform(scale_zoom, scale_zoom, MatrixOrder.Append) e.Graphics.TranslateTransform(ultimaPosicion.X, ultimaPosicion.Y) ' 'Se pinta un área de la regla, la cual siempre es de 5 mm, independientemente 'de la unidad de las coordenadas de la página.La regla se dibujarà siempre de 3" x 3" '-------------- ' 'Se crea un cepillo o pintura Brush, teniendo en cuenta que su ancho siempre 'serà de 5 mm por un largo de 3"(76.2 mm). Uno para la regla horizontal y otro para la 'regla vetical. Existen 5 tipos: SolidBrush, HatchBrush, TextureBrush,LinearGradientBrush, PathGradientBrush(personalizado). ' Dim fill_rec_horizontal As New SolidBrush(Color.LightYellow) Dim fill_rec_vertical As New SolidBrush(Color.BlanchedAlmond) 'Punto de tipo Single, de la coordenada inicial de dibujo de el pintado del rectángulo. Dim coor_ini_fill As New PointF(0, 0) ' 'Para hacer el llenado del Brush debe tenerse en cuenta que para que se visualice de forma correcta, debe 'tenerse en cuenta que al dibujar la regla en el For, se empezaràn a colocar cada (50 pix or 1" o 1 cm) des 'fasado 5 mm(ancho de la regla), por lo que para dibujar bien el Brush con un largo de 3"(independiente de la unidad de medida) 'debe tenerse en cuenta ese ancho adicional de llenado, 'y su longitud debe calcularse asì L = largo_linea_regla + largo_linea_regla*(3"*25.4mm/largo_linea_regla(5 mm)) = largo_linea_regla*(1+15.24) 'Recordar que 3" pulgadas es el largo de la regla a dibujar y que su valor en relaciones es: 'Se rellena la regla en su parte vertical. e.Graphics.FillRectangle(fill_rec_vertical, coor_ini_fill.X, coor_ini_fill.Y, (largo_linea_regla / scale_zoom), largo_linea_regla * (1 + 15.24D)) 'Se rellena la regla en su parte horizontal. e.Graphics.FillRectangle(fill_rec_horizontal, coor_ini_fill.X, coor_ini_fill.Y, largo_linea_regla * (1 + 15.24D), largo_linea_regla / scale_zoom) 'Se dibuja la lìnea de borde la regla hasta donde se hace el relleno con color del Brush. Regla vertical. e.Graphics.DrawLine(pincel_ancho_mm, largo_linea_regla / scale_zoom, largo_linea_regla / scale_zoom, largo_linea_regla / scale_zoom, largo_linea_regla * (1 + 15.24D)) 'Se dibuja la lìnea de borde la regla hasta donde se hace el relleno con color del Brush. Regla horizontal. e.Graphics.DrawLine(pincel_ancho_mm, largo_linea_regla / scale_zoom, largo_linea_regla / scale_zoom, largo_linea_regla * (1 + 15.24D), largo_linea_regla / scale_zoom) ' ' ' Dibuja las marcas principales y secundarias de la regla. For counter = 1 To ticks.Length If counter = 1 Then ' ----- Get the tick measurements. The "ticks" constant ' includes a set of "1", "2", and "4" values. "1" ' gives a full-size tick mark (for whole units), ' "2" gives a half-size tick mark, and "4" gives ' a 1/4-size tick mark. tickSize = CSng(Mid(ticks, counter, 1)) tickStep = largo_linea_regla + ((marcas_principales_regla / 4) * (counter - 1)) ' ----- Draw the horizontal ruler ticks. e.Graphics.DrawLine(pincel_ancho_mm, tickStep / scale_zoom, 0, tickStep / scale_zoom, (largo_linea_regla / tickSize) / scale_zoom) ' ----- Draw the vertical ruler ticks. e.Graphics.DrawLine(pincel_ancho_mm, 0, tickStep / scale_zoom, (largo_linea_regla / tickSize) / scale_zoom, tickStep / scale_zoom) Else ' ----- Get the tick measurements. The "ticks" constant ' includes a set of "1", "2", and "4" values. "1" ' gives a full-size tick mark (for whole units), ' "2" gives a half-size tick mark, and "4" gives ' a 1/4-size tick mark. tickSize = CSng(Mid(ticks, counter, 1)) tickStep = largo_linea_regla + ((marcas_principales_regla / 4) * (counter - 1)) ' ----- Draw the horizontal ruler ticks. e.Graphics.DrawLine(pincel_ancho_mm, tickStep, 0, tickStep, (largo_linea_regla / tickSize) / scale_zoom) ' ----- Draw the vertical ruler ticks. e.Graphics.DrawLine(pincel_ancho_mm, 0, tickStep, (largo_linea_regla / tickSize) / scale_zoom, tickStep) End If Next counter 'Se transforma el eje del sistena de coordenadas de la pàgina a las del mmundo 'desfasándolas 5.00 mm a la derecha e inferior del vèrtice superior izquierdo 'que son el eje del sistema de coordendas del dispositivo y pàgina. Esto inde- 'pendiente de las unidades de la pàgina. e.Graphics.TranslateTransform(largo_linea_regla, largo_linea_regla) ' 'Dibuja un rectángulo de un ancho determinado del pixel(siempre en mm), con 'un tamaño determinado. e.Graphics.DrawRectangle(pincel_ancho_mm, Rectangulo) ' 'Dibujo un rectangulo pegado al anterior. e.Graphics.DrawRectangle(pincel_ancho_mm, Rectangulo2) ' 'Código para dibujar una regla en el PictureBox. Dim gp As New Drawing.Drawing2D.GraphicsPath gp.AddLine(0, 0, 2, -5) gp.AddLine(0, 0, -2, -5) gp.AddLine(-2, -5, 2, -5) pincel_acotar_mm.CustomEndCap = New Drawing2D.CustomLineCap(gp, Nothing) pincel_acotar_mm.CustomStartCap = New Drawing2D.CustomLineCap(gp, Nothing) e.Graphics.DrawLine(pincel_acotar_mm, New PointF(CSng(Rectangulo.X * 0.95), Rectangulo.Y), New PointF(CSng(Rectangulo.X * 0.95), Rectangulo.Y + Rectangulo.Height)) Dim myFont As New Font("Courier", 2, FontStyle.Regular, GraphicsUnit.Millimeter, 0) e.Graphics.DrawString(Rectangulo.Height.ToString, myFont, Brushes.Black, CSng(Rectangulo.X * 0.5), CSng(Rectangulo.Y + Rectangulo.Height / 2)) ' 'Se librea el picenl de dibujo. pincel_ancho_mm.Dispose() End Sub 'Factor de aumento o disminución del zoom(10%). Dim factor_Delta_zoom As Single = 0.1 'Escala de un 100%, cuya variable será la que variará de acuerdo al MouseWheel. Dim scale_zoom As Single = 1 Private Sub pe_dibujo_Properties_MouseWheel(sender As Object, e As MouseEventArgs) Handles pe_dibujo.Properties.MouseWheel 'Verifico que el delta del cambio del Scrool haya sido positivo. If e.Delta > 0 Then ' 'En este caso aumento la escala del zoom scale_zoom += factor_Delta_zoom Else ' 'En este caso disminuyo la escala del zoom. scale_zoom -= factor_Delta_zoom ' End If ' 'Invoco el redibujado del control del PictureBox. pe_dibujo.Invalidate() ' End Sub End Class
Agradeciera mucho me pudieran guiar en este caso, porque la verdad ya no se como lograrlo.
Muchas gracias.
MOD: Imagenes adaptadas a lo permitido. Etiquetas GeSHi.