home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 4_2005-2006.ISO / data / Zips / LaVolpe_De1996435232006.psc / clsSysTray.cls < prev    next >
Text File  |  2006-05-22  |  17KB  |  442 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "clsSysTray"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15. ' *****
  16. ' This class came from another project. The remarks may or may not pertain to this project
  17.  
  18. ' almost all of this class from http://vbnet.mvps.org/index.html?code/subclass/shellnotifystructinfo.htm
  19. ' added additional routines & modified a couple so they can be used generically
  20. ' and also to allow multiple icons per hWnd
  21.  
  22. ' This class will allow you to modify system tray icons for your application
  23.  
  24. ' Any hWnd can have a tray icon. All icons you assign to the tray icons are your
  25. ' responsibility for destroying when appropriate. Only top level windows should
  26. ' be installing tray icons. This is because should Explorer crash & then
  27. ' restart & new taskbar created, the message we look for to restore the icons
  28. ' on the new taskbar is only sent to top level windows.
  29.  
  30. ' This class can be setup in your routines at any time and can be deactivated at
  31. ' any time, destroyed, or activated any time after the hWnd has begun subclassing.
  32.  
  33. Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
  34. Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
  35. Private Declare Function GetWindowRect Lib "user32.dll" (ByVal hwnd As Long, ByRef lpRect As RECT) As Long
  36. Private Declare Function IsIconic Lib "user32.dll" (ByVal hwnd As Long) As Long
  37. Private Declare Function DrawAnimatedRects Lib "user32.dll" (ByVal hwnd As Long, ByVal idAni As Long, ByRef lprcFrom As RECT, ByRef lprcTo As RECT) As Long
  38. Private Declare Function ShowWindow Lib "user32.dll" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
  39. Private Declare Function LockWindowUpdate Lib "user32.dll" (ByVal hwndLock As Long) As Long
  40. Private Declare Function MoveWindow Lib "user32.dll" (ByVal hwnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long
  41. Private Type RECT
  42.     Left As Long
  43.     Top As Long
  44.     Right As Long
  45.     Bottom As Long
  46. End Type
  47.  
  48.  
  49.  
  50.  
  51. Private Declare Function Shell_NotifyIcon Lib "shell32" Alias "Shell_NotifyIconA" _
  52.       (ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean
  53.  
  54. Private Declare Function GetFileVersionInfoSize Lib "Version.dll" Alias "GetFileVersionInfoSizeA" _
  55.   (ByVal lptstrFilename As String, lpdwHandle As Long) As Long
  56.  
  57. Private Declare Function GetFileVersionInfo Lib "Version.dll" Alias "GetFileVersionInfoA" _
  58.   (ByVal lptstrFilename As String, ByVal dwhandle As Long, ByVal dwlen As Long, lpData As Any) As Long
  59.    
  60. Private Declare Function VerQueryValue Lib "Version.dll" Alias "VerQueryValueA" (pBlock As Any, _
  61.    ByVal lpSubBlock As String, lpBuffer As Any, nVerSize As Long) As Long
  62.  
  63. 'Private Type GUID
  64. '   Data1 As Long
  65. '   Data2 As Integer
  66. '   Data3 As Integer
  67. '   Data4(7) As Byte
  68. 'End Type
  69. Private Type NOTIFYICONDATA
  70.    cbSize As Long
  71.    hwnd As Long
  72.    uID As Long
  73.    uFlags As Long
  74.    uCallbackMessage As Long
  75.    hIcon As Long
  76.    szTip As String * 128      'shell 5+  <> 64 chars max for shell <5
  77.    dwState As Long            'shell 5+  <> not used in this class
  78.    dwStateMask As Long        'shell 5+
  79.    szInfo As String * 256     'shell 5+
  80.    uTimeoutAndVersion As Long 'shell 5+
  81.    szInfoTitle As String * 64 'shell 5+
  82.    dwInfoFlags As Long        'shell 5+
  83.    guidItem(15) As Byte       ' GUID  shell 6+  <> reserved by Windows
  84. End Type
  85.  
  86. ' tray update commands
  87. Private Const NIM_ADD = &H0
  88. Private Const NIM_MODIFY = &H1
  89. Private Const NIM_DELETE = &H2
  90.       
  91. ' tray update masks
  92. Private Const NIF_MESSAGE = &H1
  93. Private Const NIF_INFO As Long = &H10
  94. Private Const NIF_ICON = &H2
  95. Private Const NIF_STATE As Long = &H8
  96. Private Const NIF_TIP = &H4
  97. Private Const NIS_HIDDEN = &H1
  98.  
  99. 'balloon tip notification messages <> not used here; for ref only
  100. 'Private Const NIN_BALLOONSHOW = (WM_USER + 2)
  101. 'Private Const NIN_BALLOONHIDE = (WM_USER + 3)
  102. 'Private Const NIN_BALLOONTIMEOUT = (WM_USER + 4)
  103. 'Private Const NIN_BALLOONUSERCLICK = (WM_USER + 5)
  104.  
  105. ' tray version settings
  106. Private Const NOTIFYICON_VERSION As Long = &H3
  107. Private Const NIM_SETVERSION As Long = &H4
  108. Private Const NOTIFYICONDATA_V1_SIZE As Long = 88  'pre-5.0 structure size
  109. Private Const NOTIFYICONDATA_V2_SIZE As Long = 488 'pre-6.0 structure size
  110. Private Const NOTIFYICONDATA_V3_SIZE As Long = 504 '6.0+ structure size
  111. Private NOTIFYICONDATA_SIZE As Long
  112.  
  113. Public Enum BalloonIcons
  114.     icNone = &H0        'NIIF_NONE As Long = &H0
  115.     icInfo = &H1        'NIIF_INFO As Long = &H1
  116.     icWarning = &H2     'NIIF_WARNING As Long = &H2
  117.     icError = &H3       'NIIF_ERROR As Long = &H3
  118.     icTrayIcon = &H4    'NIIF_USER As Long = &H4 ???
  119.     icNoSound = &H10    'NIIF_NOSOUND = &H10
  120.     icNoChange = &H40   'class-custom value
  121. End Enum
  122.  
  123. Private nid As NOTIFYICONDATA   ' cached UDT values
  124.  
  125. Private rcAni As RECT
  126.  
  127. Public Sub RemoveTrayIcon()
  128. ' remove/inactive the icon from system tray. Also can be called from
  129. ' lvSubclasser's ApplyTrayNotify function
  130.  
  131. ' The information in this class is not destroyed; therefore you can easily
  132. ' toggle the tray icon by using the lvSubclasser's ApplyTrayNotify function.
  133.  
  134.     If IsActive Then
  135.         nid.uFlags = 0
  136.         Shell_NotifyIcon NIM_DELETE, nid
  137.         nid.uCallbackMessage = 0 ' this flag determines if tray is active or not
  138.     End If
  139.  
  140. End Sub
  141.  
  142.  
  143. Public Sub InitializeTray(ByVal hIcon As Long, NewTip As String)
  144. ' This is a nice to have routine that fills in the icon & tip in one step
  145. ' vs calling those idividual properties. It does not active the tray icon.
  146. ' You must activate it from your lvSubclasser's ApplyTrayNotify function.
  147.  
  148. ' Parameters
  149. ' hIcon is a handle to an existing icon you want to display in the tray
  150. '       -- IMPORTANT: you are responsible for destroying the icon if needed
  151. ' Tip is displayed when mouse hovers icon. 128 max unless < Shell32.v5 which is 64
  152.  
  153.     Tip = NewTip
  154.     Icon = hIcon
  155. End Sub
  156.  
  157. Public Property Let Icon(ByVal hIcon As Long)
  158. ' Used to change the icon displayed on the system tray
  159. ' IMPORTANT: You are responsible for destroying icons if needed
  160.  
  161.     nid.hIcon = hIcon
  162.     If IsActive Then
  163.         nid.uFlags = NIF_ICON
  164.         Shell_NotifyIcon NIM_MODIFY, nid
  165.     End If
  166. End Property
  167. Public Property Get Icon() As Long
  168.     Icon = nid.hIcon    ' returns handle to currently assigned icon
  169. End Property
  170.  
  171. Public Property Let Tip(ByVal NewTip As String)
  172.     ' Used to change the tip displayed when mouse hovers over your icon
  173.     nid.szTip = NewTip & vbNullChar
  174.     If IsActive Then
  175.         nid.uFlags = NIF_TIP
  176.         Shell_NotifyIcon NIM_MODIFY, nid
  177.     End If
  178. End Property
  179. Public Property Get Tip() As String
  180.     Tip = Left$(nid.szTip, InStr(nid.szTip & Chr$(0), Chr$(0)) - 1)
  181. End Property
  182.  
  183. ' Read-Only properties return balloon title & message.
  184. ' Use ShowBalloon to set those values
  185. Public Property Get BalloonTitle() As String
  186.     BalloonTitle = Left$(nid.szInfoTitle, InStr(nid.szInfoTitle & Chr$(0), Chr$(0)) - 1)
  187. End Property
  188. Public Property Get BalloonMessage() As String
  189.     BalloonMessage = Left$(nid.szInfo, InStr(nid.szInfo & Chr$(0), Chr$(0)) - 1)
  190. End Property
  191.  
  192. Public Property Get isBalloonCapable() As Boolean
  193.     ' property will let you know if you can use balloons on clients pc
  194.     isBalloonCapable = (NOTIFYICONDATA_SIZE > NOTIFYICONDATA_V1_SIZE)
  195. End Property
  196.  
  197. Public Sub ShowBalloon(Optional ByVal Message As String, _
  198.     Optional ByVal Title As String, _
  199.     Optional ByVal Icon As BalloonIcons = icNoChange)
  200.  
  201. ' Routine shows a balloon tip only after this class has been assigned to your subclasser
  202. ' The class does not destroy your tip, title or icon settings; therefore you only need
  203. ' to pass the information that you want changed from the last time you called the tip
  204.  
  205. If NOTIFYICONDATA_SIZE = 0 Then GetTrayVersion
  206.  
  207. If NOTIFYICONDATA_SIZE > NOTIFYICONDATA_V1_SIZE Then
  208.     ' V1 of Shell32.dll doesn't have balloon capability (pre W2K)
  209.     
  210.     With nid
  211.         ' only make needed changes
  212.         If Len(Message) Then .szInfo = Message & vbNullChar
  213.         If Len(Title) Then .szInfoTitle = Title & vbNullChar
  214.         If (Icon Or icNoChange) <> Icon Then
  215.             If NOTIFYICONDATA_SIZE < NOTIFYICONDATA_V3_SIZE Then
  216.                 ' filter out non-XP settings if not right version of tray
  217.                 If (Icon Or icTrayIcon) = Icon Then Icon = Icon And Not icTrayIcon
  218.                 If (Icon Or icNoSound) = Icon Then Icon = Icon And Not icNoSound
  219.             End If
  220.             .dwInfoFlags = Icon
  221.         End If
  222.         .uFlags = NIF_INFO
  223.     End With
  224.     ' if the class has been added to subclasser, send the change
  225.     If IsActive Then Shell_NotifyIcon NIM_MODIFY, nid
  226. End If
  227.     
  228. End Sub
  229.  
  230. Public Sub HideBalloon()
  231.  
  232. ' function destroys a balloon if visible
  233.  
  234. ' if the class has been added to subclasser, send the change
  235. If IsActive Then
  236.     
  237.     If NOTIFYICONDATA_SIZE > NOTIFYICONDATA_V1_SIZE Then
  238.         Dim oldNid As NOTIFYICONDATA
  239.         oldNid = nid
  240.         With oldNid
  241.              ' remove all tip info
  242.             .szInfo = vbNullChar
  243.             .szInfoTitle = vbNullChar
  244.             .szTip = vbNullChar
  245.             .uFlags = NIF_INFO Or NIF_TIP
  246.         End With
  247.         ' update
  248.         Shell_NotifyIcon NIM_MODIFY, oldNid
  249.         
  250.         ' replace the original tip info
  251.         nid.uFlags = NIF_TIP
  252.         Shell_NotifyIcon NIM_MODIFY, nid
  253.     End If
  254. End If
  255. End Sub
  256.  
  257. Private Sub GetTrayVersion()
  258. ' unmodified from source
  259.  
  260.   'returns True if the Shell version
  261.   '(shell32.dll) is equal or later than
  262.   'the value passed as 'version'
  263.    Dim nBufferSize As Long
  264.    Dim nUnused As Long
  265.    Dim lpBuffer As Long
  266.    Dim nVerMajor As Integer
  267.    Dim bBuffer() As Byte
  268.    
  269.    Const sDLLFile As String = "shell32.dll"
  270.    
  271.    nBufferSize = GetFileVersionInfoSize(sDLLFile, nUnused)
  272.    
  273.    If nBufferSize > 0 Then
  274.     
  275.       ReDim bBuffer(nBufferSize - 1) As Byte
  276.     
  277.       Call GetFileVersionInfo(sDLLFile, 0&, nBufferSize, bBuffer(0))
  278.     
  279.       If VerQueryValue(bBuffer(0), "\", lpBuffer, nUnused) = 1 Then
  280.          
  281.          CopyMemory nVerMajor, ByVal lpBuffer + 10, 2
  282.         
  283.          'IsShellVersion = nVerMajor >= version
  284.          Select Case nVerMajor
  285.          Case Is < 5
  286.             NOTIFYICONDATA_SIZE = NOTIFYICONDATA_V1_SIZE
  287.         Case Is < 6
  288.             NOTIFYICONDATA_SIZE = NOTIFYICONDATA_V2_SIZE
  289.         Case Else
  290.             NOTIFYICONDATA_SIZE = NOTIFYICONDATA_V3_SIZE
  291.         End Select
  292.       
  293.       End If  'VerQueryValue
  294.     
  295.    End If  'nBufferSize
  296.   
  297. End Sub
  298.  
  299. Friend Sub BeginTrayNotifications(hwnd As Long, TrayIconID As Long, uMsg As Long)
  300. ' Only called by lvSubclasser
  301.  
  302. ' since this class can be set up on demand, knowing when to activate it isn't
  303. ' possible without user dictating that fact.  This routine fills in the
  304. ' missing information needed to activate the icon
  305.  
  306. ' determine which version is running on the OS
  307. ' calculates the NOTIFYICONDATA_SIZE value
  308. If NOTIFYICONDATA_SIZE = 0 Then GetTrayVersion
  309.     Dim lAction As Long
  310.     If IsActive = True Then lAction = NIM_MODIFY Else lAction = NIM_ADD
  311.     
  312.     With nid
  313.         .cbSize = NOTIFYICONDATA_SIZE
  314.         .uFlags = NIF_MESSAGE Or NIF_ICON Or NIF_TIP
  315.         .uTimeoutAndVersion = NOTIFYICON_VERSION
  316.         .uCallbackMessage = uMsg ' custom message
  317.         .uID = TrayIconID
  318.         .hwnd = hwnd
  319.     End With
  320.     Shell_NotifyIcon lAction, nid
  321.             
  322.     If lAction = NIM_ADD Then Shell_NotifyIcon NIM_SETVERSION, nid
  323.  
  324. ' Note: The custom message above isn't really important to you.
  325. ' It will never be sent to your ProcessMessage routine.
  326. ' The DLL reroutes these messages to a separate event call ProcessTrayIcon.
  327.  
  328. ' The value of the message, should you also be using custom messages is
  329. ' WM_USER + &H1962
  330. End Sub
  331.  
  332. Public Sub Restore(uMsg As Long)
  333.     ' function is called only from lvSubclasser after a new Explorer re-starts after crash
  334.     ' not all icons may be active, reactivate only previously active ones
  335.     If nid.hwnd <> 0 Then
  336.         nid.uCallbackMessage = 0
  337.         BeginTrayNotifications nid.hwnd, nid.uID, uMsg
  338.     End If
  339.  
  340. End Sub
  341.  
  342. Private Sub Class_Terminate()
  343. ' remove the tray icon if activated
  344.     RemoveTrayIcon
  345. End Sub
  346.  
  347. Public Property Get IsActive() As Boolean
  348.     ' returns whether or not tray icon is active.
  349.     ' Active means it is sending your hWnd messages
  350.     IsActive = nid.uCallbackMessage <> 0
  351. End Property
  352.  
  353. '---------------------------------------------------------------------------------------
  354. ' Procedure : CustomWindow.MinimizeAnimated
  355. ' DateTime  : 9/24/2005
  356. ' Author    : LaVolpe
  357. ' Purpose   : Make minimized window minimize towards the system tray
  358. ' Comments  : See Below
  359. '---------------------------------------------------------------------------------------
  360. '
  361. Public Function MinimizeAnimated(ByVal hwnd As Long) As Boolean
  362.  
  363.     Dim rcTray As RECT, trayHwnd As Long
  364.     
  365.     ' if not minimizing window and the window is not already in the system tray,
  366.     ' then we have nothing to do here
  367.     If IsIconic(hwnd) Then Exit Function
  368.     
  369.     ' find the system taskbar if it exists
  370.     trayHwnd = FindWindow("Shell_TrayWnd", vbNullString)
  371.     If trayHwnd <> 0 Then
  372.         ' now find the system tray if it exists
  373.         trayHwnd = FindWindowEx(trayHwnd, 0, "TrayNotifyWnd", vbNullString)
  374.         If trayHwnd <> 0 Then
  375.             GetWindowRect hwnd, rcAni
  376.             ' get the system tray coordiantes & size
  377.             GetWindowRect trayHwnd, rcTray
  378.             If rcTray.Right > rcTray.Left Then
  379.                 ' use a 2x2 rectangle as the source or destination Rect
  380.                 ' depending on if we are minimizing to tray or restoring from tray
  381.                 rcTray.Left = (rcTray.Right - rcTray.Left - 4) \ 2 + rcTray.Left
  382.                 rcTray.Right = rcTray.Left + 2
  383.                 rcTray.Top = (rcTray.Bottom - rcTray.Top - 4) \ 2 + rcTray.Top
  384.                 rcTray.Bottom = rcTray.Top + 2
  385.             End If
  386.             
  387.             ' DrawAnimatedRects will fail to draw the animation if the window
  388.             ' uses a WindowRgn and O/S is less than XP
  389.             ' regardless if DrawAnimatedRects fails or not, hide the window
  390.             DrawAnimatedRects hwnd, &H3, rcAni, rcTray
  391.             ShowWindow hwnd, 0      ' hide the window
  392.             ShowWindow hwnd, &H7   ' minimize no focus
  393.             MinimizeAnimated = True ' abort the wm_syscommand message
  394.         End If
  395.     End If
  396.     ShowWindow hwnd, 0&     ' hide it
  397.     
  398. End Function
  399.  
  400.  
  401. '---------------------------------------------------------------------------------------
  402. ' Procedure : CustomWindow.RestoreAnimated
  403. ' DateTime  : 9/24/2005
  404. ' Author    : LaVolpe
  405. ' Purpose   : Make minimized window restore from the system tray
  406. ' Comments  : See Below
  407. '---------------------------------------------------------------------------------------
  408. '
  409. Public Function RestoreAnimated(ByVal hwnd As Long) As Boolean
  410.  
  411.     Dim rcTray As RECT, trayHwnd As Long
  412.     
  413.     ' if showing window and the window is not minimized then not much to do
  414.     If IsIconic(hwnd) = 0 Then Exit Function
  415.         
  416.     ' find the system taskbar if it exists
  417.     trayHwnd = FindWindow("Shell_TrayWnd", vbNullString)
  418.     If trayHwnd <> 0 Then
  419.         ' now find the system tray if it exists
  420.         trayHwnd = FindWindowEx(trayHwnd, 0, "TrayNotifyWnd", vbNullString)
  421.         If trayHwnd <> 0 Then
  422.             ' get the system tray coordiantes & size
  423.             GetWindowRect trayHwnd, rcTray
  424.             If rcTray.Right > rcTray.Left Then
  425.                 ' use a 2x2 rectangle as the destination
  426.                 rcTray.Left = (rcTray.Right - rcTray.Left - 4) \ 2 + rcTray.Left
  427.                 rcTray.Right = rcTray.Left + 2
  428.                 rcTray.Top = (rcTray.Bottom - rcTray.Top - 4) \ 2 + rcTray.Top
  429.                 rcTray.Bottom = rcTray.Top + 2
  430.             End If
  431.             
  432.             ' DrawAnimatedRects will fail to draw the animation if the window
  433.             ' uses a WindowRgn and O/S is less than XP
  434.             DrawAnimatedRects hwnd, &H3, rcTray, rcAni
  435.             RestoreAnimated = True
  436.         End If
  437.     End If
  438.     ShowWindow hwnd, 9 ' show the window
  439.  
  440. End Function
  441.  
  442.