基 础 函 数 参 考
GUICtrlRegisterListViewSort
注册 ListView 控件内部排序的自定义回调函数.
参 数
控件ID |
Listview 控件ID. |
函数 |
排序回调函数的名称. |
返 回 值
备 注
!!! 要使用户定义函数能正常工作, 必须定义它最多 4 个参数, 否则函数将不能被调用 !!!
例如:
Func MySortFunction($nListViewID, $LParam1, $LParam2, $nColumn)
...
EndFunc
或
Func MySortFunction($nListViewID, $LParam1, $LParam2)
...
EndFunc
当用户函数被调用时, 这 4 个参数具有下列值:
位置
|
Parameter
|
参数
|
1 |
controlID |
回调函数使用的 listview 控件 ID. |
2 |
lParam1 |
第一个项目的 lParam 值.(默认为该项目的控件 ID). |
3 |
lParam2 |
第二个项目的 lParam 值.(默认为该项目的控件 ID). |
4 |
column |
点击排序的列.(第一列为 0). |
下列值是改变排序状态后的返回值:
返回值
|
意义
|
-1 |
第一个项目在第二个前面. |
0 |
无变化. |
1 |
第一个项目在第二个后面. |
排序 GUI 自身创建的项目参见排序示例.
相 关 函 数
GUICtrlCreateListView
函 数 示 例
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
Global $nCurCol
= -1
Global $nSortDir
= 1
Global $bSet
= 0
Global $nCol
= -1
Example1()
Example2()
;
*******************************************************
; 示例 1 - 排序 3 列的数据
;
*******************************************************
Func Example1()
Local
$lv, $msg
GUICreate("测试", 300, 200)
$lv
= GUICtrlCreateListView("列1|列2|列3", 10,
10, 280, 180)
GUICtrlRegisterListViewSort(-1,
"LVSort")
; 注册排序回调函数 "SortLV"
GUICtrlCreateListViewItem ("ABC|666|10.05.2004",
$lv)
GUICtrlSetImage(-1, "shell32.dll", 7)
GUICtrlCreateListViewItem ("DEF|444|11.05.2005",
$lv)
GUICtrlSetImage(-1, "shell32.dll", 12)
GUICtrlCreateListViewItem ("CDE|444|12.05.2004",
$lv)
GUICtrlSetImage(-1, "shell32.dll", 3)
GUISetState()
While
1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
ExitLoop
Case $lv
$bSet = 0
$nCurCol = $nCol
GUICtrlSendMsg($lv,
$LVM_SETSELECTEDCOLUMN, GUICtrlGetState($lv),
0)
DllCall("user32.dll", "int", "InvalidateRect", "hwnd", GUICtrlGetHandle($lv),
"int", 0, "int", 1)
EndSwitch
WEnd
GUIDelete()
EndFunc ;==>Example1
; 自定义排序回调函数
Func LVSort($hWnd, $nItem1, $nItem2, $nColumn)
Local
$val1, $val2, $nResult
;
切换排序方向
If
$nColumn =
$nCurCol Then
If Not $bSet Then
$nSortDir =
$nSortDir *
- 1
$bSet =
1
EndIf
Else
$nSortDir = 1
EndIf
$nCol
= $nColumn
$val1
= GetSubItemText($hWnd, $nItem1, $nColumn)
$val2
= GetSubItemText($hWnd, $nItem2, $nColumn)
; 如果排序第 3 列
(列从0开始计算), 则比较日期
If
$nColumn =
2 Then
$val1 = StringRight($val1, 4) & StringMid($val1,
4, 2) & StringLeft($val1,
2)
$val2 = StringRight($val2, 4) & StringMid($val2,
4, 2) & StringLeft($val2,
2)
EndIf
$nResult = 0 ; 项目 1 和项目 2 的位置没有改变
If
$val1 <
$val2 Then
$nResult = -1 ; 将第 2 项放到第
1 项之前
ElseIf $val1 > $val2 Then
$nResult = 1 ; 将第 2 项放到第 1 项后面
EndIf
$nResult = $nResult * $nSortDir
Return $nResult
EndFunc ;==>LVSort
; 检索 ListView 指定列的项目文本
Func GetSubItemText($nCtrlID, $nItemID, $nColumn)
Local
$stLvfi =
DllStructCreate("uint;ptr;int;int[2];int")
Local
$nIndex,
$stBuffer,
$stLvi,
$sItemText
DllStructSetData($stLvfi, 1, $LVFI_PARAM)
DllStructSetData($stLvfi, 3, $nItemID)
$stBuffer = DllStructCreate("char[260]")
$nIndex = GUICtrlSendMsg($nCtrlID, $LVM_FINDITEM , -1,
DllStructGetPtr($stLvfi));
$stLvi = DllStructCreate("uint;int;int;uint;uint;ptr;int;int;int;int")
DllStructSetData($stLvi, 1, $LVIF_TEXT)
DllStructSetData($stLvi, 2, $nIndex)
DllStructSetData($stLvi, 3, $nColumn)
DllStructSetData($stLvi, 6, DllStructGetPtr($stBuffer))
DllStructSetData($stLvi, 7, 260)
GUICtrlSendMsg($nCtrlID, $LVM_GETITEMA, 0, DllStructGetPtr($stLvi));
$sItemText = DllStructGetData($stBuffer, 1)
$stLvi = 0
$stLvfi = 0
$stBuffer = 0
Return $sItemText
EndFunc ;==>GetSubItemText
;
*******************************************************
; 示例 2 - 有 DllCall 创建项目排序
;
*******************************************************
Func Example2()
Local
$hGUI, $lv, $msg
$nCurCol = -1
$nSortDir = 1
$bSet
= 0
$nCol
= -1
$hGUI
= GUICreate("测试", 300, 200)
$lv
= GUICtrlCreateListView("列1|列2|列3", 10,
10, 280, 180)
GUICtrlRegisterListViewSort(-1,
"LVSort2")
; 注册排序回调函数 "SortLV"
MyGUICtrlCreateListViewItem
("ABC|666|10.05.2004",
$lv, -1)
MyGUICtrlCreateListViewItem
("DEF|444|11.05.2005",
$lv, -1)
MyGUICtrlCreateListViewItem
("CDE|444|12.05.2004",
$lv, -1)
GUISetState()
While
1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
ExitLoop
Case $lv
$bSet = 0
$nCurCol = $nCol
GUICtrlSendMsg($lv,
$LVM_SETSELECTEDCOLUMN, GUICtrlGetState($lv),
0)
DllCall("user32.dll", "int", "InvalidateRect", "hwnd", ControlGetHandle($hGUI,
"", $lv), "int", 0, "int", 1)
EndSwitch
WEnd
EndFunc ;==>Example2
; 自定义排序回调函数
Func LVSort2($hWnd, $nItem1, $nItem2, $nColumn)
Local
$val1, $val2, $nResult
;
切换排序方向
If
$nColumn =
$nCurCol Then
If Not $bSet Then
$nSortDir =
$nSortDir *
- 1
$bSet =
1
EndIf
Else
$nSortDir = 1
EndIf
$nCol
= $nColumn
$val1
= GetSubItemText($hWnd, $nItem1, $nColumn)
$val2
= GetSubItemText($hWnd, $nItem2, $nColumn)
; 如果排序第 3 列
(列从0开始计算), 则比较日期
If
$nColumn =
2 Then
$val1 = StringRight($val1, 4) & StringMid($val1,
4, 2) & StringLeft($val1,
2)
$val2 = StringRight($val2, 4) & StringMid($val2,
4, 2) & StringLeft($val2,
2)
EndIf
$nResult = 0 ; 项目 1 和项目 2 的位置没有改变
If
$val1 <
$val2 Then
$nResult = -1 ; 将第 2 项放到第
1 项之前
ElseIf $val1 > $val2 Then
$nResult = 1 ; 将第 2 项放到第 1 项后面
EndIf
$nResult = $nResult * $nSortDir
Return $nResult
EndFunc ;==>LVSort2
; 检索 ListView 指定列的项目文本
Func GetSubItemText2($nCtrlID, $nItemID, $nColumn)
Local
$stLvfi =
DllStructCreate("uint;ptr;int;int[2];int")
Local
$stBuffer,
$nIndex,
$stLvi,
$sItemText
DllStructSetData($stLvfi, 1, $LVFI_PARAM) ;
查找保存了索引的项目
DllStructSetData($stLvfi, 3, $nItemID)
$stBuffer = DllStructCreate("char[260]")
$nIndex = GUICtrlSendMsg($nCtrlID, $LVM_FINDITEM , -1,
DllStructGetPtr($stLvfi));
$stLvi = DllStructCreate("uint;int;int;uint;uint;ptr;int;int;int;int")
DllStructSetData($stLvi, 1, $LVIF_TEXT)
DllStructSetData($stLvi, 2, $nIndex)
DllStructSetData($stLvi, 3, $nColumn)
DllStructSetData($stLvi, 6, DllStructGetPtr($stBuffer))
DllStructSetData($stLvi, 7, 260)
GUICtrlSendMsg($nCtrlID, $LVM_GETITEMA, 0, DllStructGetPtr($stLvi));
$sItemText = DllStructGetData($stBuffer, 1)
$stLvi = 0
$stLvfi = 0
$stBuffer = 0
Return $sItemText
EndFunc ;==>GetSubItemText2
; 直接创建和插入 ListView 项目
Func MyGUICtrlCreateListViewItem ($sText, $nCtrlID, $nIndex)
Local
$stLvItem = DllStructCreate("uint;int;int;uint;uint;ptr;int;int;int;int;")
Local
$stText =
DllStructCreate("char[260]")
Local
$arText =
StringSplit($sText, "|")
If
$nIndex =
-1 Then $nIndex = GUICtrlSendMsg($nCtrlID, $LVM_GETITEMCOUNT, 0,
0)
DllStructSetData($stText, 1, $arText[1]) ;
项目的文字保存在结构中
DllStructSetData($stLvItem , 1, BitOR($LVIF_TEXT, $LVIF_PARAM))
DllStructSetData($stLvItem , 2, $nIndex)
DllStructSetData($stLvItem , 6, DllStructGetPtr($stText))
; 设置结构的
lParam 为行索引 - 在 ListView 内是唯一的
DllStructSetData($stLvItem , 9, $nIndex)
$nIndex = GUICtrlSendMsg($nCtrlID, $LVM_INSERTITEMA, 0, DllStructGetPtr($stLvItem ))
If
$nIndex >
-1 Then
; 现在插入列文本的其余部分
For $i = 2 To
$arText[0]
DllStructSetData($stText, 1,
$arText[$i])
DllStructSetData($stLvItem , 3,
$i - 1) ;
存储子项的索引
GUICtrlSendMsg($nCtrlID, $LVM_SETITEMTEXTA, $nIndex, DllStructGetPtr($stLvItem ))
Next
EndIf
$stText = 0
$stLvItem = 0
; 更改列的宽度,
以适应项目的文字
For
$i = 0 To 2
GUICtrlSendMsg($nCtrlID, $LVM_SETCOLUMNWIDTH,
$i, -1)
GUICtrlSendMsg($nCtrlID, $LVM_SETCOLUMNWIDTH,
$i, -2)
Next
EndFunc ;==>MyGUICtrlCreateListViewItem