Private Sub Form_Load()
  '隐藏窗体
  With Me
          .Top = -10000
          .Left = -10000
          .WindowState = vbMinimized
End With
  '设置类型NOTIFYICONDATA所具有的特征
  With nidProgramData
          .cbSize = Len(nidProgramData)
          .hwnd = Me.hwnd
          .uID = vbNull
          .uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
          '触发鼠标移动消息
          .uCallbackMessage = WM_MOUSEMOVE
          .hIcon = Me.Icon
          '“托盘”中放入窗体图标,你可以把窗体的图标换成你所喜欢的图标
          .szTip = "VB   的   Win32   API   编程" & vbNullChar
  End With
   
  '调用该函数
  Shell_NotifyIcon NIM_ADD, nidProgramData
  
  End Sub
  '根据不同的鼠标消息做不同的操作
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, x As Single, Y As Single)  On Error GoTo Form_MouseMove_err:
  Dim Result As Long
  Dim msg As Long
  'X的值依赖与显示模式的设置
  If Me.ScaleMode = vbPixels Then
          msg = x
  Else
          msg = x / Screen.TwipsPerPixe1X
  End If
  Select Case msg
          Case WM_LBUTTONUP
          '在这里加入鼠标左键释放时你想做的操作
          Case WM_LBUTTONDBLCLK
          '在这里加入双击鼠标左键时你想做的操作
          Case WM_RBUTTONUP
          '通常这里弹出你的功能菜单
          PopupMenu mainMenu
          Case WM_MOUSEISMOVING
          '在这里加入鼠标正在移动时你想做的操作
          End Select
  Exit Sub
   
Form_MouseMove_err:
  '在这里加入你的处理异常错误的代码End Sub模块里内容:'常量声明
   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           '响应您定义的热键
  'API函数声明
Public Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
Public Type NOTIFYICONDATA
        cbSize As Long
        hwnd As Long
        uID As Long
        uFlags As Long '使那些参数有效它是以下枚举类型中的
  'NIF_MESSAGE、NIF_ICON、NIF_TIP三组的组合
        uCallbackMessage As Long
        hIcon As Long
        szTip As String * 64
End Type'这是一个枚举类型它告诉API   Shell_NotifyIcon去做什么操作
  Public Enum enm_NIM_Shell
  NIM_ADD = &H40       '在“金碟”中加一图标
  NIM_MODIFY = &H1       '修改“金碟”中的图标
  NIM_DELETE = &H2       '删除“金碟”中的图标
  NIF_MESSAGE = &H1       '使类型"NOTIFYICONDATA"中的uCallbackMessage有效
  NIF_ICON = &H2       '使类型"NOTIFYICONDATA"中的hIcon有效
  NIF_TIP = &H4       '使类型"NOTIFYICONDATA"中的szTip有效
  WM_MOUSEMOVE = &H200       '使鼠标移动消息有效
  End Enum
  '定义一个"NOTIFYICONDATA"类型的变量
  Public nidProgramData As NOTIFYICONDATA
上面的源代码中WM_MOUSEMOVE = &H200 执行时出现过二义性,我注释了
'WM_MOUSEMOVE = &H200       '使鼠标移动消息有效才能运行,但为何RUN后却看不见时间边上没有出现它的系统托盘?还有,我注释了下面语句
  '隐藏窗体
  With Me
          .Top = -10000
          .Left = -10000
          .WindowState = vbMinimized
End With
运行后鼠标移动到窗口上会出现.TwipsPerPixe1X编译错误 未找到方法或数据成员。这个程序问题怎么这么多,另外求个最简单易懂一定能够运行的托盘程序源代码,郁闷3天了,一定要搞定,先谢谢了

解决方案 »

  1.   

    '该模块用于最小化到托盘
    Option ExplicitConst NIM_ADD = 0 '加入图标到系统状态区中
    Const NIM_MODIFY = 1 '修改系统状态区的图标
    Const NIM_DELETE = 2 '删除系统状态区的图标Const NIF_MESSAGE = 1 '消息
    Const NIF_ICON = 2 '设置图标
    Const NIF_TIP = 4 '提示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 TypeDeclare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long '建立系统状态区的图标Const GWL_WNDPROC = (-4) '窗口函数的地址
    Const WM_USER = &H400
    Const WM_MOUSEFIRST = &H200 '鼠标移动时发生,比 WM_MOUSEMOVE 要早
    Const WM_MOUSEMOVE = &H200 '鼠标移动时发生
    Const WM_LBUTTONDOWN = &H201 '鼠标左键按下时发生
    Const WM_LBUTTONUP = &H202 '鼠标左键放开时发生
    Const WM_LBUTTONDBLCLK = &H203 '鼠标左键双击时发生
    Const WM_RBUTTONDOWN = &H204 '鼠标右键按下时发生
    Const WM_RBUTTONUP = &H205 '鼠标右键放开时发生
    Const WM_RBUTTONDBLCLK = &H206 '鼠标右键双击时发生
    Const WM_MBUTTONDOWN = &H207 '中间键按下时发生
    Const WM_MBUTTONUP = &H208 '中间键放开时发生
    Const WM_MBUTTONDBLCLK = &H209 '中间键双击时发生
    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 '将消息传送给指定的窗口
    Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long '取得窗口消息
    Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long '设置窗口消息Dim tray_win As Long '保存窗口的变量
    Dim tray_nid As NOTIFYICONDATA '定义系统区图标
    Dim tray_IsWinAddress As Boolean '是否取得窗口信息的判断
    Const uId = 9998
    Const tray_uMessage = WM_USER + 100'Msg 传过来的是区域(如果工作区、标题区、系统状态区等等) lParam 传过来的是消息(如鼠标左键点击、右键点击等等) wParam 自己感觉没有多大的用处,通过前面传过来的信息,进行判断处理
    Function trayWndProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    If Msg = WM_USER + 100 Then
    Select Case lParam '下面是大部分的鼠标操作,你可根据所需的事件,定义自己的操作
    Case WM_MOUSEFIRST '鼠标移动时发生,比 WM_MOUSEMOVE 要早Case WM_MOUSEMOVE '鼠标移动时发生Case WM_LBUTTONDOWN '鼠标左键按下时发生Case WM_LBUTTONUP '鼠标左键放开时发生Case WM_LBUTTONDBLCLK '鼠标左键双击时发生Case WM_RBUTTONDOWN '鼠标右键按下时发生Case WM_RBUTTONUP '鼠标右键放开时发生Case WM_RBUTTONDBLCLK '鼠标右键双击时发生Case WM_MBUTTONDOWN '中间键按下时发生Case WM_MBUTTONUP '中间键放开时发生Case WM_MBUTTONDBLCLK '中间键双击时发生End Select
    End If
    trayWndProc = CallWindowProc(tray_win, hWnd, Msg, wParam, lParam) '将消息传送给指定的窗口
    End FunctionFunction SetTrayIcon(ByVal Icon As Long, ByVal Tip As String, ByVal Action As String)
    If tray_IsWinAddress = False Then '判断是否需要取得、设置窗口信息,如果重复取得、设置,将会造成程序死掉
    tray_win = GetWindowLong(frmMain.hWnd, GWL_WNDPROC) '取得(备份)窗口信息
    SetWindowLong frmMain.hWnd, GWL_WNDPROC, AddressOf trayWndProc '设置新的窗口信息
    End Iftray_nid.cbSize = Len(tray_nid) '取数据结构的长度设置给 cbSize
    tray_nid.hWnd = frmMain.hWnd '设置图标的句柄,这里为本窗口的
    tray_nid.uId = 9999
    tray_nid.uFlags = NIF_ICON + NIF_TIP + NIF_MESSAGE '设置图标、提示、消息
    tray_nid.hIcon = Icon '图标
    tray_nid.szTip = Tip + Chr(0) '图标提示
    tray_nid.ucallbackMessage = tray_uMessageSelect Case Action
    Case "Add"
    Shell_NotifyIcon NIM_ADD, tray_nid '加入图标到系统状态区中
    Case "Del"
    Shell_NotifyIcon NIM_DELETE, tray_nid '删除系统区的图标
    Case "Modi"
    Shell_NotifyIcon NIM_MODIFY, tray_nid '修改系统区的图标
    Case "Exit"
    Shell_NotifyIcon NIM_DELETE, tray_nid '删除系统区的图标
    SetWindowLong frmMain.hWnd, GWL_WNDPROC, tray_win '恢复窗口信息
    End Select
    tray_IsWinAddress = True '不需要再取得窗口信息
    End Function
      

  2.   

    发现自己好笨,楼上给的模块在form_load中如何调用阿
      

  3.   

    SetTrayIcon me.icon,me.caption,"Add"
      

  4.   

    最后几个问题,一定结分。
    问题1:
    Const uId = 9998
    Const tray_uMessage = WM_USER + 100 tray_nid.hWnd = frmMain.hWnd  '设置图标的句柄,这里为本窗口的
    tray_nid.uId = 9999 
    为何定义9998和9999,uId有什么具体解释?还有9997、9996、9995....?问题2:
    WM_USER+100中的"+100"是何意思?问题3:
    主窗口frmMain上添加了一级菜单mainMenu,二级菜单退出(mnuExt)
    如何在点托盘图标Case WM_RBUTTONUP  '鼠标右键放开时发生 后弹出预定义的菜单mainMenu?
      

  5.   

    用以传入NOTIFYICONDATA数据结构变量,其结构如下所示:
    Type NOTIFYICONDATA
      cbSize As Long        需填入NOTIFYICONDATA数据结构的长度
      HWnd As Long         设置成窗口的句柄 
      Uid As Long         为图标所设置的ID值
      UFlags As Long        设置uCallbackMessage,hIcon,szTip是否有效
      UCallbackMessage As Long   消息编号
      HIcon As Long         显示在状态栏上的图标
      SzTip As String * 64     提示信息
    End Type
    仔细看看,就能理解了.Const uId = 9998在后面的代码中都没用到.
      

  6.   

    第一个问题不知道...没查过,不过MSDN里应该有解释;第二个,是一个用户定义消息,MS好象是说规定WM_USER以上的值给用户使用...貌似直到65535?只要你加上你的值,就行了....那个值以下的是由系统使用的.不过严格来说,这个代码里这样使用是不规范的...应该在消息ID确定后,再注册消息,注册成功后才使用,不成功就继续加数字,再注册...直到成功不然要是正好有别的程序也使用WM_USER+100这个值作为一个程序自定义的消息ID,会冲突到时会发生什么,谁也说不准...
      

  7.   

    了解了,结分
    顺便给出1楼代码原始版链接
    http://support.microsoft.com/kb/162613/zh-cn