htm=articulo/micon.htm ok articulo/micon.htm

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