[已解决]发现一个BUG,Listview不能排序!
本帖最后由 ioripalm 于 2015-8-31 09:06 编辑就用GUICtrlRegisterListViewSort帮助文件参考里面给的示例来说。#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
Global $nCurCol = -1
Global $nSortDir = 1
Global $bSet = 0
Global $nCol = -1
Example1()
; *******************************************************
; Example 1 - sorting 3 column's different
; *******************************************************
Func Example1()
Local $lv, $msg
GUICreate("Test", 300, 200)
$lv = GUICtrlCreateListView("Column1|Col2|Col3", 10, 10, 280, 180)
GUICtrlRegisterListViewSort(-1, "LVSort") ; Register the function "SortLV" for the sorting callback
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
; Our sorting callback funtion
Func LVSort($hWnd, $nItem1, $nItem2, $nColumn)
Local $val1, $val2, $nResult
; Switch the sorting direction
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)
; If it is the 3rd colum (column starts with 0) then compare the dates
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 ; No change of item1 and item2 positions
If $val1 < $val2 Then
$nResult = -1 ; Put item2 before item1
ElseIf $val1 > $val2 Then
$nResult = 1 ; Put item2 behind item1
EndIf
$nResult = $nResult * $nSortDir
Return $nResult
EndFunc ;==>LVSort
; Retrieve the text of a listview item in a specified column
Func GetSubItemText($nCtrlID, $nItemID, $nColumn)
Local $stLvfi = DllStructCreate("uint;ptr;int;int;int")
Local $nIndex, $stBuffer, $stLvi, $sItemText
DllStructSetData($stLvfi, 1, $LVFI_PARAM)
DllStructSetData($stLvfi, 3, $nItemID)
$stBuffer = DllStructCreate("char")
$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
以上代码可以运行成功,也可以排序成功,Listview里的3行数据是通过GUICtrlCreateListViewItem函数添加的,如果将这3行数据换一种方式添加进去,排序函数就不工作了!#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#Include <GuiListView.au3>
Global $nCurCol = -1
Global $nSortDir = 1
Global $bSet = 0
Global $nCol = -1
Example1()
; *******************************************************
; Example 1 - sorting 3 column's different
; *******************************************************
Func Example1()
Local $lv, $msg
GUICreate("Test", 300, 200)
$lv = GUICtrlCreateListView("Column1|Col2|Col3", 10, 10, 280, 180)
GUICtrlRegisterListViewSort(-1, "LVSort") ; Register the function "SortLV" for the sorting callback
Dim $ListViewArray = [['ABC',666,'10.05.2004'],['DEF',444,'11.05.2005'],['CDE',444,'12.05.2004']]
_GUICtrlListView_AddArray($Lv, $ListViewArray)
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
; Our sorting callback funtion
Func LVSort($hWnd, $nItem1, $nItem2, $nColumn)
Local $val1, $val2, $nResult
; Switch the sorting direction
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)
; If it is the 3rd colum (column starts with 0) then compare the dates
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 ; No change of item1 and item2 positions
If $val1 < $val2 Then
$nResult = -1 ; Put item2 before item1
ElseIf $val1 > $val2 Then
$nResult = 1 ; Put item2 behind item1
EndIf
$nResult = $nResult * $nSortDir
Return $nResult
EndFunc ;==>LVSort
; Retrieve the text of a listview item in a specified column
Func GetSubItemText($nCtrlID, $nItemID, $nColumn)
Local $stLvfi = DllStructCreate("uint;ptr;int;int;int")
Local $nIndex, $stBuffer, $stLvi, $sItemText
DllStructSetData($stLvfi, 1, $LVFI_PARAM)
DllStructSetData($stLvfi, 3, $nItemID)
$stBuffer = DllStructCreate("char")
$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
以上数据是通过_GUICtrlListView_AddArray()函数添加进去的,排序就完全不起作用了,不知道那块出了问题
经过网友chzj589的帮助,测试
_GUICtrlListView_RegisterSortCallBack($ListView1)
_GUICtrlListView_SortItems($ListView1, 0);以ID排序
_GUICtrlListView_SortItems($ListView1, GUICtrlGetState($ListView1))
可以排序,问题已解决! GUICtrlCreateListViewItem这个会返回控件ID,这个是在LISTVIEW中创建的控件
_GUICtrlListView_AddArray() 这个添加的只是数据,添加在LISTVIEW中的数据
我理解的就是这样的。
因为今天我做实时更新LISTVIEW中时,也碰到了。才发现这的区别。 回复 1# ioripalm
我看不出哪里有问题
哦,点击项目后,条目重新排序
但是
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)
与
Dim $ListViewArray = [['ABC','666','10.05.2004'],['DEF','444','11.05.2005'],['CDE','444','12.05.2004']]
_GUICtrlListView_AddArray($Lv, $ListViewArray)
一样吗?
所以
GUICtrlRegisterListViewSort(-1, "LVSort") ; 注册用于排序的回调函数 "LVSort".
不能回调 回复 4# chzj589
嗯,导入的数据虽然一样,但是方式不对,导入少量数据用GUICtrlCreateListViewItem比较方便,但是遇到大量的数据还是_GUICtrlListView_AddArray速度快(目前看来效率不比用)。
虽然_GUICtrlListView_AddArray是UDF函数,使用同样是UDF的_GUICtrlListView_Create来创建Listview的话,连GUICtrlCreateListViewItem导入的数据都无法排序。
_GUICtrlListView_RegisterSortCallBack这个简单排序,和_GUICtrlListView_AddArray一样时UDF却也不能正常工作。 回复 5# ioripalm
我用数据库MDB导入GUICtrlCreateListView,可以排序 回复 5# ioripalm
用
_GUICtrlListView_RegisterSortCallBack($ListView1)
_GUICtrlListView_SortItems($ListView1, 0);以ID排序
_GUICtrlListView_SortItems($ListView1, GUICtrlGetState($ListView1))
查看帮助 回复 7# chzj589
感谢。测试成功,的确可以点击标题排序,而且会自动加上下小箭头。
再请问一个问题,这个注册简单排序回调函数,为什么称之为简单?是不是不能设置排序format的都算是简单排序! 能贴一下,解决后的代码么?学习一下
页:
[1]