robby321 Posted April 13, 2015 Share 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! Link to comment Share on other sites More sharing options...
Solution argumentum Posted April 13, 2015 Solution Share 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. Link to comment Share on other sites More sharing options...
robby321 Posted April 13, 2015 Author Share 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 Link to comment Share on other sites More sharing options...
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