Gráficas con Áreas
Activas
Un
Método para Programar Áreas Activas en Una Gráfica
Por Harvey Triana
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.
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
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.
- 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
- 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
- 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.
Perspectiva
Esta implementación es una fuente de ideas
para diversas aplicaciones:
- Una aplicación que al dar clic muestre
otra fotografía referente al área que se señalo, y
así sucesivamente (una visita virtual). Un ejemplo de
esto son aquellos programas multimedia para niños que
les enseñan algún idioma y ellos simplemente van
navegando por donde quieran y señalando objetos, los
cuales indican y pronuncian el nombre del objeto.
- Escribir una aplicación que muestre el
funcionamiento de una fabrica o empresa. Nuevamente las
áreas activas llevaran a otras fotografías. Seria
elegante incluir sonido tanbién.
- Crear una interfaz muy amigable y simple,
para usuarios con escasos conocimientos en manejo de
software.
- Escribir un tutor de su aplicación.
Etcétera.
 |
El
ejemplo que incluye este articulo contiene todo el
código descrito de manera que puede observar los
resultados y juzgar. Este ejemplo tiene tres áreas
activas como decribe el procedimiento AsigneAreas(). Si
quiere pase el Mouse por la las casetas y torre que se
ven en el fotografia. La imagen inicial que se muestra en
este documento corresponde a este ejemplo en ejecución.
vbAreas.zip (97k). |
|