Type Class_ListView Extends Class_Control
Protected : 
   m_ReDraw As Boolean  '修改列表时是否允许刷新
   nColumn     As Integer  '点击排序的列
   SortOrder   As Integer  ' 排序方向
   Declare Sub DrawHeaderArrow(ByVal pColumn As Integer, ByVal pSortOrder As Integer)
Public : 
   Declare Constructor
   Declare Destructor
   Declare Function AddItem (ColText as CWSTR, ParamL As lParam = 0, iImage As Long = 0) As Long  '新增项(1行)，返回新的项的索引，ColText 是0列文本，其它文本用 SetItemText 设置。
   Declare Sub AddItemCount(nCount As Long)  '予分配项目数量内存，避免每次新增分配，速度过慢。
   Declare Function InsertItem(iRow As Long, ColText As CWSTR , ParamL As lParam = 0, iImage As Long = 0) As Long  '在iRow行插入项(1行)，返回新的项的索引，ColText 是0列文本，其它文本用 SetItemText 设置。
   Declare Function DeleteAllItems() As Long '删除所有项目。
   Declare Function DeleteItem(iRow As Long) As Long  '删除项目(删除第iRow行)。如果成功返回 TRUE 否则为 FALSE
   Declare Function ItemCount() As Long   '项目数(多少行)
   Declare Function GetItemText(iRow As Long, iColumn As Long) As CWSTR '返回列表项的文本(索引从0开始)(支持宽字符的火星文)
   Declare Function SetItemText(iRow As Long, iColumn As Long, TheText As CWSTR) As Long  '设置列表项的文本(索引从0开始)(支持宽字符的火星文)
   Declare Property ItemData(iRow As Long) As Integer '返回/设置第iR+++++++++++++++++++++++++++++++ow行关联的 值
   Declare Property ItemData(iRow As Long, nlParam As Integer)
   Declare Property ItemImage(iRow As Long) As Long '返回/设置第iRow行图像索引
   Declare Property ItemImage(iRow As Long, iImage As Long)
   Declare Property Checked(iRow As Long) As Boolean '返回/设置第iRow行复选框状态，{=.True.False}
   Declare Property Checked(iRow As Long, nCheckState As Boolean)
   Declare Property SelectedItem() As Long '返回/设置当前选择项（索引从零开始）
   Declare Property SelectedItem(nIndex As Long)
   Declare Sub SelectAllItems()  '选择ListView控件的所有项目。
   Declare Sub UnselectItem(iIndex As Long) '取消选择ListView项目。
   Declare Sub UnselectAllItems()   '取消选择所有ListView项目。
   Declare Sub ColumnToSort(lpNMV As NM_LISTVIEW Ptr) '点列名排序操作，在LVN_ColumnClick事件里调用即可。
   Declare Function AddColumn(TheText As CWSTR, nAlignment As Long = LVCFMT_LEFT, nWidth As Long = 100) As Long  '新增列（标题）,{2.LVCFMT_CENTER 文本居中.LVCFMT_LEFT 左对齐.LVCFMT_RIGHT 右对齐},成功返回新列的索引，否则为-1
   Declare Function InsertColumn(iPosition As Long, TheText As CWSTR, nAlignment As Long = LVCFMT_LEFT, nWidth As Long = 100) As Long  '插入一列（标题）,{3.LVCFMT_CENTER 文本居中.LVCFMT_LEFT 左对齐.LVCFMT_RIGHT 右对齐},成功返回新列的索引，否则为-1
   Declare Function DeleteAllColumn() As Long  '删除所有列（标题）。
   Declare Function DeleteColumn(iPosition As Long) As Long '删除1列(索引从0开始)。成功返回 TRUE 否则为 FALSE
   Declare Function ColumnCount() As Long  '返回多少列数。（标题）。
   Declare Property ColumnText(iRow As Long) As CWSTR '列标题的文本(索引从0开始)
   Declare Property ColumnText(iRow As Long, sText As CWSTR)
   Declare Property ColumnAlignment(iRow As Long) As Long '返回/设置文本对齐方式。(索引从0开始),{=.LVCFMT_CENTER 文本居中.LVCFMT_LEFT 左对齐.LVCFMT_RIGHT 右对齐}
   Declare Property ColumnAlignment(iRow As Long, nAlignment As Long)
   Declare Property ColumnWidth(iRow As Long) As Long '返回/设置列的宽度。(索引从0开始)
   Declare Property ColumnWidth(iRow As Long, nWidth As Long)
   
   Declare Function CountPerPage() As Long '可见区域项的数目（可以显示多少行）。
   Declare Function TopIndex() As Long '列表或报表视图中时最顶层的可见项的索引。
   Declare Function ScrollSelectedItem() As Long '滚动到当前选择的项目
   Declare Function FindString(fs As CWSTR) As Long '搜索列表视图项目文本。搜寻不区分大小写。成功时返回该项目的索引，否则返回-1。
   Declare Function FitContent(iCol As Long) As Long '自动调整列表视图控件的指定列的大小。成功返回TRUE，否则返回FALSE。
   Declare Function Scroll(dx As Long, dy As Long) As Long '水平和垂直滚动量（像素）。成功返回TRUE，否则返回FALSE。
   Declare Property ImageList(ImageListType As Long) As Handle '返回/设置关联的图像列表对象，LVSIL_NORMAL 大图标,LVSIL_SMALL 小图标,LVSIL_STATE 状态图像
   Declare Property ImageList(ImageListType As Long, hImageList As HIMAGELIST)
   Declare Property ReDraw() As Boolean         '设置重绘标志，大量新增项目时关闭重绘，避免控件闪耀和提高速度。{=.True.False}
   Declare Property ReDraw(nValue As Boolean)    '修改项目时是否允许刷新，（注意：多开窗口中的控件，多窗口用同1个控件类，返回此值可能不正确）
   Declare Function ColumnsWidthSave(FileIni As String , nName As String) As Boolean   '在INI文件里保存所有列的宽度。成功返回 True (通常在窗口销毁事件里)
   Declare Sub ColumnsWidthLoad(FileIni As String, nName As String)  '从INI文件里加载所有列的宽度，来列宽，需要先新增列。 (通常在窗口加载事件里)
   
End Type
   Declare Function Class_ListView_CompareFunc(ByVal index1 As Long, ByVal index2 As Long, ByVal JPL As UInteger Ptr ) As Long

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

Destructor Class_ListView
  
End Destructor
Function Class_ListView.AddColumn(TheText As CWSTR, nAlignment As Long = LVCFMT_LEFT, nWidth As Long = 100) As Long
  '新增列（标题）,LVCFMT_CENTER 文本居中,LVCFMT_LEFT 左对齐,LVCFMT_RIGHT 右对齐,成功返回新列的索引，否则为-1
  Dim u As Long = This.ColumnCount
  Function = This.InsertColumn(u, TheText, nAlignment, nWidth)
End Function
Function Class_ListView.InsertColumn(iPosition As Long, TheText As CWSTR, nAlignment As Long = LVCFMT_LEFT, nWidth As Long = 100) As Long
  '插入一列（标题）,LVCFMT_CENTER 文本居中,LVCFMT_LEFT 左对齐,LVCFMT_RIGHT 右对齐,成功返回新列的索引，否则为-1
  Dim tlvc As LV_COLUMNW
  '检查窗口句柄是否有效
  If IsWindow(hWndControl) Then
      tlvc.mask = LVCF_FMT Or LVCF_WIDTH Or LVCF_TEXT Or LVCF_SUBITEM
      tlvc.fmt = nAlignment
      tlvc.cx = nWidth
      tlvc.pszText = TheText.vptr 
      tlvc.iSubItem = 0
      Function = SendMessageW(hWndControl, LVM_INSERTCOLUMN, iPosition, Cast(lParam, VarPtr(tlvc)))
  End If
End Function
Function Class_ListView.DeleteAllColumn() As Long  '删除所有列（标题）。
  '检查窗口句柄是否有效
  If IsWindow(hWndControl) Then
      Do Until ListView_DeleteColumn(hWndControl, 0) = 0
      Loop
  End If
  Return 0
End Function
Function Class_ListView.DeleteColumn(iPosition As Long) As Long '删除1列(索引从0开始)。成功返回 TRUE 否则为 FALSE
  '检查窗口句柄是否有效
  If IsWindow(hWndControl) Then
      Function = ListView_DeleteColumn(hWndControl, iPosition)
  End If
End Function
Function Class_ListView.ColumnCount() As Long  '返回多少列数。（标题）。
  Dim hWndLVHdr As.hWnd
  '// get the header control
  hWndLVHdr = Cast(.hWnd, SendMessage(hWndControl, LVM_GETHEADER, 0, 0))
  '// return the number of items in the header (ie. the number of columns).
  Function = SendMessage(hWndLVHdr, HDM_GETITEMCOUNT, 0, 0)
End Function
Property Class_ListView.ColumnText(iRow As Long) As CWSTR '列标题的文本(索引从0开始)
  Dim tlvc  As LV_COLUMNW
  Dim zText As wString * MAX_PATH
  '检查窗口句柄是否有效
  If IsWindow(hWndControl) Then
      tlvc.mask = LVCF_TEXT
      tlvc.pszText = VarPtr(zText)
      tlvc.cchTextMax = SizeOf(zText)
      If SendMessageW(hWndControl, LVM_GETCOLUMN, iRow, Cast(lParam, VarPtr(tlvc))) Then
          Return zText
      End If
  End If
End Property
Property Class_ListView.ColumnText(iRow As Long, sText As CWSTR)
  Dim tlvc As LV_COLUMNW
  '检查窗口句柄是否有效
  If IsWindow(hWndControl) Then
      tlvc.mask = LVCF_TEXT
      tlvc.pszText = sText.vptr
      SendMessageW(hWndControl, LVM_SETCOLUMN, iRow, Cast(lParam, VarPtr(tlvc)))
  End If
End Property
Property Class_ListView.ColumnAlignment(iRow As Long) As Long
  Dim tlvc As LV_COLUMN
  '检查窗口句柄是否有效
  If IsWindow(hWndControl) Then
      tlvc.mask = LVCF_FMT
      If SendMessage(hWndControl, LVM_GETCOLUMN, iRow, Cast(lParam, VarPtr(tlvc))) Then
          If (tlvc.fmt And LVCFMT_RIGHT) = LVCFMT_RIGHT Then
              Return LVCFMT_RIGHT
          End If
          If (tlvc.fmt And LVCFMT_CENTER) = LVCFMT_CENTER Then
              Return LVCFMT_CENTER
          End If
          If (tlvc.fmt And LVCFMT_LEFT) = LVCFMT_LEFT Then
              Return LVCFMT_LEFT
          End If
      End If
  End If
End Property
Property Class_ListView.ColumnAlignment(iRow As Long, nAlignment As Long)
  Dim tlvc As LV_COLUMN
  '检查窗口句柄是否有效
  If IsWindow(hWndControl) Then
      tlvc.mask = LVCF_FMT
      tlvc.fmt = nAlignment
      SendMessage(hWndControl, LVM_SETCOLUMN, iRow, Cast(lParam, VarPtr(tlvc)))
  End If
End Property
Property Class_ListView.ColumnWidth(iRow As Long) As Long '返回/设置列的宽度。(索引从0开始)
  Return ListView_GetColumnWidth(hWndControl, iRow)
End Property
Property Class_ListView.ColumnWidth(iRow As Long, nWidth As Long)
  ListView_SetColumnWidth(hWndControl, iRow, nWidth)
End Property
Function Class_ListView.AddItem (ColText as CWSTR, ParamL As lParam = 0, iImage As Long = 0) As Long '新增项(1行)，返回新的项的索引。
   Dim iRow As Long = This.ItemCount
   Function = This.InsertItem(iRow, ColText, ParamL, iImage)
End Function
Function Class_ListView.InsertItem(iRow As Long, ColText As CWSTR, ParamL As lParam = 0, iImage As Long = 0) As Long  '在iRow行插入项(1行)，返回新的项的索引。
   Dim tlv_item As LV_ITEMW
   '检查窗口句柄是否有效
   If IsWindow(hWndControl) Then
      tlv_item.iSubItem = 0
      tlv_item.pszText = ColText.vptr
      tlv_item.iImage = iImage
      tlv_item.lParam = ParamL
      tlv_item.mask = LVIF_TEXT Or LVIF_PARAM Or LVIF_IMAGE
      tlv_item.iItem = iRow
      Function = SendMessageW(hWndControl, LVM_INSERTITEMW, 0, Cast(lParam, VarPtr(tlv_item)))
   Else
      Function = -1
   End If
   
End Function
Function Class_ListView.DeleteAllItems() As Long '删除所有项目。
  Function = SendMessage(hWndControl, LVM_DELETEALLITEMS, 0, 0)
End Function
Function Class_ListView.DeleteItem(iRow As Long) As Long '删除项目(删除第iRow行)。如果成功返回 TRUE 否则为 FALSE
  Function = ListView_DeleteItem(hWndControl, iRow)
End Function
Function Class_ListView.ItemCount()  As Long '项目数(多少行)
  Function = SendMessage(hWndControl, LVM_GETITEMCOUNT, 0, 0)
End Function
Function Class_ListView.GetItemText(iRow As Long, iColumn As Long) As CWSTR '返回/设置列表项的文本(索引从0开始)
  Dim tlv_item As LV_ITEMW
  Dim zText    As wString * MAX_PATH
  '检查窗口句柄是否有效
  If IsWindow(hWndControl) Then
      tlv_item.mask = LVIF_TEXT
      tlv_item.iItem = iRow
      tlv_item.iSubItem = iColumn
      tlv_item.pszText = VarPtr(zText)
      tlv_item.cchTextMax = SizeOf(zText)
      If SendMessageW(hWndControl, LVM_GETITEMW, 0, Cast(lParam, VarPtr(tlv_item))) Then
          Return zText
      End If
  End If
End Function
Function Class_ListView.SetItemText(iRow As Long, iColumn As Long, TheText As CWSTR) As Long
  Dim tlv_item As LV_ITEMW
  '检查窗口句柄是否有效
  If IsWindow(hWndControl) Then
      tlv_item.mask = LVIF_TEXT
      tlv_item.iItem = iRow
      tlv_item.iSubItem = iColumn
      tlv_item.pszText = TheText.vptr 
      tlv_item.cchTextMax = Len(TheText)
      Return SendMessageW(hWndControl, LVM_SETITEMW, 0, Cast(lParam, VarPtr(tlv_item)))
  End If
End Function
Property Class_ListView.ItemData(iRow As Long) As Integer  '返回/设置第iRow行关联的 32 位值
  Dim tlv_item As LV_ITEM
  '检查窗口句柄是否有效
  If IsWindow(hWndControl) Then
      tlv_item.mask = LVIF_PARAM
      tlv_item.iItem = iRow
      tlv_item.iSubItem = 0
      If SendMessage(hWndControl, LVM_GETITEM, 0, Cast(lParam, VarPtr(tlv_item))) Then
          Return tlv_item.lParam
      End If
  End If
End Property
Property Class_ListView.ItemData(iRow As Long, lParam As Integer )
  Dim tlv_item As LV_ITEM
  '检查窗口句柄是否有效
  If IsWindow(hWndControl) Then
      tlv_item.mask = LVIF_PARAM
      tlv_item.iItem = iRow
      tlv_item.iSubItem = 0
      tlv_item.lParam = lParam
      SendMessage(hWndControl, LVM_SETITEM, 0, Cast(.lParam, VarPtr(tlv_item)))
  End If
End Property
Property Class_ListView.ItemImage(iRow As Long) As Long '返回/设置第iRow行图像索引
  Dim tlv_item As LV_ITEM
  '检查窗口句柄是否有效
  If IsWindow(hWndControl) Then
      tlv_item.mask = LVIF_IMAGE
      tlv_item.iItem = iRow
      tlv_item.iSubItem = 0
      If SendMessage(hWndControl, LVM_GETITEM, 0, Cast(lParam, VarPtr(tlv_item))) Then
          Return  Cast(Long, tlv_item.iImage)
      End If
  End If
End Property
Property Class_ListView.ItemImage(iRow As Long, iImage As Long)
  Dim tlv_item As LV_ITEM
  '检查窗口句柄是否有效
  If IsWindow(hWndControl) Then
      tlv_item.mask = LVIF_IMAGE
      tlv_item.iItem = iRow
      tlv_item.iSubItem = 0
      tlv_item.iImage = iImage
      SendMessage(hWndControl, LVM_SETITEM, 0, Cast(lParam, VarPtr(tlv_item)))
  End If
End Property
Property Class_ListView.Checked(iRow As Long) As Boolean '返回/设置第iRow行复选框状态，非0为选择
  Return ListView_GetCheckState(hWndControl, iRow)
End Property
Property Class_ListView.Checked(iRow As Long, nCheckState As Boolean)
  If nCheckState <> 0 Then nCheckState = 1
  ListView_SetCheckState(hWndControl, iRow, nCheckState)
End Property
Property Class_ListView.SelectedItem() As Long '返回/设置当前选择项（索引从零开始）
  Return SendMessage(hWndControl, LVM_GETSELECTIONMARK, 0, 0)
End Property
Property Class_ListView.SelectedItem(nIndex As Long)
  '检查窗口句柄是否有效
  If IsWindow(hWndControl) Then
      SendMessage(hWndControl, LVM_SETSELECTIONMARK, 0, nIndex)
      
      'ensure that the item is set visually as well
      Dim tItem As LVITEM
      tItem.mask = LVIF_STATE
      tItem.iItem = nIndex
      tItem.iSubItem = 0
      tItem.State = LVIS_FOCUSED Or LVIS_SELECTED
      tItem.statemask = LVIS_FOCUSED Or LVIS_SELECTED
      SendMessage hWndControl, LVM_SETITEMSTATE, nIndex, Cast(lParam, VarPtr(tItem))
  End If
End Property
Property Class_ListView.ImageList(ImageListType As Long) As Handle
  Return ListView_GetImageList(hWndControl, ImageListType)
End Property
Property Class_ListView.ImageList(ImageListType As Long, nImageList As HIMAGELIST)
  ListView_SetImageList(hWndControl, nImageList, ImageListType)
End Property
Sub Class_ListView.SelectAllItems()  '选择ListView控件的所有项目。
  ListView_SelectAllItems hWndControl
End Sub
Sub Class_ListView.UnselectItem(iIndex As Long)  '取消选择ListView项目。
  ListView_UnselectItem  hWndControl, iIndex
End Sub
Sub Class_ListView.UnselectAllItems()  '取消选择所有ListView项目。
  ListView_UnselectAllItems  hWndControl
End Sub
Function Class_ListView.CountPerPage() As Long '可见区域项的数目（可以显示多少行）。
  Return ListView_GetCountPerPage(hWndControl)
End Function
Function Class_ListView.TopIndex() As Long '列表或报表视图中时最顶层的可见项的索引。
  Return ListView_GetTopIndex(hWndControl)
End Function
Function Class_ListView.ScrollSelectedItem() As Long '滚动到当前选择的项目
  Dim i As Long = SendMessage(hWndControl, LVM_GETSELECTIONMARK, 0, 0)
  Return SendMessage(hWndControl, LVM_ENSUREVISIBLE, Cast(wParam, i), -1)
End Function
Function Class_ListView.FindString(fs As CWSTR) As Long '搜索列表视图项目文本。搜寻不区分大小写。成功时返回该项目的索引，否则返回-1。
  Return ListView_FindString(hWndControl, fs.vptr)
End Function
Function Class_ListView.FitContent(iCol As Long) As Long '自动调整列表视图控件的指定列的大小。成功返回TRUE，否则返回FALSE。。
  Return ListView_FitContent(hWndControl, iCol)
End Function
Function Class_ListView.Scroll(dx As Long, dy As Long) As Long '水平和垂直滚动量（像素）。成功返回TRUE，否则返回FALSE。
  Return ListView_Scroll(hWndControl, dx, dy)
End Function
Sub Class_ListView.AddItemCount(nCount As Long )  '予分配项目数量内存，避免每次新增分配，速度过慢。
   SendMessage(hWndControl, LVM_SETITEMCOUNT, nCount, LVSICF_NOINVALIDATEALL)
End Sub
Property Class_ListView.ReDraw()  As Boolean         '返回/设置重绘标志，大量新增项目时关闭重绘，避免控件闪耀和提高速度。{=.True.False}
    Property = m_ReDraw  '无需返回
End Property
Property Class_ListView.ReDraw(nValue As Boolean)
 m_ReDraw = nValue
 SendMessage(hWndControl, WM_SETREDRAW, nValue, 0)
End Property
Function Class_ListView.ColumnsWidthSave(FileIni As String, nName As String) As Boolean   '在INI文件里保存所有列的宽度。成功返回 True (通常在窗口销毁事件里)
   Dim nCols As Long = ListView_GetColumnCount(hWndControl)
   Dim wszBuffer As ZString * MAX_PATH
   For idx As Long = 0 To nCols - 1
      wszBuffer += Str(ListView_GetColumnWidth(hWndControl, idx))
      If idx < nCols - 1 Then wszBuffer += ","
   Next
   Return WritePrivateProfileStringA (StrPtr(nName), "ColumnsWidth", @wszBuffer, StrPtr(FileIni))
End Function
Sub Class_ListView.ColumnsWidthLoad(FileIni As String, nName As String)  '从INI文件里加载所有列的宽度，来列宽，需要先新增列。 (通常在窗口加载事件里)
   Dim nCols As Long = ListView_GetColumnCount(hWndControl)
   Dim wszBuffer As ZString * MAX_PATH
   Dim dwChars As DWord = GetPrivateProfileStringA(StrPtr(nName), "ColumnsWidth", Null, @wszBuffer, MAX_PATH, StrPtr(FileIni))
   If dwChars Then  
       If Len(wszBuffer) Then
           For idx As Long = 0 To nCols - 1
               Dim s As String = AfxStrParse(wszBuffer, idx + 1, ",")
               Dim nWidth As Long = Val(s)
               ListView_SetColumnWidth(hWndControl, idx, nWidth)
           Next
       End If
   End If
End Sub


'Type JPL_ListView_ComparePar
'    hWndControl As HWnd 
'    Column      As UInteger 
'    SortOrder   As UInteger
'End Type
Sub Class_ListView.ColumnToSort(ByVal lpNMV As NM_LISTVIEW Ptr)
   '为比较结构
   Dim lListView_ComparePar(2) As Integer
   '若要反转排序顺序
   If SortOrder = 1 Then SortOrder = 2 Else SortOrder = 1
   '遏止以前排序的列上的箭头 （包含零被单击的基于的列号）
   If nColumn <> - 1 And nColumn <> lpNMV->iSubItem Then DrawHeaderArrow(nColumn, 0)
   '排序列表视图中选择的列
   lListView_ComparePar(0) = Cast(Integer, hWndControl )
   lListView_ComparePar(1) = lpNMV->iSubItem
   lListView_ComparePar(2) = SortOrder
   SendMessage(hWndControl, LVM_SORTITEMSEX, Cast(wParam, @lListView_ComparePar(0)), Cast(lParam, @Class_ListView_CompareFunc))
   '向下箭头或向上箭头上绘制这一项目。
   DrawHeaderArrow( lpNMV->iSubItem, SortOrder)
   '要保存的已排序的列号
   nColumn = lpNMV->iSubItem
End Sub


Function Class_ListView_CompareFunc(ByVal index1 As Long, ByVal index2 As Long, ByVal JPL As UInteger Ptr) As Long
   Dim zItem1 As wString * MAX_PATH
   Dim zItem2 As wString * MAX_PATH
   Dim As Long zv1,zv2
   Dim lNumeric1 As Double
   Dim lNumeric2 As Double
   Dim lReturn As Integer
   Dim nControl As HWND = Cast(HWND, JPL[0])
   '从列表视图中获取价值
   Dim tlv_item as LV_ITEMW
   
   tlv_item.mask = LVIF_TEXT
   tlv_item.iItem = index1
   tlv_item.iSubItem = JPL[1]
   tlv_item.pszText = @zItem1
   tlv_item.cchTextMax = SizeOf(zItem1)
   
   SendMessageW(nControl, LVM_GETITEMW, 0, Cast(LPARAM, @tlv_item))
   tlv_item.iItem = index2
   tlv_item.pszText = @zItem2
   SendMessageW(nControl, LVM_GETITEMW, 0, Cast(LPARAM, @tlv_item))
   '--------------------------------------------------------------------------------------------
   '确定哪种类型的排序 （日期、 数字或字符） 根据列点击
   '--------------------------------------------------------------------------------------------
   '日期
   'If IsDate(zItem1) And IsDate(zItem2) Then '速度太慢，放弃
   'lNumeric1 = DateValue(zItem1)
   'lNumeric2 = DateValue(zItem2)
   'If lNumeric1 < lNumeric2 Then lReturn = -1 Else If lNumeric1 > lNumeric2 Then lReturn = +1 Else lReturn = 0
   'Else
   '数字
   Dim i As Long
   zv1 = True
   zv2 = True
   If UCase(Left(zItem1, 2)) = "&H" Then
      For i = 0 To Len(zItem1) -1
         Dim bj As Long = zItem1[i]
         if (bj >= 48 And bj <= 57) OrElse (bj <= 65 And bj <= 70) OrElse (bj <= 97 And bj <= 102) Then
         Else
            zv1 = 0
            Exit For
         End If
      Next
      Print
   Else
      For i = 0 To Len(zItem1)-1     '"0123456789.,'+-"
         Dim bj As Long =  zItem1[i]
         if (bj >= 48 And bj <= 57) OrElse bj = 46 OrElse bj = 44 OrElse bj = 39 OrElse bj = 43 OrElse bj = 45 Then
         Else
            zv1 = 0
            Exit For
         End If
      Next
      Print
   End If
   if zv1 Then
      If UCase(Left(zItem2, 2)) = "&H" Then
         For i = 0 To Len(zItem2)-1
            Dim bj As Long = zItem2[i]
            if (bj >= 48 And bj <= 57) OrElse (bj <= 65 And bj <= 70) OrElse (bj <= 97 And bj <= 102) Then
            Else
               zv2 = 0
               Exit For
            End If
         Next
      Else
         For i = 0 To Len(zItem2)-1     '"0123456789.,'+-"
            Dim bj As Long = zItem2[i]
            if (bj >= 48 And bj <= 57) OrElse bj = 46 OrElse bj = 44 OrElse bj = 39 OrElse bj = 43 OrElse bj = 45 Then
            Else
               zv2 = 0
               Exit For
            End If
         Next
      End If
   End if
   
   If zv1 = True And zv2 = True Then
      'zItem1 = FF_Remove(zItem1, " ")   ' 删除任何数字1000的空格
      'zItem2 = FF_Remove(zItem2, " ")
      lNumeric1 = Val(zItem1)
      lNumeric2 = Val(zItem2)
      If lNumeric1 < lNumeric2 Then lReturn = -1 Else If lNumeric1 > lNumeric2 Then lReturn = + 1 Else lReturn = 0
   Else
      '字符
      zItem1 = LTrim(zItem1)
      zItem2 = LTrim(zItem2)
      lReturn = lstrcmpiW(zItem1, zItem2)
   End If
   If JPL[2] = 1 Then Return lReturn Else Return - lReturn
End Function

Sub Class_ListView.DrawHeaderArrow(ByVal pColumn As Integer, ByVal pSortOrder As Integer)
    Dim hHeader As HWnd  
    Dim HDI As HD_ITEM
    hHeader =Cast(HWnd, SendMessage(hWndControl, LVM_GetHeader, 0, 0) )    
    HDI.mask = HDI_FORMAT
    Header_GetItem(hHeader, pColumn, @HDI)
    ' 取决于排序次序 (SO_NONE, SO_ASCENDING, SO_DESCENDING) 
    Select Case pSortOrder
        Case 0
            ' 删除向下箭头或向上箭头
            HDI.fmt = HDI.fmt And Not (HDF_SORTDOWN Or HDF_SORTUP) 
        Case 1
            ' 这一项目上绘制一个向上箭头
            HDI.fmt = HDI.fmt And Not HDF_SORTDOWN
            HDI.fmt = HDI.fmt Or      HDF_SORTUP                       
        Case 2
            ' 在这个项目上绘制一个向下箭头
            HDI.fmt = HDI.fmt And Not HDF_SORTUP 
            HDI.fmt = HDI.fmt Or      HDF_SORTDOWN                             
    End Select       
    Header_SetItem(hHeader, pColumn, @HDI)
End Sub
