Type Class_TrayIco
Private : 
   m_hWndForm As HWnd '控件句柄
   m_IDC As Long '控件IDC
   m_Msg As uLong 
   m_Tip as CWSTR
   m_ResImg As String
   m_Ok As Boolean  '是不是创建了提示
   Declare Function GetFP() As FormControlsPro_TYPE ptr '返回控件保存数据的指针（一般是类自己用）
Public : 
   Declare Constructor
   Declare Destructor
   Declare Property hWndForm() As.hWnd         '返回/设置控件所在的窗口句柄，主要用于多开同一个窗口后，要使用控件前，必须先指定控件所在的窗口句柄，才能正常使用控件。
   Declare Property hWndForm(ByVal hWndParent As.hWnd) '获取控件所在的窗口句柄（父窗口）
   Declare Property IDC() As Long             '返回/设置控件IDC，控件标识符，1个窗口里每个控件IDC都是唯一的，包括控件数组。（不可随意修改，系统自动处理）
   Declare Property IDC(NewIDC As Long)
   Declare Property Tag() As CWSTR                       '存储程序所需的附加数据。
   Declare Property Tag(ByVal sText As CWSTR)
   Declare Function Create() As Boolean '创建托盘图标，如果成功，则返回TRUE，否则返回FALSE。
   Declare Property CallMsg() As uLong             '返回/设置消息值，是：WM_User + 消息值，用于本控件事件值，万一与其它冲突，可以修改此值。不同控件必须不同值。
   Declare Property CallMsg(wMsg As uLong)
   Declare Property Tips() As CWSTR             '返回/设置 鼠标指向图标时提示的内容
   Declare Property Tips(nTip As CWSTR)
   Declare Property ResImg() As String      '返回/设置 图像资源名，就是在图像管理器中的名称
   Declare Property ResImg(nResImg As String)
   Declare Function Del() As Boolean '删除托盘图标，如果成功，则返回TRUE，否则返回FALSE。
   
End Type

'----------------------------------------------------------------------------------------------------------------------------------------------------------------
Constructor Class_TrayIco
   '注意：由于窗口类是永久的，全局变量，因此这里从开软件到关软件只执行1次。
End Constructor

Destructor Class_TrayIco
   '注意：由于窗口类是永久的，全局变量，因此为了可以完成特殊功能，Destructor 会重复执行
   '1，每次窗口销毁  就执行1次 Destructor  ，多次显示和关窗口就重复操作
   '2，退出软件  执行1次 Destructor
  This.Del
   
End Destructor
Function Class_TrayIco.GetFP() As FormControlsPro_TYPE ptr '返回自己控件的指针
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(m_hWndForm, "FCP_TYPE_PTR")
   While fp
      if fp->IDC = m_IDC Then Return fp      
      fp = fp->VrControls
   Wend

End Function
Property Class_TrayIco.hWndForm() As .hWnd         '返回/设置控件所在的窗口句柄
      Return m_hWndForm
End Property
Property Class_TrayIco.hWndForm(ByVal hWndParent As .hWnd)
   m_hWndForm = hWndParent
End Property
Property Class_TrayIco.CallMsg() As uLong      
      Return m_Msg
End Property
Property Class_TrayIco.CallMsg(wMsg As uLong)
   m_Msg = wMsg
   if m_Ok Then This.Create
End Property
Property Class_TrayIco.IDC() As Long   
   Return m_IDC
End Property
Property Class_TrayIco.IDC(ByVal NewIDC As Long)
   m_IDC = NewIDC
   if m_Ok Then  This.Create
End Property
Property Class_TrayIco.Tips() As CWSTR 
   Return m_Tip
End Property
Property Class_TrayIco.Tips(nTip As CWSTR)
   m_Tip = nTip
   if m_Ok Then
      Dim ti as NOTIFYICONDATAW
      ti.cbSize = SizeOf(ti)
      ti.HWnd = m_hWndForm
      ti.uID = m_IDC '图标号，其它用什么都可以，只是取消时要记得用同样的号，就可以了。
      ti.uFlags = NIF_TIP
      ti.szTip = m_Tip     '提示
      Shell_NotifyIconW NIM_MODIFY, @ti
   End if
End Property
Property Class_TrayIco.ResImg() As String 
   Return m_ResImg
End Property
Property Class_TrayIco.ResImg(nResImg As String)
   m_ResImg = nResImg
   if m_Ok Then
      Dim ti as NOTIFYICONDATAW
      ti.cbSize = SizeOf(NOTIFYICONDATAW)
      ti.HWnd = m_hWndForm
      ti.uID = m_IDC '图标号，其它用什么都可以，只是取消时要记得用同样的号，就可以了。
      ti.uFlags = NIF_ICON
      Dim nIcon As HICON, nResImg As String = m_ResImg
      if instr(nResImg, "RCDATA_") = 1 Then
         nIcon = AfxGdipIconFromRes(App.hInstance, ResImg)
      Elseif instr(nResImg, "BITMAP_") = 1 Then
         Dim nBmp As HBITMAP = LoadImageA(app.hInstance, ResImg, IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR)
         Dim po As ICONINFO
         po.fIcon = TRUE
         po.hbmColor = nBmp
         po.hbmMask = nBmp
         nIcon = CreateIconIndirect(@po)
         DeleteObject nBmp
      Elseif instr(nResImg, "ICON_") = 1 Then
         nIcon = LoadImageA(app.hInstance, ResImg, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR)  '从资源里加载图标
      End if
      ti.hIcon = nIcon
      Shell_NotifyIcon NIM_MODIFY, @ti
      DestroyIcon ti.HICON
   End if
End Property
Function Class_TrayIco.Create() As Boolean '创建一个托盘图标，如果成功，则返回TRUE，否则返回FALSE。
   if m_Ok Then This.Del
   Dim ti as NOTIFYICONDATAW
   ti.cbSize = SizeOf(NOTIFYICONDATAW)
   ti.HWnd = m_hWndForm
   ti.uID = m_IDC '图标号，其它用什么都可以，只是取消时要记得用同样的号，就可以了。
   ti.uFlags = NIF_ICON Or NIF_MESSAGE Or NIF_TIP
   ti.uCallbackMessage = WM_User + m_Msg ' 向窗口发送的消息，可以自己定，只要与接受到的处理相同就可以了
   Dim nIcon As HICON, nResImg As String = m_ResImg
   if instr(nResImg, "RCDATA_") = 1 Then
      nIcon = AfxGdipIconFromRes(App.hInstance, ResImg)
   Elseif instr(nResImg, "BITMAP_") = 1 Then
      Dim nBmp As HBITMAP = LoadImageA(app.hInstance, ResImg, IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR)
      Dim po As ICONINFO
      po.fIcon = TRUE
      po.hbmColor = nBmp
      po.hbmMask = nBmp
      nIcon = CreateIconIndirect(@po)
      DeleteObject nBmp
   Elseif instr(nResImg, "ICON_") = 1 Then
      nIcon = LoadImageA(app.hInstance, ResImg, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR)  '从资源里加载图标
   End if
   ti.hIcon = nIcon
   ti.szTip = m_Tip     '提示
   m_Ok = Shell_NotifyIconW(NIM_ADD, @ti) ' '加入任务栏图标
   DestroyIcon nIcon '销毁一个图标并且释放该图标所占用的内存；
   Function = m_Ok
End Function
Function Class_TrayIco.Del() As Boolean '删除托盘图标，如果成功，则返回TRUE，否则返回FALSE。
   if m_Ok Then
      Dim ti as NOTIFYICONDATAW
      ti.cbSize = SizeOf(NOTIFYICONDATAW)
      ti.HWnd = m_hWndForm
      ti.uID = m_IDC '图标号，其它用什么都可以，只是取消时要记得用同样的号，就可以了。
      Function = Shell_NotifyIconW(NIM_DELETE, @ti)
      m_Ok = FALSE
   Else
      Function = TRUE
   End if
End Function















