Type Class_StatusBar
Private : 
   hWndControl As.HWnd '控件句柄
   m_IDC As Long     '控件IDC
Public : 
   Declare Constructor
   Declare Destructor
   Declare Property HWnd() As.HWnd                    '返回/设置控件句柄
   Declare Property HWnd(ByVal hWndNew As.HWnd)
   Declare Property hWndForm() As.HWnd         '用于多开窗口时，要使用控件前，必须先指定控件的父句柄
   Declare Property hWndForm(ByVal hWndParent As.HWnd)         '用于多开窗口时，要使用控件前，必须先指定控件的父句柄
   Declare Property Text(iPart As Long) As CWSTR                  '返回/设置文本。从0开始的索引 (文本前面是 WChr(9)为中间对齐，Wchr(9,9)为右对齐)
   Declare Property Text(iPart As Long, nText As CWSTR)
   Declare Property TipText(iPart As Long) As CWSTR                  '返回/设置工具提示文本 从0开始的索引
   Declare Property TipText(iPart As Long, nText As CWSTR)
   Declare Property Icon(iPart As Long) As HICON          '返回/设置在状态栏中的图标。iPart：从0开始的索引,如果成功返回图标的句柄，否则为 NULL。
   Declare Property Icon(iPart As Long, nIcon As HICON)  '如果设置图标的值为 NULL，将从 iPart 中删除该图标。
   Declare Sub MinHeight(nHeight As Long) ' 设置状态窗口的绘图区域的最小高度。（以像素为单位）
   
   Declare Property BackColor(clrBk As Long)      '设置状态栏背景色。如果颜色背景为默认颜色 =CLR_DEFAULT 。
   Declare Function GetPartsCount() As Long               '返回部件总数
   Declare Property TextDrawingMode(iPart As Long) As Long   '检索用于绘制文本操作的类型。
   Declare Property TextDrawingMode(iPart As Long, uType As Long)
   Declare Property Font() As String          '返回/设置用于在控件中绘制文本的字体，格式为：字体,字号,加粗,斜体,下划线,删除线  中间用英文豆号分割，可以省略参数 默认为：宋体,9,0,0,0,0  自动响应系统DPI创建字体大小。
   Declare Property Font(nFont As String)     '操作字体句柄用 WM_SETFONT WM_GETFONT 发消息给控件即可
   
   Declare Property Enabled() As Boolean                 '返回/设置控件是否允许操作。{=.True.False}
   Declare Property Enabled(ByVal bValue As Boolean)
   Declare Property Visible() As Boolean                 '显示或隐藏控件。{=.True.False}
   Declare Property Visible(ByVal bValue As Boolean)
   Declare Property Tag() As CWSTR                      '存储程序所需的附加数据。
   Declare Property Tag(ByVal sText As CWSTR)
   Declare Function Left() As Long                   '返回相对于父窗口的 X（像素）
   Declare Function Top() As Long                  '返回相对于父窗口的 Y（像素）
   Declare Function Width() As Long                '返回控件宽度（像素）
   Declare Function Height() As Long               '返回控件高度（像素）
   Declare Property IDC() As Long             '返回/设置控件IDC，控件标识符，1个窗口里每个控件IDC都是唯一的，包括控件数组。（不可随意修改，系统自动处理）
   Declare Property IDC(NewIDC As Long)
   Declare Function AddPane(zText As CWStr, zTipText As CWStr = "", uType As Long = 0, nWidth as Long = 0, ResImg As String = "") As Long  '多窗格 新增窗格，返回新添加的索引（从0开始）,失败返回 -1 {3.0 绘制的文本带有边框，显示为低于窗口的平面。.SBT_NOBORDERS 绘制的文本没有边框。.SBT_OWNERDRAW 自绘.SBT_POPOUT 绘制的文本带有边框，看起来比窗口的平面高。.SBT_RTLREADING 文本将以与父窗口中的文本相反的方向显示。.SBT_NOTABPARSING 制表符将被忽略。}
   Declare Function RemovePane(nIndex As Long) As Long  '删除一个窗格,从0开始的索引，返回剩余窗格数 ,失败返回 0  ,窗格数最小为1 ，最后1个不可以删除
   Declare Sub SetSize() '重新设置多窗格大小，当主窗口大小被改变就自动调用这个，不需要我们写代码调用。
   Declare Sub SetFocus()  ' 使控件获取键盘焦点
End Type

'----------------------------------------------------------------------------------------------------------------------------------------------------------------
Constructor Class_StatusBar
    '注意：由于窗口类是永久的，全局变量，因此为了可以完成特殊功能，Constructor 和 Destructor 会重复执行
   '1，开启软件后创建了窗口类，执行1次 Constructor
   '2，每 xxForm.Show 就执行1次 Constructor
   '3，每次窗口销毁  就执行1次 Destructor  ，多次显示和关窗口就重复 2，3 操作
   '4，退出软件  执行1次 Destructor   
End Constructor

Destructor Class_StatusBar
   if IsWindow(hWndControl) Then 
      Dim u As Long = This.GetPartsCount
      if u > 0 Then 
         Dim nIcon As HICON
         Dim i As Long 
         For i=0 To u-1  
            nIcon = This.Icon(i)
            if nIcon Then DestroyIcon nIcon
         Next 
      End if 
   End if  
End Destructor
Property Class_StatusBar.HWnd() As.HWnd                    '句柄
  Return hWndControl
End Property
Property Class_StatusBar.HWnd(ByVal hWndNew As.HWnd)        '句柄
  hWndControl = hWndNew
  m_IDC = GetDlgCtrlID(hWndNew)
End Property
Property Class_StatusBar.IDC() As Long
  Return m_IDC
End Property
Property Class_StatusBar.IDC(NewIDC As Long)  
   m_IDC = NewIDC 
End property
Property Class_StatusBar.hWndForm() As.HWnd         '用于多开窗口时，要使用控件前，必须先指定控件的父句柄
  Return GetParent(hWndControl)
End Property
Property Class_StatusBar.hWndForm(ByVal hWndParent As.HWnd)         '用于多开窗口时，要使用控件前，必须先指定控件的父句柄
  hWndControl = GetDlgItem(hWndParent,m_IDC)
End Property
Property Class_StatusBar.Enabled() As Boolean                 '使能
  Return IsWindowEnabled(hWndControl)
End Property
Property Class_StatusBar.Enabled(ByVal bValue As Boolean)
  EnableWindow(hWndControl, bValue)
End Property
Property Class_StatusBar.Tag() As CWSTR
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   If fp  Then
      Return fp->Tag
   End If
End Property
Property Class_StatusBar.Tag(ByVal sText As CWSTR)
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   If fp  Then
      fp->Tag = sText
   End If  
End Property
Function Class_StatusBar.Left() As Long                '
  Dim rc As Rect
  GetWindowRect hWndControl, @rc          '获得窗体大小
  MapWindowPoints HWND_DESKTOP, GetParent(hWndControl), Cast(LPPOINT, @rc), 2
  Return rc.Left
End Function

Function Class_StatusBar.Top() As Long     '
  Dim rc As Rect
  GetWindowRect hWndControl, @rc     '获得窗体大小
  MapWindowPoints HWND_DESKTOP, GetParent(hWndControl), Cast(LPPOINT, @rc), 2
  Return rc.Top
End Function

Function Class_StatusBar.Height() As Long                  '
  Dim rc As Rect
  GetWindowRect hWndControl, @rc          '获得窗体大小
  Return  rc.Bottom - rc.Top
End Function

Function Class_StatusBar.Width() As Long
  Dim rc As Rect
  GetWindowRect hWndControl, @rc          '获得窗体大小
  Return rc.Right - rc.Left
End Function

Property Class_StatusBar.Visible() As Boolean                 '可见
  Return IsWindowVisible(hWndControl)
End Property
Property Class_StatusBar.Visible(ByVal bValue As Boolean)
  If bValue Then
      ShowWindow(hWndControl, SW_SHOW)
  Else
      ShowWindow(hWndControl, SW_HIDE)
  End If
End Property
Property Class_StatusBar.Text(iPart As Long) As CWSTR                  '返回/设置文本。
   Dim nLen   As Long
   Dim bb As String 
   nLen = LoWord( SendMessageW (hWndControl, SB_GETTEXTLENGTH, iPart, 0) ) +1
   bb = String(nLen *2 ,0) 'ensure room for the trailing $Nul
   SendMessageW hWndControl, SB_GETTEXT, iPart, Cast(lParam, StrPtr(bb))
   dim cw as CWSTR = *CPtr(WString Ptr ,StrPtr(bb))
   Return  cw 
End Property
Property Class_StatusBar.Text(iPart As Long, nText As CWSTR)
   Dim Pane_Type As Long = This.TextDrawingMode(iPart)
   SendMessageW(hWndControl, SB_SETTEXT, iPart or Pane_Type, Cast(lParam, nText.vptr))
   InvalidateRect hWndControl, 0, True
   UpdateWindow hWndControl
End Property
Property Class_StatusBar.TipText(iPart As Long) As CWSTR                  '返回/设置工具提示文本
  Dim bb As WString *2049
  Dim nSize As Long = 2048
  SendMessageW(hWndControl, SB_GETTIPTEXT, MAKELONG(iPart, nSize), Cast(lParam, @bb))
  Return bb
End Property
Property Class_StatusBar.TipText(iPart As Long, nText As CWSTR)
   SendMessageW hWndControl, SB_SETTIPTEXT, iPart, Cast(lParam, nText.vptr)
End Property
Property Class_StatusBar.Icon(iPart As Long) As HICON          '返回/设置在状态栏中的图标。
  Return Cast(HICON , SendMessage (hWndControl, SB_GETICON, iPart, 0) )
End Property
Property Class_StatusBar.Icon(iPart As Long, nIcon As HICON)  '如果设置图标的值为 NULL，将从 iPart 中删除该图标。
   Dim Pane_Ico As HICON = This.Icon(iPart)
   if Pane_Ico Then DeleteObject Pane_Ico
   SendMessage(hWndControl, SB_SETICON, iPart, Cast(lParam, nIcon))
End Property
Property Class_StatusBar.BackColor(clrBk As Long)        '在状态栏中设置的背景色。返回前一种背景颜色，如果颜色背景为默认颜色 =CLR_DEFAULT 。
   Dim cc As Long = GetCodeColorGDI(clrBk)
   if cc = -1 Then GetSysColor(COLOR_BTNFACE)
   SendMessage(hWndControl, SB_SETBKCOLOR, 0, cc)
End Property
Function Class_StatusBar.GetPartsCount() As Long               '返回部件总数
   Function=SendMessage (hWndControl, SB_GETPARTS, 0, 0)
End Function
Property Class_StatusBar.TextDrawingMode(iPart As Long) As Long   '检索用于绘制文本操作的类型。
   Dim dwResult As Long
   dwResult = SendMessage (hWndControl, SB_GETTEXTLENGTH, iPart, 0)
   Return HiWord(dwResult)
'   返回值：
'
'      值       意义
'-------------- -------------------------------------------------------
'0               与要显示边框绘制文本低于窗口的飞机。
'SBT_NOBORDERS   无边界绘制文本。
'SBT_OWNERDRAW   由父窗口绘制文本。
'SBT_POPOUT      文本绘制带边框显示窗口的飞机比高。
'SBT_RTLREADING  显示文本在希伯来语或阿拉伯语的系统上使用从右向左的阅读顺序。
End Property
Property Class_StatusBar.TextDrawingMode(iPart As Long, uType As Long)
   Dim Pane_Text As CWSTR = This.Text(iPart)
   SendMessageW(hWndControl, SB_SETTEXT, iPart or uType, Cast(lParam, Pane_Text.vptr))
   InvalidateRect hWndControl, 0, True
   UpdateWindow hWndControl
End Property
Sub Class_StatusBar.MinHeight(nHeight As Long ) ' 设置状态窗口的绘图区域的最小高度。（以像素为单位）
   SendMessage(hWndControl, SB_SETMINHEIGHT, nHeight, 0)
   SendMessage(hWndControl, WM_SIZE, SIZE_RESTORED, 0)
End Sub
Function Class_StatusBar.AddPane(zText As CWStr, zTipText As CWStr = "", uType As Long = 0, nWidth as Long = 0, ResImg As String = "") As Long  '多窗格 新增窗格，
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp then
      Dim u As Long = Len(fp->nData) / 4
      If u < 256 Then
         ReDim Pane_Width(u) As Long
         if u > 0 Then memcpy @Pane_Width(0), StrPtr(fp->nData), u * 4
         Pane_Width(u) = nWidth
         fp->nData = Space((u + 1) * 4)
         memcpy StrPtr(fp->nData), @Pane_Width(0), (u + 1) * 4
         This.SetSize() '重新设置多窗格大小
         Dim nIcon As HICON  ,nResImg As String = 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
         This.Icon(u) = nIcon
         SendMessageW(hWndControl, SB_SETTEXT, u or uType, Cast(lParam, zText.vptr))
         This.TipText(u) = zTipText
         InvalidateRect hWndControl, 0, True
         UpdateWindow hWndControl
      End If
      Function = u
   Else
      Function = -1
   End If
   
End Function
Function Class_StatusBar.RemovePane(nIndex As Long) As Long  '删除一个窗格，返回剩余窗格数
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp then
      Dim u As Long = Len(fp->nData) / 4 -1
      If u > 0 And nIndex > -1 And nIndex <= u Then
         Dim i As Long
         Dim Pane_Text(u) As CWSTR, Pane_TipText(u) As CWSTR, Pane_Type(u) As Long, Pane_Width(u) As Long, Pane_Ico(u) As HICON
         For i = 0 To u
            Pane_Text(i) = This.Text(i)
            Pane_TipText(i) = This.TipText(i)
            Pane_Type(i) = This.TextDrawingMode(i)
            Pane_Ico(i) = This.Icon(i)
         Next
         memcpy @Pane_Width(0), StrPtr(fp->nData), (u + 1) * 4
         if nIndex < u Then
            For i = nIndex To u -1
               Pane_Text(i) = Pane_Text(i + 1)
               Pane_TipText(i) = Pane_TipText(i + 1)
               Pane_Type(i) = Pane_Type(i + 1)
               Pane_Width(i) = Pane_Width(i + 1)
               Pane_Ico(i) = Pane_Ico(i + 1)
            Next
         End if
         u = u -1
         ReDim Preserve Pane_Text(u), Pane_TipText(u), Pane_Type(u), Pane_Width(u), Pane_Ico(u)
         fp->nData = Space((u + 1) * 4)
         memcpy StrPtr(fp->nData), @Pane_Width(0), (u + 1) * 4
         This.SetSize() '重新设置多窗格大小
         For i = 0 To u
            SendMessageW hWndControl, SB_SETTEXT, i or Pane_Type(i), Cast(LPARAM, Pane_Text(i).vptr)
            SendMessage hWndControl, SB_SETICON, i, Cast(LPARAM, Pane_Ico(i))
            If Len(Pane_TipText(i)) then SendMessage hWndControl, SB_SETTIPTEXT, i, Cast(LPARAM, Pane_TipText(i).vptr)
         Next
      End if
      InvalidateRect hWndControl, 0, True
      UpdateWindow hWndControl
       Function = U + 1
   End If

End Function
Sub Class_StatusBar.SetSize() '重新设置多窗格大小，当主窗口大小被改变就自动调用这个，不需要我们写代码调用。
   If IsWindow(hWndControl) = 0 Then Return
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp then
      Dim u As Long = Len(fp->nData) / 4
      if u = 0 Then Return
      Dim FLY_Rect As Rect
      SendMessage hWndControl, WM_SIZE, 0, 0
      GetClientRect hWndControl, @FLY_Rect
      Dim As Long SP(u-1) , i ,t ,m = FLY_Rect.Right
      Dim Pane_Width As Long Ptr = cast(Any Ptr, StrPtr(fp->nData))
      
      For i = 0 To u -1
         if Pane_Width[i] <= 0 Then t += m / (u - i) Else t += AfxScaleX(Pane_Width[i])
         m = FLY_Rect.Right - t '剩余
         if m < 1 Then m = 1
         sp(i) = t
      Next
      SendMessage hWndControl, SB_SETPARTS, u, Cast(LPARAM, @sp(0))
      
      
   End If
End Sub
Property Class_StatusBar.Font() As String                   '返回/设置用于在控件中绘制文本的字体
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp then
       Return fp->nFont 
   End If
End Property
Property Class_StatusBar.Font(nFont As String)
   Dim nMargins As Long
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp then
      fp->nFont = nFont
      SendMessageA  hWndControl, WM_SETFONT, Cast(wParam, gFLY_GetFontHandles(nFont)), True
   End If
   
End Property
Sub Class_StatusBar.SetFocus()  ' 获取键盘焦点
     .SetFocus hWndControl
End Sub