Attribute VB_Name = "modSystray"
Option Explicit
Public Const WM_NCMOUSEMOVE = &HA0

Public Const WM_DRAWITEM = &H2B
Public Const WM_MEASUREITEM = &H2C
Public Const WM_COMMAND = &H111

Public Const WM_MENUSELECT = &H11F
Public Const WM_USER = &H400
Public Const WM_RBUTTONDBLCLK = &H206
Public Const WM_RBUTTONDOWN = &H204
Public Const WM_RBUTTONUP = &H205
Public Const WM_MOUSEMOVE = &H200
Public Const WM_MBUTTONUP = &H208
Public Const WM_MBUTTONDOWN = &H207
Public Const WM_MBUTTONDBLCLK = &H209
Public Const WM_LBUTTONUP = &H202
Public Const WM_LBUTTONDOWN = &H201
Public Const WM_LBUTTONDBLCLK = &H203
Public Const WM_CONTEXTMENU = &H7B
Public Const WM_TIMER = &H113

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''' TYPES
' Old NotifyIconData

Public 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

' NotifyIconData for Window NT 5.0 (Windows 2000)

Public Type NOTIFYICONDATA5
    cbSize As Long
    hwnd As Long
    uId As Long
    uFlags As Long
    uCallbackMessage As Long
    hIcon As Long
    szTip As String * 128
    dwState As Long
    dwStateMask As Long
    szInfo As String * 256
    uVersion As Long
    szInfoTitle As String * 64
    dwInfoFlags As Long
End Type
' Shell_NotifyIcon features for Windows NT 5.0 (Windows 2000)

Public Const NIN_SELECT = (WM_USER + 0)
Public Const NINF_KEY = &H1
Public Const NIN_KEYSELECT = (NIN_SELECT + NINF_KEY)
Public Const NIM_SETFOCUS = &H3
Public Const NIM_SETVERSION = &H4
Public Const NOTIFYICON_VERSION = 3
Public Const NIF_STATE = &H8
Public Const NIF_INFO = &H10

Public Const NIS_HIDDEN = &H1
Public Const NIS_SHAREDICON = &H2

' Regular NotifyIcon Features for Windows 95/98/NT

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

' Notify Icon Infotip flags

Public Const NIIF_NONE = &H0

' icon flags are mutualy exclusive
' and take only the lowest 2 bits

' Notify Icon Balloon Icon constants

Public Const NIIF_INFO = &H1
Public Const NIIF_WARNING = &H2
Public Const NIIF_ERROR = &H3

Public Enum NII
    None = &H0
    Info_Icon = &H1
    Warning_Icon = &H2
    error_Icon = &H3
End Enum

' Shell_NotifyIconA if OSVersion <= 4

Public Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long

' Shell_NotifyIconA if OSVersion >= 5

Public Declare Function Shell_NotifyIcon5 Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA5) As Long

Public Const NIF_CUSTOM_MSG = (WM_USER + &H108)
Public Notify As NOTIFYICONDATA5


Public OldWindowProc As Long

Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Const GWL_WNDPROC = (-4)

Public Declare Function RegisterHotKey Lib "user32" (ByVal hwnd As Long, ByVal id As Long, ByVal fsModifiers As Long, ByVal vk As Long) As Long
Public Declare Function UnregisterHotKey Lib "user32" (ByVal hwnd As Long, ByVal id As Long) As Long
Public Const MOD_ALT = &H1
Public Const VK_F10 = &H79

Public Const HOTKEY_ID = 1
Public NotifyAdded As Boolean
Sub AddNotifyIcon(ByVal hwnd As Long, ByVal hIcon As Long, ByVal sTip As String)
    With Notify
        .cbSize = Len(Notify)
        .uFlags = NIF_TIP Or NIF_ICON Or NIF_MESSAGE Or NIF_INFO
        .szTip = StrFix(sTip, 127, True) + Chr(0)
        .hIcon = hIcon
        .hwnd = hwnd
        .szInfo = StrFix("Webshots Loaded", 255, True) + Chr(0)
        .szInfoTitle = StrFix(App.Title, 63, True) + Chr(0)
        .dwInfoFlags = Info_Icon
        .uCallbackMessage = WM_MOUSEMOVE
        .uVersion = NOTIFYICON_VERSION
        .uId = 0
    End With
Shell_NotifyIcon5 NIM_ADD, Notify
'    lPrevProc = SetWindowLong(m_hWnd, GWL_WNDPROC, AddressOf NifWndProc)
        NotifyAdded = True
End Sub
Sub RemoveNotifyIcon()
    Shell_NotifyIcon5 NIM_DELETE, Notify
        NotifyAdded = False
End Sub
Private Sub SetTip(ByVal sTip As String)
    Notify.szTip = TipStr(sTip)
    Shell_NotifyIcon5 NIM_MODIFY, Notify
End Sub
' Get the tip string (can be 128 or 64 bytes depending on the OS version)

Private Function TipStr(vData As String) As String
        TipStr = StrFix(vData, 127, True)
    TipStr = TipStr + Chr(0)
End Function
    
' once the balloon show message is posted, the modify flag is called with
' the NIF_TIP value set, setting the tip to normal.

' When you set the tip to normal, the next time the user hovers over the icon, it will
' display a normal tool tip.  Setting the tip back to normal immediately does not
' affect the balloon when it's already visible.

Public Sub ShowBalloon(ByVal Info As String, ByVal Title As String, _
    Optional ByVal umTimeout As Long = 100, Optional ByVal hIcon As Long)
    Notify.uFlags = NIF_TIP Or NIF_ICON Or NIF_MESSAGE Or NIF_INFO 'NIF_INFO
    Notify.uVersion = umTimeout
    Notify.szInfo = StrFix(Info, 255, True) + Chr(0)
    Notify.szInfoTitle = StrFix(Title, 63, True) + Chr(0)
    Notify.dwInfoFlags = Info_Icon
        If hIcon <> 0 Then Notify.hIcon = hIcon
    Shell_NotifyIcon5 NIM_MODIFY, Notify
    
    Notify.szTip = StrFix(Notify.szTip, 127, True) + Chr(0)
    Notify.uFlags = NIF_TIP
    Shell_NotifyIcon5 NIM_MODIFY, Notify
End Sub
Sub ChangeIcon(ByVal hIcon As Long)
    Notify.uFlags = NIF_ICON
Notify.hIcon = hIcon
    Shell_NotifyIcon5 NIM_MODIFY, Notify
End Sub
' Truncate a long string and/or pad a short string

Private Function StrFix(ByVal sz As String, ByVal uLen As Long, Optional ByVal LengthFix As Boolean = False) As String

    Dim I As Long, x As String
    
    If Len(sz) > uLen Then
        x = Mid(sz, 1, uLen)
    Else
        If LengthFix = True Then
            I = uLen = Len(sz)
            x = sz + String(I, 0)
        Else
            x = sz
        End If
    End If
    
    StrFix = x
End Function

' Look for the WM_HOTKEY message.
Public Function NewWindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Const WM_NCDESTROY = &H82
Const WM_HOTKEY = &H312

    ' If we're being destroyed,
    ' restore the original WindowProc and
    ' unregister the hotkey.
    If Msg = WM_NCDESTROY Then
        SetWindowLong _
            hwnd, GWL_WNDPROC, _
            OldWindowProc
        UnregisterHotKey hwnd, HOTKEY_ID
    End If
    ' See if this is the WM_HOTKEY message.
    If Msg = WM_HOTKEY Then Hotkey
    ' Process the message normally.
    NewWindowProc = CallWindowProc( _
        OldWindowProc, hwnd, Msg, wParam, _
        lParam)
End Function

Public Sub Hotkey()
'    txtTimes.Text = txtTimes.Text & _
'        Time & vbCrLf
'    txtTimes.SelStart = Len(txtTimes.Text)
'
'    If Me.WindowState = vbMinimized Then Me.WindowState = vbNormal
'    Me.SetFocus
End Sub
Sub RegisterHotKeys(ByVal hwnd As Long)
Dim ErrorCount As Byte
    ' Register the hotkey.
    If RegisterHotKey(hwnd, HOTKEY_ID, MOD_ALT, VK_F10) = 0 Then
        MsgBox "Error registering hotkey.", vbCritical
        ErrorCount = 1
    End If

    ' Subclass the TextBox to watch for
    ' WM_HOTKEY messages.
If ErrorCount = 0 Then
    OldWindowProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf NewWindowProc)
End If
End Sub

