VB6程序开机自启驻留托盘后无法唤起窗体,求右键菜单实现方案
VB6托盘图标唤起窗体及右键菜单实现方案
问题分析
你原有的Form_MouseMove代码无法生效,因为托盘图标是通过系统API创建的,不属于窗体的鼠标事件范围,必须通过处理Shell_NotifyIcon的回调消息来响应托盘图标的鼠标操作。
完整实现步骤
1. 添加标准模块(Module1.bas)
复制以下代码到模块中,包含托盘图标所需的API声明和结构体:
Option Explicit Public Const WM_USER = &H400 Public Const WM_NOTIFYICON = WM_USER + 20 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 Public Const WM_LBUTTONUP = &H202 Public Const WM_RBUTTONUP = &H205 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 Public Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long Public Declare Function TrackPopupMenu Lib "user32" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal X As Long, ByVal Y As Long, ByVal nReserved As Long, ByVal hwnd As Long, ByVal lprc As Any) As Long Public Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long Public Type POINTAPI X As Long Y As Long End Type
2. 窗体代码修改
假设你的窗体名为Form1,替换原代码为以下内容:
Option Explicit Private nid As NOTIFYICONDATA Private Sub Form_Load() ' 初始化托盘图标 With nid .cbSize = Len(nid) .hwnd = Me.hwnd .uID = vbNull .uFlags = NIF_MESSAGE Or NIF_ICON Or NIF_TIP .uCallbackMessage = WM_NOTIFYICON .hIcon = Me.Icon.Handle .szTip = "你的程序名称" & vbNullChar End With Shell_NotifyIcon NIM_ADD, nid ' 启动时最小化到托盘 Me.WindowState = vbMinimized Me.Hide End Sub Private Sub Form_Unload(Cancel As Integer) ' 退出时删除托盘图标 Shell_NotifyIcon NIM_DELETE, nid End Sub Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) ' 处理窗体最小化到托盘 If Button = vbLeftButton And Me.WindowState = vbMinimized Then Me.Hide End If End Sub Private Sub WndProc(ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) Dim pt As POINTAPI Dim hMenu As Long If Msg = WM_NOTIFYICON Then Select Case lParam Case WM_LBUTTONUP ' 左键点击托盘图标,恢复窗体 Me.WindowState = vbNormal Me.Show SetForegroundWindow Me.hwnd Case WM_RBUTTONUP ' 右键点击托盘图标,弹出菜单 GetCursorPos pt hMenu = Me.MenuHandle TrackPopupMenu hMenu, 0, pt.X, pt.Y, 0, Me.hwnd, 0 End Select End If Call DefWindowProc(Me.hwnd, Msg, wParam, lParam) End Sub ' 必须添加这个函数声明到窗体 Private Declare Function DefWindowProc Lib "user32.dll" Alias "DefWindowProcA" (ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
3. 添加右键菜单
按Ctrl+E打开菜单编辑器,创建一个顶级菜单(名称设为mnuTray,可见性设为False),再添加两个子菜单:
- 名称
mnuOpen,标题打开 - 名称
mnuClose,标题关闭
然后添加菜单点击事件代码:
Private Sub mnuOpen_Click() Me.WindowState = vbNormal Me.Show SetForegroundWindow Me.hwnd End Sub Private Sub mnuClose_Click() Unload Me End Sub
关键说明
- 托盘图标的操作必须通过
Shell_NotifyIconAPI实现,回调消息WM_NOTIFYICON用于接收托盘的鼠标事件 - 左键点击托盘直接唤起窗体,右键点击弹出自定义菜单
- 退出程序时务必删除托盘图标,避免残留
内容的提问来源于stack exchange,提问作者Kush Tiwari
相关产品推荐
相关产品推荐

