'自己写的托盘程序:运行后点击command1,托盘区出现图标,窗体隐藏;右键单击托盘区的图标,弹出菜单,点击恢复后窗体恢复正常大小;如果再次点击command1,窗体最小化到托盘区,可是此时如果将鼠标放到托盘区的图标上,程序会自动退出。思前想后,找不到问题出在哪里,请各位高手帮忙看看,谢谢!'一个form1,一个module1
'form1包括一个command1,一个弹出菜单,弹出菜单有两个按钮(恢复mnuPopR和退出mnuPopE)'窗体form1程序为:
Private Sub Command1_Click()
Me.Hidexn.uFlags = NIF_ICON Or NIF_MESSAGE Or NIF_TIP
Shell_NotifyIcon NIM_ADD, xnDebug.Print xn.cbSize
Debug.Print xn.hIcon
Debug.Print xn.hwnd
Debug.Print xn.szTip
Debug.Print xn.uCallbackMessage
Debug.Print xn.uFlags
Debug.Print xn.uID
Call OldProc
End SubPrivate Sub Form_Load()
xn.cbSize = Len(xn)
xn.hIcon = Me.Icon.Handle
xn.hwnd = Me.hwnd
xn.szTip = "Good" & vbNullChar
xn.uCallbackMessage = TRAY_CALLBACK
xn.uID = 0If Me.WindowState = vbMinimized Then
    LastState = vbNormal
Else
    LastState = Me.WindowState
End If
End Sub
Private Sub mnuPopE_Click()
Shell_NotifyIcon NIM_DELETE, xnSendMessage Me.hwnd, WM_SYSCOMMAND, SC_CLOSE, 0&
DefWindowProc Me.hwnd, Msg, wParam, lParamEnd SubPrivate Sub mnuPopR_Click()
SendMessage Me.hwnd, WM_SYSCOMMAND, SC_RESTORE, 0&Shell_NotifyIcon NIM_DELETE, xn
xn.uFlags = NIF_ICON Or NIF_MESSAGE Or NIF_TIP
DefWindowProc Me.hwnd, Msg, wParam, lParam
End Sub'module1的程序为:
Public Declare Function IsIconic Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) 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 Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As LongPublic 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
Public Const NIM_ADD = &H0
Public Const NIM_DELETE = &H2
Public Const NIM_MODIFY = &H1
Public Const SC_RESTORE = &HF120&
Public Const NIF_ICON = &H2
Public Const NIF_MESSAGE = &H1
Public Const NIF_TIP = &H4
Public Const GWL_WNDPROC = (-4)
Public Const WM_USER = &H400
Public Const TRAY_CALLBACK = WM_USER + 1001&
Public Const WM_SYSCOMMAND = &H112
Public Const SC_CLOSE = &HF060&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_SETHOTKEY = &H32      'ÏìÓ¦Äú¶¨ÒåµÄÈȼü
Public OldWindowProc As Long
Public xn As NOTIFYICONDATA
Public LastState As Integer
Public Function NewWindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
If Msg = TRAY_CALLBACK Then
    If lParam = WM_MOUSEMOVE Then
        xn.uFlags = NIF_TIP
        Shell_NotifyIcon NIM_MODIFY, xn
    End If
    If lParam = WM_LBUTTONUP Then
        If Form1.WindowState = vbMinimized Then
            Form1.WindowState = LastState
            Form1.SetFocus
            Exit Function
        End If
    End If
    
    If lParam = WM_RBUTTONUP Then
        Form1.PopupMenu Form1.mnuPop
        Exit Function
    End If
End If
NewWindowProc = CallWindowProc(OldWindowProc, hwnd, Msg, wParam, lParam)
End Function
Public Sub OldProc()
OldWindowProc = SetWindowLong(Form1.hwnd, GWL_WNDPROC, AddressOf NewWindowProc)End Sub

解决方案 »

  1.   

    谢谢,但是我把对xn赋值的部分移到command1_click中,还是不行
    改过后的程序就几行,请大家帮忙看看源代码吧,这个程序我已经折腾了一个月了
    form1:
    Private Sub Command1_Click()
        Me.Hide
        xn.cbSize = Len(xn)
        xn.hIcon = Me.Icon.Handle
        xn.hwnd = Me.hwnd
        xn.szTip = "Good" & vbNullChar
        xn.uCallbackMessage = TRAY_CALLBACK
        xn.uID = 0
        
        xn.uFlags = NIF_ICON Or NIF_MESSAGE Or NIF_TIP
        Shell_NotifyIcon NIM_ADD, xn
        
        Debug.Print xn.hwnd
        Call OldProc
    End SubPrivate Sub Form_Unload(Cancel As Integer)
        Shell_NotifyIcon NIM_DELETE, xn
    End SubPrivate Sub mnuPopE_Click()
        Shell_NotifyIcon NIM_DELETE, xn
        SendMessage Me.hwnd, WM_SYSCOMMAND, SC_CLOSE, 0&
    End SubPrivate Sub mnuPopR_Click()
        Shell_NotifyIcon NIM_DELETE, xn
        SendMessage Me.hwnd, WM_SYSCOMMAND, SC_RESTORE, 0&
    End SubModule1:
    Public OldWindowProc As Long
    Public xn As NOTIFYICONDATA
    Public Function NewWindowProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        If Msg = TRAY_CALLBACK Then
            If lParam = WM_MOUSEMOVE Then
                xn.uFlags = NIF_TIP
                Shell_NotifyIcon NIM_MODIFY, xn
            End If
       
            If lParam = WM_RBUTTONUP Then
                Form1.PopupMenu Form1.mnuPop
                Exit Function
            End If
        End If
        NewWindowProc = CallWindowProc(OldWindowProc, hwnd, Msg, wParam, lParam)
    End Function
    Public Sub OldProc()
       OldWindowProc = SetWindowLong(Form1.hwnd, GWL_WNDPROC, AddressOf NewWindowProc)End Sub
      

  2.   

    '看看这个例子http://community.csdn.net/Expert/topic/3669/3669461.xml?temp=.8736383