Shell_NotifyIcon en Visual Basic.
Para colocar un icono en la barra de tareas de W95, junto al reloj,
se usa la funcion Shell_NotifyIcon. Este artículo explica cómo
se puede usar esta funcion y recibir los mensajes desde Visual Basic sin
necesidad de usar un control OCX.
El problema:
Visual Basic no permite capturar mensajes definidos por el usuario,
los eventos en VB son fijos. Los iconos de notificacion usan un mensaje
definido por el usuario para notificar a una ventana de los eventos del
mouse sobre el icono. Muchas veces se recurre a un control OCX especializado
para capturar los mensajes generados por el icono de notificación,
pero esto no sería necesario si se pudiera usar como mensaje de
notificacion un mensaje estandard windows que sería transformado
en evento por VB.
La solucion:
Vamos a usar un control Picture para cargar un icono y para recibir
los eventos, este control será invisible (propiedad Visible = False)
y por lo tanto no recibirá eventos del mouse, así podemos
usar un evento del mouse como evento de notificacion.
Los pasos a seguir son los
siguientes:
- Inserta un control Picture en un formulario.
- Coloca la propiedad Visible del Picture a False.
- Coloca la propiedad ScaleMode del Picture a Pixels.
- Coloca en la propiedad Picture del Picture el Icono que
vas usar.
Usaremos la propiedad hWnd y el icono del Picture
en la llamada a Shell_NotifyIcon, y usaremos el evento MouseMove
del Picture para recibir las notificaciones. (notese que el control
Picture tiene una propiedad llamada tambien Picture, y esta propiedad
contiene el handle del icono)
Crea un módulo .BAS
con el siguiente código:
' estructura que usa la funcion Shell_NotifyIcon
Type NOTIFYICONDATA
cbSize As Long
hwnd As Long
uID As Long
uFlags As Long
uCallbackMessage As Long
hIcon As Long
szTip As String * 64
End Type
' Flags para NOTIFYICONDATA
Public Const NIF_MESSAGE = &H1
Public Const NIF_ICON = &H2
Public Const NIF_TIP = &H4
' comandos que procesa Shell_NotifyIcon
Public Const NIM_ADD = &H0
Public Const NIM_MODIFY = &H1
Public Const NIM_DELETE = &H2
' funcion Shell_NotifyIcon
Declare Sub Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA)
' funcion para copiar string
Declare Sub lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As String)
' eventos del mouse
Public Const WM_MOUSEFIRST = &H200
Public Const WM_MOUSEMOVE = &H200
Public Const WM_LBUTTONDOWN = &H201
Public Const WM_LBUTTONUP = &H202
Public Const WM_LBUTTONDBLCLK = &H203
Public Const WM_RBUTTONDOWN = &H204
Public Const WM_RBUTTONUP = &H205
Public Const WM_RBUTTONDBLCLK = &H206
Public Const WM_MBUTTONDOWN = &H207
Public Const WM_MBUTTONUP = &H208
Public Const WM_MBUTTONDBLCLK = &H209
Public Const WM_MOUSELAST = &H209
' Global, solo usamos un icono
Dim NotIcon As NOTIFYICONDATA
Sub IconModify(ico As Long)
NotIcon.hIcon = ico
Shell_NotifyIcon NIM_MODIFY, NotIcon
End Sub
Sub IconDelete()
Shell_NotifyIcon NIM_DELETE, NotIcon
End Sub
Sub IconAdd(hwnd As Long, ico As Long, tip As String)
NotIcon.cbSize = 88
NotIcon.hwnd = hwnd
NotIcon.uID = 1
NotIcon.uFlags = NIF_ICON + NIF_MESSAGE + NIF_TIP
NotIcon.uCallbackMessage = WM_MOUSEMOVE
NotIcon.hIcon = ico
lstrcpy NotIcon.szTip, tip
Shell_NotifyIcon NIM_ADD, NotIcon
End Sub
Tenemos en este módulo tres funciones, IconAdd, IconModify
e IconDelete que usaremos para colocar, modificar y eliminar el
icono de la barra de tareas. Asimismo usamos una variable global NotIcon
para simplificar el uso de las funciones anteriores
La funcion IconAdd debe recibir como parámetros el hWnd
del Picture que va a recibir las notificaciones, el handle del icono (propiedad
Picture) que va a mostrar y un texto descriptivo que no debe
sobrepasar 63 caracteres de longitud. Usa la funcion IconAdd así:
IconAdd Picture1.hWnd, Picture1.Picture, "Texto de ayuda"
La funcion IconModify permite cambiar el icono y con ello crear
una animación. Puedes usarla así (por ejemplo): IconModify
Picture2.Picture
La funcion IconDelete no lleva ningún parámetro
y sirve para eliminar el icono de la barra de tareas.
Estas tres funciones es todo lo que necesitamos saber del nuevo módulo
.BAS. Volvamos ahora al formulario y coloquemos una llamda a
IconAdd en el evento Load y otra llamada IconDelete
en el evento Unload.
Private Sub Form_Load()
IconAdd Picture1.hwnd, Picture1.Picture, "mini-ayuda"
End Sub
Private Sub Form_Unload(Cancel As Integer)
IconDelete
End Sub
Si ejecutamos ahora la aplicacion, deberemos ver el icono en
la barra de tareas mientras el formulario permanezca cargado. Si
deseamos que el icono parezca animado deberemos añadir una llamda
a IconModify (usando por ejemplo un control Timer).
Recibiendo notificaciones.
Volvamos al control Picture1, cuya propiedad hWnd se usó
en la llamada a IconAdd, y en el evento MouseMove de este
control recibiremos las notificaciones del icono. A pesar de estar
encapsuladas en un único evento, el icono envía varios tipos
de notificaciones. Para distinguir el tipo de notificacion
que estamos recibiendo usaremos el parámetro X. Aquí
resulta fundamental haber puesto ScaleMode = Pixels en el control
Picture1.
Simplemente con un Select Case X podemos distinguir entre los
siguientes mensajes:
Public Const WM_MOUSEMOVE = &H200 ' movimiento de ratón
Public Const WM_LBUTTONDOWN = &H201 ' boton izquierdo
Public Const WM_LBUTTONUP = &H202
Public Const WM_LBUTTONDBLCLK = &H203
Public Const WM_RBUTTONDOWN = &H204 ' boton derecho
Public Const WM_RBUTTONUP = &H205
Public Const WM_RBUTTONDBLCLK = &H206
Public Const WM_MBUTTONDOWN = &H207 ' boton central
Public Const WM_MBUTTONUP = &H208
Public Const WM_MBUTTONDBLCLK = &H209
Así por ejemplo si deseamos procesar solamente los click u dblclick
del botón izquierdo podemos incluir el siguiente código:
Private Sub Picture1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Select Case X
Case WM_LBUTTONDBLCLK
Label1 = Label1 + " Doble " ' codigo correspondiente a doble-click
Case WM_LBUTTONUP
Label1 = Label1 + " Click " ' codigo correspondiente a click
End Select
End Sub
Ejecuta ahora el programa y actúa con el mouse sobre el icono,
funciona ?
El archivo micon.zip contiene un ejemplo
que muestra un icono animado.
©
info3@maicas.net