
Artículo: Gráficas con Áreas Activas
Autor / Fuente: Harvey Triana
Tema: Programación General
Actualización: Febrero 1 de 1998
Descripción: Un Método para Programar Áreas Activas en Una Gráfica
Una pregunta frecuente que he visto en los News y Mailing List de Visual Basic es: ¿hay alguna forma de construir un mapa que dependiendo donde se haga clic, haga diferentes procesos?. Este articulo presenta una técnica bastante práctica y efectiva para hacer esto.
Principio Básico
Es simple, se escribe código en los eventos MouseMove, para indicar al usuario con un puntero que la área es activa, y MouseDown, donde escribiremos el código de la acción, todo limitado a un rectángulo definido por un área de coordenadas (x1,y1)-(x2, y2).
El siguiente ejemplo describe el principio con un área entre (100, 100)-(140-140) en pixeles.
Cree un Proyecto, con un Form, un PictureBox (llámalo P) y un Label. Pegue el siguiente código. Puede adicionar una imagen al Picture para que se vea mejor. En las dos áreas especificadas el puntero del Mouse cambia a una cruz. Al dar clic nos dirá algo.
------------------------------------8<------------------------------------
Private Sub Form_Load()
P.ScaleMode = vbPixels
End Sub
Private Sub P_MouseDown( _
Button As Integer, Shift As Integer, X As Single, Y As Single _
)
P.MousePointer = vbDefault
If (X >= 100 And X <= 140) And (Y >= 100 And Y <= 140) Then
MsgBox "Clic sobre área (10, 10)-(40, 40)..."
Else
MsgBox "Clic fuera del área activa..."
End If
End Sub
Private Sub P_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If (X >= 101 And X <= 140) And (Y >= 100 And Y <= 140) Then
If Not P.MousePointer = vbCrosshair Then
P.MousePointer = vbCrosshair
End If
Else
If Not P.MousePointer = vbDefault Then
P.MousePointer = vbDefault
End If
End If
Label1 = X & ", " & Y
End Sub
--------------------------------- >8------------------------------------
El Control Label es útil para que pueda observar los valores (x, y) en pixeles por donde pasa el Mouse. Cuando el Mouse pase por el área comprendida entre (100, 100)-(140, 140), cambiará su puntero a una cruz; si da clic sobre esta área se dará un mensaje.
Para más de un área activa usaría bloques ElseIf dentro de los eventos y el mismo modelo de código.
NOTA
Para usar un puntero de Mouse personalizado, use la constante vbCustom en MousePointer, agregue un Control Image con el Icono que desee, y el bloque de código sería:
If Not pic_Panorama.MousePointer = vbCustom Then
pic_Panorama.MousePointer = vbCustom
pic_Panorama.MouseIcon = Image1
End If
Método Avanzado
Bien, la técnica explicada anteriormente es efectiva para unas pocas áreas activas. Es seguida explicare como crear un procedimiento generalizado y práctico para muchas áreas activas en una aplicación dedicada.
1.Variables Requeridas. El siguiente bloque de variables es el modelo básico. La estructura puede ser modificada para agregar nuevas propiedades a cada área, p.e. un Icono de Mouse diferente para cada área, un sonido asociado, etc.
Private Type AreaActiva
x1 As Integer
x2 As Integer
y1 As Integer
y2 As Integer
Descripción As String * 64
End Type
Private AreasActivas As Integer
Private Area() As AreaActiva
Private IndexActivo As Integer
2.Código Base. El código para los eventos MouseMove y MouseDown seguirán el siguiente modelo.
Private Sub pic_Panorama_MouseMove( _
Button As Integer, Shift As Integer, X As Single, Y As Single _
)
Static i
i = 1
IndexActivo = 0
Do Until Not (IndexActivo = 0) Or i > AreasActivas
If (X >= Area(i).x1 And X <= Area(i).x2) _
And _
(Y >= Area(i).y1 And Y <= Area(i).y2) Then
IndexActivo = i
End If
i = i + 1
Loop
If IndexActivo Then
If Not pic_Panorama.MousePointer = vbCustom Then
'Implementa un cambio de Icono de Mouse personalizado
pic_Panorama.MousePointer = vbCustom
pic_Panorama.MouseIcon = Image1
'Implementa el cambio del ToolTipText
LetToolTipTex Area(IndexActivo).Descripción
End If
Else
If Not pic_Panorama.MousePointer = vbDefault Then
pic_Panorama.MousePointer = vbDefault
pic_Panorama.ToolTipText = ""
End If
End If
'Label que indica las coordenadas del puntero del mouse
lbl_Guia = X & ", " & Y
End Sub
Private Sub pic_Panorama_MouseDown( _
Button As Integer, Shift As Integer, X As Single, Y As Single _
)
If IndexActivo Then
pic_Panorama.MousePointer = vbDefault
'En un aplicación usaría Select Case IndexActivo...
MsgBox "Clic sobre: " & Area(IndexActivo).Descripción
End If
End Sub
Por supuesto, la implementación del mensaje de ToolTipText es opcional, solo se uso para demostrar la funcionalidad.
NOTA
Uso un procedimiento particular para asignar el ToolTipText. Esto se hace para que no se reasigne continuamente al mover el Mouse sobre el área activa. Una buena práctica de programación:
Private Sub LetToolTipTex(ByVal s As String)
s = RTrim(s)
If Not pic_Panorama.ToolTipText = s Then
pic_Panorama.ToolTipText = s
End If
End Sub
3.Asignando las Areas Activas. Este es un paso bastante simple, valiéndose del control Label que me indica la posición del puntero (note la línea lbl_Guia = X & ", " & Y), tóme una hoja y un lápiz, corra la aplicación, y mueva el Mouse por donde quiera.
Seleccione los contornos de las áreas que desea serán activas (señale una esquina superior y una esquina inferior aproximadas) y anote su descripción. Algunas figuras pueden tener dificultad para encasillarlas en un rectángulo, en este caso puede usar varios rectángulos para dar el contorno, y el caso será programado como único según su organización.
Procure no cruzar los rectángulos. Despues escriba un procedimiento para asignar los datos. La forma más simple, es como el ejemplo que suministro:
Private Sub AsigneAreas()
AreasActivas = 3
ReDim Area(1 To AreasActivas)
Area(1).Descripción = "Torre de Perforación"
Area(1).x1 = 199
Area(1).y1 = 11
Area(1).x2 = 214
Area(1).y2 = 132
Area(2).Descripción = "Caseta de Químicos"
Area(2).x1 = 104
Area(2).y1 = 109
Area(2).x2 = 141
Area(2).y2 = 125
Area(3).Descripción = "Laboratorio de Geología"
Area(3).x1 = 60
Area(3).y1 = 151
Area(3).x2 = 117
Area(3).y2 = 183
End Sub
Por ultimo, si lo desea puede eliminar el Control Label (y su línea en el evento MouseMove del PictureBox) que sirvió de guía para apuntar las áreas, ya no será necesario en la aplicación.

