(11-12-2023, 20:32)guizans escribió: Hombre Shell, que menos que compartir ese código
No es problema, solo tienen que decirlo.
Me lié con que debería incorporar la clase. No es algo sencillo.
Por ejemplo:
¿ Debe la clase incorporar un método de escalado o es mejor escalar en el FMain y luego pasarle la imagen ya escalada a la clase ?.
Mejor escalarla en otro lugar, ejemplo en el Fmain ( solo se haría una vez ).
Mientras que si el método se hace desde la clase , cada vez que se cree una instancia de la clase, tiene que estar escalando y escalando...un rollo.
Cuando dije que era complicado, es que lo es, comencé a darle vueltas, ¿ y si creo un método estático ?. Por ahora no.
Tampoco es un código optimizado.
Comencemos con el código que solo hace uso de Pictureboxes.
Un código menor, pero no tan ideal.
Código:
' Gambas class file
'En este ejemplo crearemos los pictureboxes y lo distribuiremos por el formulario
Const ALTOBANDERA As Integer = 64
Const ANCHOBANDERA As Integer = 64
Const NUMBANDERAS As Integer = 6
Const MARGEN As Integer = 5
Public Sub Form_Open()
Dim ventanaancho As Integer
Dim ventanalto As Integer
Dim nummargenes As Integer
Dim x As Integer
Dim y As Integer
Dim unabandera As PictureBox
Dim indicesdebanderas As Integer
nummargenes = NUMBANDERAS + 1
ventanaancho = NUMBANDERAS * ANCHOBANDERA + nummargenes * MARGEN
ventanalto = NUMBANDERAS * ALTOBANDERA + nummargenes * MARGEN
With Me
.Resizable = False
.H = ventanalto
.W = ventanaancho
End With
For y = 0 To NUMBANDERAS - 1
For x = 0 To NUMBANDERAS - 1
unabandera = New PictureBox(Me) As "Banderas"
With unabandera
'La imagen es estrechada para que quepa el ancho y alto del PictureBox. La proporción de la imagen no se mantiene
.Mode = PictureBox.Fill
.Picture = Picture.Load("AguilaBicefala.jpg") 'Bandera de Albania
.Tag = indicesdebanderas
.W = ANCHOBANDERA
.H = ALTOBANDERA
.y = MARGEN + y * ALTOBANDERA + y * MARGEN
.x = MARGEN + x * ANCHOBANDERA + x * MARGEN
End With
Inc indicesdebanderas
Next
Next
End
Public Sub Banderas_MouseDown() 'Carece de Click
With Message
.Title = "Mostar Indice"
.Info("Indice: " & Last.tag)
End With
End
El código de la clase. Esta clase hereda de la clase Rect para aprovechar sus propiedades y sus métodos.
Añadimos ademas la imagen ya escalada en una propiedad.
Código:
Inherits Rect
'La clase se limita al dibujo y a las dimensiones de la misma
'Ademas se hace uso de la clase Rect que es lo "ideal" para temas de sprites.
Property imgbandera As Image Use $imgbandera
Property indice As Integer Use $indice
Public Sub _new(ialto As Integer, iancho As Integer, ix As Integer, iy As Integer, imb As Image)
Me.H = ialto
Me.W = iancho
Me.x = ix
Me.y = iy
Me.imgbandera = imb
End
Public Sub DibujarBandera()
Paint.DrawImage(Me.imgbandera, Me.x, Me.y, Me.W, Me.H)
End
Y ahora el formulario que hace uso de la misma. Parte del código del formulario se podía haber añadido a la clase.
El único problema que me encuentro es, ¿ debe la clase tenerlo ?.
Como la clase hereda de Rect, probablemente el método de detectar si se ha hecho clic sobre una imagen,
si deba contenerlo y no es difícil de hacer. Cuando digo que si la clase debe contener ese código, me refiero
que si es lo ideal en POO.
Código:
'En este ejemplo haremos uso de dibujar una serie de imagenes en un DrawingArea
Const ALTOBANDERA As Integer = 64
Const ANCHOBANDERA As Integer = 64
Const NUMBANDERAS As Integer = 6
Const MARGEN As Integer = 5
Private hImage2 As Image 'No tiene por que ser global
Private abanderas As New ClsBandera[]
Private banderascreadas As Boolean
Public Sub Form_Open()
Me.Title = "Imágenes en DrawingArea"
EscalarImagen()
CrearBanderas()
End
Public Sub EscalarImagen()
Dim hImage As Image
Dim hbrush As PaintBrush
hImage = Image.Load("AguilaBicefala.jpg")
hImage2 = New Image(ANCHOBANDERA, ALTOBANDERA)
'Partiendo de la imagen original, hImage se va a escalar la imagen y el resultado se guardará en hImage2
Paint.Begin(hImage2)
hbrush = Paint.Image(hImage)
hbrush.Scale(ANCHOBANDERA / hImage.W, ALTOBANDERA / hImage.H)
Paint.Brush = hbrush
Paint.Rectangle(0, 0, ANCHOBANDERA, ALTOBANDERA)
Paint.Fill
Paint.End
End
Public Sub CrearBanderas()
Dim i, j, x, y, cuenta As Integer
Dim nummargenes As Integer
Dim ventanaancho As Integer
Dim ventanalto As Integer
Dim unabandera As ClsBandera
nummargenes = NUMBANDERAS + 1
ventanaancho = NUMBANDERAS * ANCHOBANDERA + nummargenes * MARGEN
ventanalto = NUMBANDERAS * ALTOBANDERA + nummargenes * MARGEN
DrawingArea1.W = ventanaancho
DrawingArea1.H = ventanalto
For i = 0 To NUMBANDERAS - 1
For j = 0 To NUMBANDERAS - 1
y = MARGEN + i * ALTOBANDERA + i * MARGEN
x = MARGEN + j * ANCHOBANDERA + j * MARGEN
unabandera = New ClsBandera(ALTOBANDERA, ANCHOBANDERA, x, y, hImage2)
cuenta += 1
unabandera.indice = cuenta
abanderas.Add(unabandera)
Next
Next
'Solo cuando tegamos todos las imagenes, permitiremos que se dibuje en el DrawingArea
banderascreadas = True
End
Public Sub DrawingArea1_Draw()
Dim tbandera As ClsBandera
' Se han creado todas las imagenes ?.
If banderascreadas Then
'Adelante, dibujalas
For Each tbandera In abanderas
tbandera.DibujarBandera()
Next
Endif
End
Public Sub DrawingArea1_MouseDown()
Dim tbandera As ClsBandera
For Each tbandera In abanderas
'Se ha hecho clic en alguna imagen ? ( Rectángulo)
If tbandera.Contains(Mouse.x, Mouse.y) Then
With Message
.Title = "Mostar Indice"
.Info("Indice: " & Str(tbandera.indice))
End With
Endif
Next
End
Adjunto el ejemplo.
Ahora imaginar lo que sería crear eventos propios en el código de la clase, observadores, etc,etc.
Saludos