| '----------------------------------------------------------------------
'Start of Class Module: clsInTray
Option Explicit
Private m_hWndHidden As Long 'Dummy window used for call backs
Private m_nid As NOTIFYICONDATA
Private m_bVisible As Boolean 'Is the icon visible yet?
Private m_sClass As String
Public Event MouseMove()
Public Event MouseUp(Button As Integer)
Public Event MouseDown(Button As Integer)
Public Event DblClick(Button As Integer)
'The handle of the hIcon to use
Public Property Get hIcon() As Long
hIcon = m_nid.hIcon
End Property
Public Property Let hIcon(newhIcon As Long)
m_nid.hIcon = newhIcon
End Property
'Tool tip for the system tray icon
Public Property Get Tip() As String
Tip = m_nid.szTip
End Property
Public Property Let Tip(szTip As String)
m_nid.szTip = szTip & vbNullChar
End Property
'Adds the icon to the system tray.
' Set hIcon and Tip before calling this function
Public Sub AddIcon()
Debug.Assert m_bVisible = False
Shell_NotifyIcon NIM_ADD, m_nid
m_bVisible = True
End Sub
'Updates the system tray icon to reflect any changes to
' hIcon or Tip
Public Sub ModifyIcon()
Debug.Assert m_bVisible
Shell_NotifyIcon NIM_MODIFY, m_nid
End Sub
'Removes the system tray icon
Public Sub RemoveIcon()
Debug.Assert m_bVisible
Shell_NotifyIcon NIM_DELETE, m_nid
m_bVisible = False
End Sub
Private Sub Class_Initialize()
m_sClass = "VB InTray Class"
'Register a class for, and create the dummy window
Dim wc As WNDCLASS
wc.style = 0
wc.lpfnwndproc = Pass(AddressOf InTrayWndProc)
wc.hInstance = App.hInstance
wc.lpszClassName = m_sClass
RegisterClass wc
m_hWndHidden = CreateWindowEx(0, m_sClass, "VB InTray Hidde" & _
"n Window", 0, 0, 0, 100, 100, 0, 0, 0, ByVal 0)
Dim lpMe As Long
lpMe = CreateRef(Me)
SetWindowLong m_hWndHidden, GWL_USERDATA, lpMe
'Initialize the Notify Icon Data structure
With m_nid
.cbSize = Len(m_nid)
.hIcon = 0
.hwnd = m_hWndHidden
.szTip = "" & vbNullString
.uCallbackMessage = WM_USER_SYSTRAY
.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
.uID = 0
End With
End Sub
'Function should only be called from modInTray to process windows
' messages generated from the System Tray
Public Sub ProcessMessage(wParam As Long, lParam As Long)
Select Case lParam
Case WM_MOUSEMOVE
RaiseEvent MouseMove
Case WM_LBUTTONDOWN
RaiseEvent MouseDown(vbLeftButton)
Case WM_LBUTTONUP
RaiseEvent MouseUp(vbLeftButton)
Case WM_LBUTTONDBLCLK
RaiseEvent DblClick(vbLeftButton)
Case WM_RBUTTONDOWN
RaiseEvent MouseDown(vbRightButton)
Case WM_RBUTTONUP
RaiseEvent MouseUp(vbRightButton)
Case WM_RBUTTONDBLCLK
RaiseEvent DblClick(vbRightButton)
Case WM_MBUTTONDOWN
RaiseEvent MouseDown(vbMiddleButton)
Case WM_MBUTTONUP
RaiseEvent MouseUp(vbMiddleButton)
Case WM_MBUTTONDBLCLK
RaiseEvent DblClick(vbMiddleButton)
End Select
End Sub
Private Sub Class_Terminate()
'Close the dummy window
SendMessage m_hWndHidden, WM_CLOSE, 0, ByVal 0&
'Remove the icon if it exists
If m_bVisible Then
RemoveIcon
End If
UnregisterClass m_sClass, App.hInstance
End Sub
'This function should only be called from modInTray when the
' TaskBar is recreated (ie, in response to TaskbarCreated)
Public Sub RecreateIcon()
If m_bVisible Then
m_bVisible = False
AddIcon
End If
End Sub
'End of Class Module: clsInTray
'----------------------------------------------------------------------
'----------------------------------------------------------------------
'Start of Module: modInTray
Option Explicit
'Windows API's
Declare Function RegisterClass Lib "user32" Alias "RegisterClassA" _
(Class As WNDCLASS) As Long
Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" _
(ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal _
lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, _
ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, _
ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance _
As Long, lpParam As Any) As Long
Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) _
As Long
Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias _
"Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As _
NOTIFYICONDATA) As Long
Declare Function RegisterWindowMessage Lib "user32" Alias _
"RegisterWindowMessageA" (ByVal lpString As String) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As _
Long) As Long
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal _
hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam _
As Any) As Long
Declare Function CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal _
dest As Long, ByVal src As Long, ByVal length As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long) As Long
Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _
ByVal lParam As Long) As Long
Declare Function UnregisterClass Lib "user32" Alias "UnregisterClassA" _
(ByVal lpClassName As String, ByVal hInstance As Long) As Long
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
Type WNDCLASS
style As Long
lpfnwndproc As Long
cbClsextra As Long
cbWndExtra2 As Long
hInstance As Long
hIcon As Long
hCursor As Long
hbrBackground As Long
lpszMenuName As Long
lpszClassName As String
End Type
Public Const NIM_ADD = &H0
Public Const NIM_MODIFY = &H1
Public Const NIM_DELETE = &H2
Public Const NIF_MESSAGE = &H1
Public Const NIF_ICON = &H2
Public Const NIF_TIP = &H4
Public Const WM_USER = &H400
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_USER_SYSTRAY = WM_USER + 5
Public Const WM_CLOSE = &H10
Public Const GWL_USERDATA = (-21)
'Have we initialized TaskbarRestart yet?
Private m_bMessageInited As Boolean
'Windows message sent out when the taskbar is restarted
' (ie4 and up)
Private m_uTaskbarRestart As Long
'Dummy function to allow AddressOf to assign to a variable
Public Function Pass(n As Long) As Long
Pass = n
End Function
'Return a VB object pointed by nPointer
Public Function DeRef(nPointer As Long) As clsInTray
CopyMemory VarPtr(DeRef), VarPtr(nPointer), 4
End Function
'Creates a pointer to a VB object
Public Function CreateRef(obj As clsInTray) As Long
CopyMemory VarPtr(CreateRef), VarPtr(obj), 4
End Function
'Destroys a VB object created by DeRef (otherwise the VB's
' reference count would be incorrect)
Public Sub DestroyRef(nobj As Long)
Dim n As Long
CopyMemory nobj, VarPtr(n), 4
End Sub
'The window procedure for the dummy windows that clsInTray creates
Public Function InTrayWndProc(ByVal hwnd As Long, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
Dim lpObj As Long
Dim obj As clsInTray
If Not m_bMessageInited Then
InitMessage
End If
Select Case uMsg
'Pass WM_USER_SYSTRAY to the clsInTray object
Case WM_USER_SYSTRAY
lpObj = GetWindowLong(hwnd, GWL_USERDATA)
Set obj = DeRef(lpObj)
obj.ProcessMessage wParam, lParam
DestroyRef VarPtr(obj)
'If the TaskBar restarts, let clsInTray know about it
Case m_uTaskbarRestart
lpObj = GetWindowLong(hwnd, GWL_USERDATA)
Set obj = DeRef(lpObj)
obj.RecreateIcon
DestroyRef VarPtr(obj)
End Select
InTrayWndProc = DefWindowProc(hwnd, uMsg, wParam, lParam)
End Function
'Register the windows message TaskbarCreated so we can watch for it
Private Function InitMessage()
m_bMessageInited = True
m_uTaskbarRestart = RegisterWindowMessage("TaskbarCreated")
End Function
'End of Module: modInTray
'----------------------------------------------------------------------
|