小小鸭

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
'Explorer 崩溃重启后的任务栏图标重建

'在窗体中:
'**************************************************************************
'**模 块 名:工程1 - Form1
'**说    明:永远的魔灵 by icecept(郭卫)
'**创 建 人:icecept(魔灵)
'**日    期:2009-06-17 01:09:52
'**修 改 人:icecept(魔灵)
'**版    本:V1.0.0
'**E-mail  :icecept@163.com    QQ:543375508
'**网    址:http://hi.baidu.com/icecept       http://hi.csdn.net/icecept
'*************************************************************************
Option Explicit
Private Sub Form_Load()
    With nfIconData
        .hwnd = Me.hwnd
        .uId = Me.Icon
        .uCallBackMessage = WM_NOTIFYICON
        .uFlags = NIF_ICON Or NIF_INFO Or NIF_MESSAGE Or NIF_TIP
        .uCallBackMessage = WM_TRAYICON
        .hIcon = Me.Icon.Handle
        .szTip = App.Title + "(版本 " & App.Major & "." & App.Minor & "." & App.Revision & ")" & vbNullChar
        .cbSize = Len(nfIconData)
        .szInfoTitle = "欢迎" & vbNullChar
        .szInfo = "你好,我在这里哦" & vbNullChar
        .uTimeoutOrVersion = 10000
        .dwInfoFlags = NIIF_INFO
    End With
    '在托盘中添加图标
    Shell_NotifyIcon NIM_ADD, nfIconData
    pWndProc = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf WndProc)
    'explorer重启之后广播的一个 windows message 消息
    MsgTaskbarRestart = RegisterWindowMessage("TaskbarCreated")
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    On Error Resume Next
    Shell_NotifyIcon NIM_DELETE, nfIconData
    pWndProc = SetWindowLong(Me.hwnd, GWL_WNDPROC, pWndProc)
End Sub

在模块中:
'**************************************************************************
'**模 块 名:工程1 - Form1
'**说    明:永远的魔灵 by icecept(郭卫)
'**创 建 人:icecept(魔灵)
'**日    期:2009-06-17 01:09:52
'**修 改 人:icecept(魔灵)
'**版    本:V1.0.0
'**E-mail  :icecept@163.com    QQ:543375508
'**网    址:http://hi.baidu.com/icecept       http://hi.csdn.net/icecept
'--------------------------------------------------------------------------
'实现托盘图标
Public Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" _
                        (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
Public nfIconData As NOTIFYICONDATA
Public Const MAX_TOOLTIP As Integer = 64
' uFlags to NOTIFYICONDATA structure
Public Const NIF_MESSAGE = &H1
Public Const NIF_ICON = &H2
Public Const NIF_TIP = &H4
Public Const NIF_STATE = &H8
Public Const NIF_INFO = &H10
' dwMessage to Shell_NotifyIcon
Public Const NIM_ADD = &H0
Public Const NIM_MODIFY = &H1
Public Const NIM_DELETE = &H2
Public Const NIM_SETFOCUS = &H3
Public Const NIM_SETVERSION = &H4
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 SW_RESTORE = 9
Public Const SW_HIDE = 0
Public Type NOTIFYICONDATA
    cbSize As Long              ' 结构大小(字节)
    hwnd As Long                ' 处理消息的窗口的句柄
    uId As Long                 ' 唯一的标识符
    uFlags As Long              ' Flags
    uCallBackMessage As Long    ' 处理消息的窗口接收的消息
    hIcon As Long               ' 托盘图标句柄
    szTip As String * 128       ' Tooltip 提示文本
    dwState As Long             ' 托盘图标状态
    dwStateMask As Long         ' 状态掩码
    szInfo As String * 256      ' 气球提示文本
    uTimeoutOrVersion As Long   ' 气球提示消失时间或版本
    ' uTimeout - 气球提示消失时间(单位:ms, 10000 -- 30000)
    ' uVersion - 版本(0 for V4, 3 for V5)
    szInfoTitle As String * 64  ' 气球提示标题
    dwInfoFlags As Long         ' 气球提示图标
End Type

Public Const NIS_HIDDEN = &H1              ' 隐藏图标
Public Const NIS_SHAREDICON = &H2          ' 共享图标
Public Const NIIF_NONE = &H0               ' 无图标
Public Const NIIF_INFO = &H1               ' "消息"图标
Public Const NIIF_WARNING = &H2            ' "警告"图标
Public Const NIIF_ERROR = &H3              ' "错误"图标
Public Const NIIF_GUID = &H4
Public Const WM_USER = &H400
Public Const WM_NOTIFYICON = WM_USER + &H100
Public Const WM_TRAYICON = WM_USER + 123 '托盘消息
' 关于气球提示的自定义消息, 2000下不产生这些消息
Public Const NIN_BALLOONSHOW = (WM_USER + &H2)      ' 当 Balloon Tips 弹出时执行
Public Const NIN_BALLOONHIDE = (WM_USER + &H3)      ' 当 Balloon Tips 消失时执行(如 SysTrayIcon 被删除),
' 但指定的 TimeOut 时间到或鼠标点击 Balloon Tips 后的消失不发送此消息
Public Const NIN_BALLOONTIMEOUT = (WM_USER + &H4)   ' 当 Balloon Tips 的 TimeOut 时间到时执行
Public Const NIN_BALLOONUSERCLICK = (WM_USER + &H5) ' 当鼠标点击 Balloon Tips 时执行。
' 注意:在XP下执行时 Balloon Tips 上有个关闭按钮,
' 如果鼠标点在按钮上将接收到 NIN_BALLOONTIMEOUT 消息。
'实现托盘菜单自动消失功能
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 SetForegroundWindow Lib "user32" (ByVal hwnd 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 pWndProc As Long
'---------------------------------------------------------------
'RegisterWindowMessage获取分配给一个字串标识符的消息编号
'返回值Long,&C000 到 &FFFF之间的一个消息编号。零意味着出错
'参数 类型及说明
'lpString String,注册消息的名字
'注解如果没有一个子类处理程序的帮助,这个函数就没有什么用
Public Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageA" _
                        (ByVal lpString As String) As Long
Public MsgTaskbarRestart As Long
Public Function WndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    If Msg = WM_TRAYICON Then
        Select Case lParam
            Case WM_LBUTTONDOWN
            FrmAbout.Show 0
            Case WM_RBUTTONDOWN
            SetForegroundWindow hwnd '关键的一步,使菜单重画
            Case WM_RBUTTONUP
            Form1.PopupMenu Form1.mnuIndex  '显示系统菜单
        End Select
    End If
    'Explorer.exe 崩溃之后重建任务栏图标
    If Msg = MsgTaskbarRestart Then
        '原理:Explorer.exe 重新载入后会重建系统任务栏。当系统任务栏建立的时候会向系统内所有
        '注册接收TaskbarCreated 消息的顶级窗口发送一条消息,我们只需要捕捉这个消息,并重建系统托盘的图标即可。
        Shell_NotifyIcon NIM_ADD, nfIconData   '关键的一步,使图标重建
        WndProc = True
    End If
    WndProc = CallWindowProc(pWndProc, hwnd, Msg, wParam, lParam)
End Function

'原文地址:http://www.vbgood.com/viewthread.php?tid=61114&extra=&page=5

  

posted on 2012-06-30 22:45  小小鸭  阅读(809)  评论(0编辑  收藏  举报