Type Class_VScroll Extends Class_Control
    Declare Property Value() As Long                 '返回/设置滚动值
    Declare Property Value(ByVal bValue As Long)     '
    Declare Property nMax() As Long                 '返回/设置滚动条最大值
    Declare Property nMax(ByVal posMax As Long)     '
    Declare Property nMin() As Long                 '返回/设置滚动最小值
    Declare Property nMin(ByVal posMin As Long)     '
    Declare Property nPage() As Long                 '返回/设置页大小，比如类似 ListBox控件 可以显示多少行。=0 为自动调整。
    Declare Property nPage(ByVal bPage As Long)     '
    Declare Property SmallChange() As Long                 '返回/设置用户单击滚动条剪头时，滚动条 Value 属性改变的数量
    Declare Property SmallChange(ByVal bValue As Long)     '
    Declare Property LargeChange() As Long                 '返回/设置用户单击滚动条区域时，滚动条 Value 属性改变的数量
    Declare Property LargeChange(ByVal bValue As Long)     '
    Declare Function HandleScroll(hWndControl As hWnd, nScrollCode As Long, nPosition As Long) As long '处理滚动条消息，并且返回最新的当前位置值。由VFB系统调用然后发送给用户 Change 事件
End Type
      
'----------------------------------------------------------------------------------------------------------------------------------------------------------------


Property Class_VScroll.Value() As Long                 '返回/设置滚动值
  Return GetScrollPos(hWndControl, SB_CTL)
End Property
Property Class_VScroll.Value(ByVal bValue As Long)     '
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp = 0 then Return 
   if Len(fp->nData) = 0 Then fp->nData = String(24, 0)
   Dim vv As Long Ptr = Cast(Any Ptr, StrPtr(fp->nData))
   Dim ss As SCROLLINFO
   ss.cbSize = SizeOf(SCROLLINFO)
   ss.fMask = SIF_PAGE Or SIF_RANGE
   GetScrollInfo hWndControl, SB_CTL, @ss  '获取原来内容
   if vv[2] = 0 Then ss.nMax -= ss.nPage '得到实际最大值
   if bValue < ss.nMin Then bValue = ss.nMin
   if bValue > ss.nMax Then bValue = ss.nMax
   
   SetScrollPos(hWndControl, SB_CTL, bValue, True)
End Property
Property Class_VScroll.nMax() As Long                 '返回/设置滚动条最大值
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp = 0 then Return 0
   if Len(fp->nData) = 0 Then fp->nData = String(24, 0)
   Dim vv As Long Ptr = Cast(Any Ptr, StrPtr(fp->nData))
   Dim ss As SCROLLINFO
   ss.cbSize = SizeOf(SCROLLINFO)
   ss.fMask = SIF_PAGE Or SIF_RANGE
   GetScrollInfo hWndControl, SB_CTL, @ss  '获取原来内容
   if vv[2] = 0 Then ss.nMax -= ss.nPage '得到实际最大值
   Return ss.nMax
End Property
Property Class_VScroll.nMax(ByVal posMax As Long)
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp = 0 then Return 
   if Len(fp->nData) = 0 Then fp->nData = String(24, 0)
   Dim vv As Long Ptr = Cast(Any Ptr, StrPtr(fp->nData))
   Dim ss As SCROLLINFO
   ss.cbSize = SizeOf(SCROLLINFO)
   ss.fMask = SIF_PAGE Or SIF_RANGE
   GetScrollInfo hWndControl, SB_CTL, @ss  '获取原来内容
   if vv[2] = 0 Then ss.nMax -= ss.nPage '得到实际最大值
   if ss.nMin > posMax Then posMax = ss.nMin
   if vv[2] = 0 Then
      ss.nPage = (posMax - ss.nMin ) / 5  '重新计算页大小
      if ss.nPage = 0 Then ss.nPage = 1
      ss.nMax = posMax + ss.nPage   '需要多1页大小，拖动 滑框才能得到最大值，不然永远少1页。
   Else
      ss.nPage = vv[2]
      ss.nMax = posMax
   End if
   SetScrollInfo hWndControl, SB_CTL, @ss, TRUE
   'SendMessage(hWndControl, SBM_SETRANGEREDRAW, lpposMin, posMax)
End Property
Property Class_VScroll.nMin() As Long                 '返回/设置滚动最小值
  Dim lpposMin As Long, lpposMax As Long
  GetScrollRange(hWndControl, SB_CTL, @lpposMin, @lpposMax)
  Return lpposMin
End Property
Property Class_VScroll.nMin(ByVal posMin As Long)     '
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp = 0 then Return 
   if Len(fp->nData)= 0 Then  fp->nData = String(24,0) 
   Dim vv As Long Ptr = Cast(Any Ptr, StrPtr(fp->nData))   
   Dim ss As SCROLLINFO
   ss.cbSize = SizeOf(SCROLLINFO)
   ss.fMask = SIF_PAGE Or SIF_RANGE
   GetScrollInfo hWndControl, SB_CTL, @ss  '获取原来内容
   if vv[2] = 0 Then ss.nMax -= ss.nPage '得到实际最大值
   if posMin > ss.nMax Then posMin = ss.nMax
   if vv[2] = 0 Then 
      ss.nPage = (ss.nMax - posMin ) / 5  '根据最大和最小范围，重新计算页大小。
      if ss.nPage = 0 Then ss.nPage = 1
      ss.nMax += ss.nPage
   Else
      ss.nPage =vv[2]
   End if 
   ss.nMin = posMin
   SetScrollInfo hWndControl, SB_CTL, @ss, TRUE
   'SendMessage(hWndControl, SBM_SETRANGEREDRAW, posMin, lpposMax)
End Property
Property Class_VScroll.nPage() As Long 
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp = 0 then Return 0
   if Len(fp->nData)= 0 Then  fp->nData = String(24,0) 
   Dim vv As Long Ptr = Cast(Any Ptr, StrPtr(fp->nData))
   '0  SChange
   '1  LChange
   '2  nPage
  Return vv[2]
End Property
Property Class_VScroll.nPage(ByVal bPage As Long)
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp = 0 then Return 
   if Len(fp->nData) = 0 Then fp->nData = String(24, 0)
   Dim vv As Long Ptr = Cast(Any Ptr, StrPtr(fp->nData))
   Dim ss As SCROLLINFO
   ss.cbSize = SizeOf(SCROLLINFO)
   ss.fMask = SIF_PAGE Or SIF_RANGE
   GetScrollInfo hWndControl, SB_CTL, @ss  '获取原来内容
   if vv[2] = 0 Then ss.nMax -= ss.nPage  '原来是自动设置，需要复原 最大值。
   if bPage > (ss.nMax - ss.nMin +1) Then bPage = (ss.nMax - ss.nMin +1)
   vv[2] = bPage
   if bPage = 0 Then  '自动处理
      ss.nPage = (ss.nMax - ss.nMin ) / 5  '根据最大和最小范围，重新计算页大小。
      if ss.nPage = 0 Then ss.nPage = 1
      ss.nMax += ss.nPage
   Else
      ss.nPage = bPage
   end if
   SetScrollInfo hWndControl, SB_CTL, @ss, TRUE
End Property

Property Class_VScroll.SmallChange() As Long    
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp = 0 then Return 0
   if Len(fp->nData)= 0 Then  fp->nData = String(24,0) 
   Dim vv As Long Ptr = Cast(Any Ptr, StrPtr(fp->nData))
   '0  SChange
   '1  LChange
   '2  nPage
  Return vv[0]           
End Property
Property Class_VScroll.SmallChange(ByVal bValue As Long)     '
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp = 0 then Return 
   if Len(fp->nData)= 0 Then  fp->nData = String(24,0) 
   Dim vv As Long Ptr = Cast(Any Ptr, StrPtr(fp->nData))
   '0  SChange
   '1  LChange
   '2  nPage
  vv[0] = bValue   
End Property
Property Class_VScroll.LargeChange() As Long    
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp = 0 then Return 0
   if Len(fp->nData)= 0 Then  fp->nData = String(24,0) 
   Dim vv As Long Ptr = Cast(Any Ptr, StrPtr(fp->nData))
   '0  SChange
   '1  LChange
   '2  nPage
  Return vv[1]            
End Property
Property Class_VScroll.LargeChange(ByVal bValue As Long)     '
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp = 0 then Return 
   if Len(fp->nData)= 0 Then  fp->nData = String(24,0) 
   Dim vv As Long Ptr = Cast(Any Ptr, StrPtr(fp->nData))
   '0  SChange
   '1  LChange
   '2  nPage
  vv[1]  = bValue    
End Property
Function Class_VScroll.HandleScroll(hControl As hWnd, nScrollCode As Long, nPosition As Long) As Long   '
   Dim fp As FormControlsPro_TYPE ptr = GetPropW(hWndControl, "FCP_TYPE_PTR")
   if fp = 0 then Return 0
   if Len(fp->nData) = 0 Then fp->nData = String(24, 0)
   Dim vv As Long Ptr = Cast(Any Ptr, StrPtr(fp->nData))
   '0  SChange
   '1  LChange
   '2  nPage
   Dim As Long nPos,jMin, jMax
   'GetScrollRange(hControl, SB_CTL, @jMin, @jMax)
   nPos = GetScrollPos(hControl, SB_CTL)
   Dim ss As SCROLLINFO
   ss.cbSize = SizeOf(SCROLLINFO)
   ss.fMask = SIF_PAGE Or SIF_RANGE Or SIF_POS
   GetScrollInfo hWndControl, SB_CTL, @ss  '获取原来内容
   nPos = ss.nPos
   jMin = ss.nMin
   if vv[0] = 0 Then jMax = ss.nMax - ss.nPage Else jMax = ss.nMax
   'nScrollCode = SB_LINELEFT  SB_LINERIGHT  SB_PAGELEFT  SB_PAGERIGHT  SB_THUMBPOSITION SB_THUMBTRACK  SB_ENDSCROLL   SB_LEFT     SB_RIGHT
   ''             SB_LINEUP    SB_LINEDOWN   SB_PAGEUP    SB_PAGEDOWN   SB_THUMBPOSITION SB_THUMBTRACK  SB_ENDSCROLL   SB_TOP      SB_BOTTOM
   '点击向上按钮 点击向下按钮  点击滑块上面 点击滑块下面  托动滑块结束     托动滑块进行中 结束滚动条操作 滚动到顶部  滚动到底部
   Select Case nScrollCode
      Case SB_LINEUP '点击向上按钮
         If nPos - vv[0] >= jMin Then nPos -= vv[0]
         SetScrollPos(hControl, SB_CTL, nPos, 1)
      Case SB_LINEDOWN '点击向下按钮
         If nPos + vv[0] <= jMax Then nPos += vv[0]
         SetScrollPos(hControl, SB_CTL, nPos, 1)
      Case SB_PAGEUP '点击滑块上面空白处
         If nPos > jMin + vv[1] Then
            nPos -= vv[1]
         Else
            nPos = jMin
         End If
         SetScrollPos(hControl, SB_CTL, nPos, 1)
      Case SB_PAGEDOWN '点击滑块下面空白处
         If nPos < jMax - vv[1] Then
            nPos += vv[1]
         Else
            nPos = jMax
         End If
         SetScrollPos(hControl, SB_CTL, nPos, 1)
      Case SB_THUMBPOSITION '托动滑块 鼠标放开后
         
      Case SB_THUMBTRACK '托动滑块 同时 nPosition 是托动后的位置
         if nPosition > jMax Then nPosition = jMax
         SetScrollPos(hControl, SB_CTL, nPosition, 1)
         nPos = nPosition
      Case SB_TOP
      Case SB_BOTTOM
      Case SB_ENDSCROLL ' 结束滚动  不管点了什么地方，只要放开鼠标，就是这个
         
      Case Else
         
   End Select
   Function = nPos
End Function
