robby321 Posted April 13, 2015 Posted April 13, 2015 Hi! i'm using GUICtrlRegisterListViewSort() with a custum sort callback function to compare/sort dates (in column 3). I know about _GUICtrlListView_SortItems() with _GUICtrlListView_RegisterSortCallBack(), but that 'simple sort function' and will not work correctly with dates, right? is it possible to re-sort a listview after adding items to it? example: expandcollapse popup#include <GUIConstantsEx.au3> #include <ListViewConstants.au3> #include <GuiListView.au3> Global $g_iCurCol = -1 Global $g_iSortDir = 1 Global $g_bSet = False Global $g_iCol = -1 Example() Func Example() GUICreate("Test", 300, 200) Local $idLv = GUICtrlCreateListView("Column1|Col2|Col3", 10, 10, 280, 150) GUICtrlRegisterListViewSort(-1, "LVSort") ; Register the function "SortLV" for the sorting callback GUICtrlCreateListViewItem("ABC|666|10.05.2004", $idLv) GUICtrlSetImage(-1, "shell32.dll", 7) GUICtrlCreateListViewItem("DEF|444|11.05.2005", $idLv) GUICtrlSetImage(-1, "shell32.dll", 12) GUICtrlCreateListViewItem("CDE|444|12.05.2004", $idLv) GUICtrlSetImage(-1, "shell32.dll", 3) $idBtn = GUICtrlCreateButton('add item', 10, 166, 280, 28) GUISetState(@SW_SHOW) Local $idMsg ; Loop until the user exits. While 1 $idMsg = GUIGetMsg() Switch $idMsg Case $GUI_EVENT_CLOSE ExitLoop Case $idLv $g_bSet = False $g_iCurCol = $g_iCol GUICtrlSendMsg($idLv, $LVM_SETSELECTEDCOLUMN, GUICtrlGetState($idLv), 0) ;~ DllCall("user32.dll", "int", "InvalidateRect", "hwnd", GUICtrlGetHandle($idLv), "int", 0, "int", 1) Case $idBtn GUICtrlCreateListViewItem("BCD|333|13.05.2001", $idLv) GUICtrlSetImage(-1, "shell32.dll", 5) ; ################################ ; RE-SORT ITEMS NOW! BUT HOW? ; ################################ EndSwitch WEnd GUIDelete() EndFunc ;==>Example ; Our sorting callback funtion Func LVSort($hWnd, $nItem1, $nItem2, $iColumn) Local $sVal1, $sVal2, $iResult ; Switch the sorting direction If $iColumn = $g_iCurCol Then If Not $g_bSet Then $g_iSortDir = $g_iSortDir * -1 $g_bSet = True EndIf Else $g_iSortDir = 1 EndIf $g_iCol = $iColumn $sVal1 = GetSubItemText($hWnd, $nItem1, $iColumn) $sVal2 = GetSubItemText($hWnd, $nItem2, $iColumn) ; If it is the 3rd colum (column starts with 0) then compare the dates If $iColumn = 2 Then $sVal1 = StringRight($sVal1, 4) & StringMid($sVal1, 4, 2) & StringLeft($sVal1, 2) $sVal2 = StringRight($sVal2, 4) & StringMid($sVal2, 4, 2) & StringLeft($sVal2, 2) EndIf $iResult = 0 ; No change of item1 and item2 positions If $sVal1 < $sVal2 Then $iResult = -1 ; Put item2 before item1 ElseIf $sVal1 > $sVal2 Then $iResult = 1 ; Put item2 behind item1 EndIf $iResult = $iResult * $g_iSortDir Return $iResult EndFunc ;==>LVSort ; Retrieve the text of a listview item in a specified column Func GetSubItemText($idCtrl, $idItem, $iColumn) Local $tLvfi = DllStructCreate("uint;ptr;int;int[2];int") DllStructSetData($tLvfi, 1, $LVFI_PARAM) DllStructSetData($tLvfi, 3, $idItem) Local $tBuffer = DllStructCreate("char[260]") Local $nIndex = GUICtrlSendMsg($idCtrl, $LVM_FINDITEM, -1, DllStructGetPtr($tLvfi)); Local $tLvi = DllStructCreate("uint;int;int;uint;uint;ptr;int;int;int;int") DllStructSetData($tLvi, 1, $LVIF_TEXT) DllStructSetData($tLvi, 2, $nIndex) DllStructSetData($tLvi, 3, $iColumn) DllStructSetData($tLvi, 6, DllStructGetPtr($tBuffer)) DllStructSetData($tLvi, 7, 260) GUICtrlSendMsg($idCtrl, $LVM_GETITEMA, 0, DllStructGetPtr($tLvi)); Local $sItemText = DllStructGetData($tBuffer, 1) Return $sItemText EndFunc ;==>GetSubItemText I really appreciate any help you guys can provide!
Solution argumentum Posted April 13, 2015 Solution Posted April 13, 2015 I really appreciate any help you guys can provide! you could add an additional column, hide the additional column, put the dates as Integer ( 20151231 ) and tell it to sort from there. ( my .02 cents ) Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
robby321 Posted April 13, 2015 Author Posted April 13, 2015 you could add an additional column, hide the additional column, put the dates as Integer ( 20151231 ) and tell it to sort from there. ( my .02 cents ) heh, that's pretty clever! another way to solve this is.. create copies of GUICtrlListView_SortItems(), _GUICtrlListView_RegisterSortCallBack() and __GUICtrlListView_Sort() and implement whatever you need! dirty, but its working thank you for your reply! argumentum 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now