PctGL SERIES  
http://pctgl.cnblogs.com

 

 NotifyBar.cls :

 

  1 Option Explicit
  2 
  3 Private Type POINTAPIs
  4     x As Long
  5     y As Long
  6 End Type
  7 
  8 Private Type NOTIFYICONDATA
  9     cbSize As Long
 10     hwnd As Long
 11     uID As Long
 12     uFlags As Long
 13     uCallbackMessage As Long
 14     hIcon As Long
 15     szTip As String * 128
 16     dwState As Long
 17     dwStateMask As Long
 18     szInfo As String * 256
 19     uTimeout As Long
 20     szInfoTitle As String * 64
 21     dwInfoFlags As Long
 22 End Type
 23 
 24 Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, Optional ByVal Length As Long = 4)
 25 Private 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 LongAs Long
 26 Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As LongAs Long
 27 Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As LongAs Long
 28 Private Declare Function VirtualProtect Lib "kernel32" (lpAddress As Any, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As LongAs Long
 29 Private 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
 30 Private Declare Function GetDesktopWindow Lib "user32" () As Long
 31 Private Declare Function Shell_NotifyIcon Lib "shell32" Alias "Shell_NotifyIconA" (ByVal dwMessage As NotifyBarActions, pnid As NOTIFYICONDATA) As Long
 32 Private Declare Function DestroyWindow Lib "user32" (ByVal hwnd As LongAs Long
 33 Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPIs) As Long
 34 Private Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageA" (ByVal lpString As StringAs Long
 35 Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As LongAs Long
 36 
 37 Enum NotifyClickClass
 38     NCL_MouseMove = 0
 39     NCL_DoubleClick = 1
 40     NCL_LeftButtonClick = 2
 41     NCL_RightButtonClick = 3
 42 End Enum
 43 
 44 Enum NotifyMessageIcons
 45     NIIF_NONE = &H0
 46     NIIF_INFO = &H1
 47     NIIF_WARNING = &H2
 48     NIIF_ERROR = &H3
 49     NIIF_GUID = &H4
 50 End Enum
 51 
 52 Private Enum NotifyBarActions
 53     NIM_ADD = &H0
 54     NIM_MODIFY = &H1
 55     NIM_DELETE = &H2
 56     NIM_SETFOCUS = &H3
 57     NIM_SETVERSION = &H4
 58 End Enum
 59 
 60 Private Const NOTIFYICON_VERSION = 3       'V5 style taskbar
 61 Private Const NOTIFYICON_OLDVERSION = 0    'Win95 style taskbar
 62 
 63 Private Const NIS_HIDDEN = &H1
 64 Private Const NIS_SHAREDICON = &H2
 65 
 66 Private Const NIF_STATE = &H8
 67 Private Const NIF_MESSAGE = &H1
 68 Private Const NIF_ICON = &H2
 69 Private Const NIF_TIP = &H4
 70 Private Const NIF_INFO = &H10
 71 
 72 Private Const WM_NOTIFYMESSAGE = 11122
 73 
 74 Event NotifyClick(NClickClass As NotifyClickClass, ByVal x As Long, ByVal y As Long)
 75 
 76 Private Type ThisClassSet
 77     
 78     s_wm_TaskBarCreated        As Long
 79     
 80     n_HandleOfWindow        As Long
 81     s_AddressOfWndProc      As Long
 82     
 83     n_NotifyData            As NOTIFYICONDATA
 84     
 85     n_ClickSign             As Boolean
 86     
 87 End Type
 88 Dim PG                      As ThisClassSet
 89 Dim LinkProc()              As Long
 90 
 91 Private Sub MsgHook(Result As Long, ByVal cHwnd As Long, ByVal Message As Long, ByVal wParam As Long, ByVal lParam As Long)
 92 
 93     '子类化接口过程
 94     
 95     Const WM_MOUSEMOVE = &H200
 96     Const WM_LBUTTONDBLCLK = &H203
 97     Const WM_LBUTTONDOWN = &H201
 98     Const WM_LBUTTONUP = &H202
 99     Const WM_RBUTTONDOWN = &H204
100     Const WM_RBUTTONUP = &H205
101     
102     Dim Pss As POINTAPIs
103     
104     Result = CallWindowProc(PG.s_AddressOfWndProc, cHwnd, Message, wParam, lParam)
105     
106     If Message = PG.n_NotifyData.uCallbackMessage Then
107     
108         GetCursorPos Pss
109         
110         Select Case lParam
111                 Case WM_MOUSEMOVE: RaiseEvent NotifyClick(NCL_MouseMove, Pss.x, Pss.y)
112                 Case WM_LBUTTONDBLCLK: RaiseEvent NotifyClick(NCL_DoubleClick, Pss.x, Pss.y)
113                 Case WM_LBUTTONDOWN, WM_RBUTTONDOWN: PG.n_ClickSign = True
114                 Case WM_LBUTTONUP
115                     If PG.n_ClickSign Then RaiseEvent NotifyClick(NCL_LeftButtonClick, Pss.x, Pss.y)
116                     PG.n_ClickSign = False
117                     
118                 Case WM_RBUTTONUP
119                     SetForegroundWindow cHwnd
120                     If PG.n_ClickSign Then RaiseEvent NotifyClick(NCL_RightButtonClick, Pss.x, Pss.y)
121                     PG.n_ClickSign = False
122                     
123         End Select
124         
125     ElseIf Message = PG.s_wm_TaskBarCreated Then
126         
127         If PG.n_NotifyData.cbSize Then
128             
129             PG.n_NotifyData.uFlags = NIF_ICON Or NIF_MESSAGE Or NIF_TIP
130             Shell_NotifyIcon NIM_ADD, PG.n_NotifyData
131             
132         End If
133     End If
134 
135 End Sub
136 
137 Private Function GetWndProcAddress(ByVal SinceCount As LongAs Long
138 '   地址指针 = GetWndProcAddress( SinceCount = 所有公用过程(例: Function,Sub,Property,公共变量) 总和 + 第 N 个 Private function/sub   )
139 '// 本例是取 MsgHook 函数地址, SinceCount 取值 12 ,可自行依例验证
140     Dim mePtr As Long
141     Dim jmpAddress As Long
142     mePtr = ObjPtr(Me)
143     CopyMemory jmpAddress, ByVal mePtr, 4
144     CopyMemory jmpAddress, ByVal jmpAddress + (SinceCount - 1) * 4 + &H1C, 4
145 
146     ReDim LinkProc(10)
147     LinkProc(0) = &H83EC8B55
148     LinkProc(1) = &HFC8B14EC
149     LinkProc(2) = &H56FC758D
150     LinkProc(3) = &H3308758D
151     LinkProc(4) = &HFC04B1C9
152     LinkProc(5) = &HFF68A5F3
153     LinkProc(6) = &HB8FFFFFF
154     LinkProc(7) = &HFFFFFFFF
155     LinkProc(8) = &H48BD0FF
156     LinkProc(9) = &H10C2C924
157     
158     CopyMemory ByVal VarPtr(LinkProc(5)) + 3, mePtr, 4
159     CopyMemory ByVal VarPtr(LinkProc(7)), jmpAddress, 4
160     GetWndProcAddress = VarPtr(LinkProc(0))
161     VirtualProtect ByVal VarPtr(LinkProc(0)), 44, &H40, mePtr
162 End Function
163 
164 Private Sub Class_Initialize()
165     
166     PG.n_HandleOfWindow = CreateWindowEx(0"button", vbNullString, &H40010F00, 001010, GetDesktopWindow&, ByVal 10&, App.hInstance, ByVal 0&)
167     
168     PG.n_NotifyData.uID = 1
169     PG.n_NotifyData.hwnd = PG.n_HandleOfWindow
170     PG.n_NotifyData.uCallbackMessage = WM_NOTIFYMESSAGE
171     PG.s_AddressOfWndProc = SetWindowLong(ByVal PG.n_HandleOfWindow, ByVal -4&, ByVal GetWndProcAddress(12))
172     PG.s_wm_TaskBarCreated = RegisterWindowMessage("TaskbarCreated")
173 End Sub
174 
175 Private Sub Class_Terminate()
176 
177     Debug.Print "Start !NotifyBar Terminate ..."Timer
178 
179     SetWindowLong PG.n_HandleOfWindow, -4&, PG.s_AddressOfWndProc
180     NotifyBoxVisible = False
181     DestroyWindow PG.n_HandleOfWindow
182     
183     Debug.Print "NotifyBar Terminate ... end "Timer
184     
185 End Sub
186 
187 Public Property Get Icon() As Long
188     '// Notify Icon
189     Icon = PG.n_NotifyData.hIcon
190 End Property
191 
192 Public Property Let Icon(ByVal vNewValue As Long)
193     
194     With PG.n_NotifyData
195         .uFlags = NIF_ICON Or .uFlags
196         .hIcon = vNewValue
197     End With
198     
199     If PG.n_NotifyData.cbSize Then
200         PG.n_NotifyData.uFlags = NIF_ICON
201         Shell_NotifyIcon NIM_MODIFY, PG.n_NotifyData
202     End If
203     
204 End Property
205 
206 Public Property Get HandleOfNotifybar() As Long
207     '// Notify hWnd
208     HandleOfNotifybar = PG.n_NotifyData.hwnd
209 End Property
210 
211 Public Property Let HandleOfNotifybar(ByVal vNewValue As Long)
212     
213     PG.n_NotifyData.hwnd = vNewValue
214     If PG.n_NotifyData.cbSize Then _
215             Shell_NotifyIcon NIM_MODIFY, PG.n_NotifyData
216     
217 End Property
218 
219 Public Property Get CallBackMessage() As Long
220     '// Notify uCallbackMessage
221     CallBackMessage = PG.n_NotifyData.uCallbackMessage
222 End Property
223 
224 Public Property Let CallBackMessage(ByVal vNewValue As Long)
225     
226     PG.n_NotifyData.uFlags = NIF_MESSAGE Or PG.n_NotifyData.uFlags
227     PG.n_NotifyData.uCallbackMessage = vNewValue
228     
229     If PG.n_NotifyData.cbSize Then
230         PG.n_NotifyData.uFlags = NIF_MESSAGE
231         Shell_NotifyIcon NIM_MODIFY, PG.n_NotifyData
232     End If
233     
234 End Property
235 
236 Public Property Get ToolTipText() As String
237     '// ToolTips
238     ToolTipText = PG.n_NotifyData.szTip
239 End Property
240 
241 Public Property Let ToolTipText(ByVal vNewValue As String)
242     
243     With PG.n_NotifyData
244         .uFlags = NIF_TIP Or .uFlags
245         .szTip = vNewValue & vbNullChar
246     End With
247     
248     If PG.n_NotifyData.cbSize Then
249         PG.n_NotifyData.uFlags = NIF_TIP
250         Shell_NotifyIcon NIM_MODIFY, PG.n_NotifyData
251     End If
252     
253 End Property
254 
255 Sub NotifyMsgBox(ByVal strMessage As String, Optional ByVal strTitle As String = "Application Notify", Optional ByVal NotifyMessageIcon As NotifyMessageIcons = NIIF_NONE)
256     
257     '// Notify MessageBox
258     With PG.n_NotifyData
259         .uFlags = NIF_INFO Or .uFlags
260         .szInfo = strMessage & vbNullChar
261         .szInfoTitle = strTitle & vbNullChar
262         .dwInfoFlags = NotifyMessageIcon
263     End With
264     
265     If PG.n_NotifyData.cbSize Then
266         PG.n_NotifyData.uFlags = NIF_INFO
267         Shell_NotifyIcon NIM_MODIFY, PG.n_NotifyData
268     End If
269 End Sub
270 
271 Public Property Get NotifyBoxVisible() As Boolean
272     '// Notify visible
273     If PG.n_NotifyData.cbSize Then NotifyBoxVisible = True
274 End Property
275 
276 Public Property Let NotifyBoxVisible(ByVal vNewValue As Boolean)
277     
278     If vNewValue Then
279         CallBackMessage = PG.n_NotifyData.uCallbackMessage
280         PG.n_NotifyData.cbSize = Len(PG.n_NotifyData)
281         Shell_NotifyIcon NIM_ADD, PG.n_NotifyData
282         
283     Else
284         PG.n_NotifyData.uFlags = 0
285         Shell_NotifyIcon NIM_DELETE, PG.n_NotifyData
286         PG.n_NotifyData.cbSize = 0
287     End If
288     
289 End Property

 

 

 一个托盘图标类, 包括:

    图标的动态更换、托盘气泡提示(多个类型)、工具提示、托盘图标重建、连带着把右键托盘菜单的问题一并加入解决;

自实现的窗口实现托盘消息管理

 

   NotifyBar

            .Icon(属性)                        托盘图标属性,直接赋值图标, 具体可参考实例代码; 动态换图标由调用端联合 Timer 配合 Icon 属性自己实现即可

            .HandleOfNotifybar(属性)    托盘图标的消息接受窗口句柄,这个窗口是自动创建的,非必须勿改,且如必须更改则应在显示图标之前调用此属性更改

            .CallBackMessage(属性)      自定义托盘消息,非需勿改,有默认值

            .ToolTipText(属性)              托盘图标的工具提示

            .NotifyMsgBox(方法)          托盘的气泡提示:  NotifyMsgBox (气泡通知内容, 气泡通知标题,气泡通知类型[包含4个类型的枚举,分别表示用不同的图标])

            .NotifyBoxVisible(属性)       启用/停用 托盘图标,如果需要对 HandleOfNotifybar、CallBackMessage 属性自定义修改,则应该在此属性之前调用

 

             NotifyClick (事件)              托盘图标鼠标事件,提供 MouseMove,LeftButtonClick,RightButtonClick,LBDoubleClick,4个事件

 

 

Private Sub sysNotifyBar_NotifyClick(NClickClass As NotifyClickClass, ByVal x As Long, ByVal y As Long)
    '//  托盘图标事件
    Select Case NClickClass
            Case NCL_MouseMove: Debug.Print “这是鼠标 MouseMove 事件”
            Case NCL_LeftButtonClick: Debug.Print “这是鼠标 左键点击 事件”                
            Case NCL_RightButtonClick: Debug.Print “这是鼠标 右键单击 事件”
            Case NCL_DoubleClick: Debug.Print “这是鼠标 左键双击 事件”

            '//Case   右键双击 因应用范围、方式等原因,该事件未提供, 如需要请自行修改 NotifyBar 类 MsgHook 过程的相关代码添加即可

    End Select
End Sub

 

 

一般情况下,使用时,最后调用  NotifyBoxVisible 属性将托盘图标显示出来即可; 所有属性都支持动态修改;

系统资源管理器崩溃后,托盘图标会按照 NotifyBar 最后一次的记录的属性自动重建托盘图标.

 

实例工程演示:

 

Download:

              

              https://files.cnblogs.com/pctgl/notifybar.rar

              https://files.cnblogs.com/pctgl/%E6%89%98%E7%9B%98%E5%9B%BE%E6%A0%87.rar

posted on 2012-09-07 03:10  PctGL  阅读(2005)  评论(0编辑  收藏  举报