jcpetu Posted August 6, 2012 Share Posted August 6, 2012 (edited) Hello forum,I'm using a sort function to order dates and check boxes that requieres the following input parameters:Func LVSort($hWnd, $nItem1, $nItem2, $nColumn)Though I´m able to change the sort function according to the columns content,I don´t know how to get the appropiate parameters for my sorting function from:WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)...... Case $LVN_COLUMNCLICK ;ListView column clicked Local $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam) Local $iCol = DllStructGetData($tInfo, "SubItem") ;Column clicked starting from 0 Local $tNMLVCUSTOMDRAW = DllStructCreate($tagNMLVCUSTOMDRAW, $ilParam) Local $dwItemSpec = DllStructGetData($tNMLVCUSTOMDRAW, "dwItemSpec") ; Item index Local $iSubItem = DllStructGetData($tNMLVCUSTOMDRAW, "iSubItem") ; Subitem index LVSort($idLV, $dwItemSpec, $dwItemSpec, $iCol)I would appreciate if someone could help me.thanks in advance and regards. Edited August 6, 2012 by jcpetu Link to comment Share on other sites More sharing options...
BrewManNH Posted August 6, 2012 Share Posted August 6, 2012 An easier way to do it is to trigger off of the ListView to do it without the Windows messaging system. If you're using message loop mode, you would include a case statement for the listview's ID and do it like I have below. #include <GUIConstantsEx.au3> #include <GUIListView.au3> $gui = GUICreate("Listview sorter") $idListView = GUICtrlCreateListView("Column 1|Column 2", 10, 10, 300, 300) $hListView = GUICtrlGetHandle($idListView) For $I = 1 To 10 GUICtrlCreateListViewItem($I * Random(1, 100, 1) & "|" & $I * Random(1, 100, 1), $idListView) Next GUISetState() _GUICtrlListView_RegisterSortCallBack($hListView) While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_Event_CLose _GUICtrlListView_UnRegisterSortCallBack($hListView) Exit Case $idListView sortLV() EndSwitch WEnd Func sortLV() Local $iCol = GUICtrlGetState($idListView) _GUICtrlListView_BeginUpdate($hListView) _GUICtrlListView_SortItems($hListView, $iCol) _GUICtrlListView_EndUpdate($hListView) EndFunc ;==>sortLV It's a bit easier to do it this way than doing it with the Windows messages. It can also be done the same way if you use OnEvent mode. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
jcpetu Posted August 6, 2012 Author Share Posted August 6, 2012 BrewManNH, thanks for your answer. I´m using a function that allows me to check the column and change the sorting algorithm, for example to sort dates and check boxes columns. In this example, how can I use a diferrente algorithm for dates? Link to comment Share on other sites More sharing options...
LarsJ Posted August 7, 2012 Share Posted August 7, 2012 (edited) Hi jcpetu, I understand your problems with sorting of the ListView. If you are using a native ListView you can register your own sorting callback function with GUICtrlRegisterListViewSort(). But if you are creating ListView's with the functions in GuiListView.au3 it's apparently not possible to use your own callback function with _GUICtrlListView_RegisterSortCallBack(). So you have to modify the sorting functions in GuiListView.au3 a little bit. I have already modified the functions in the zip below. The following is just explanations. Start to create a copy of the functions _GUICtrlListView_RegisterSortCallBack() __GUICtrlListView_Sort() _GUICtrlListView_SortItems(). Add "Ex" to the names so that the new names will become _GUICtrlListView_RegisterSortCallBackEx() __GUICtrlListView_SortEx() _GUICtrlListView_SortItemsEx(). Modify _GUICtrlListView_RegisterSortCallBackEx() to use __GUICtrlListView_SortEx in stead of __GUICtrlListView_Sort. __GUICtrlListView_SortEx() is the new callback function. Modify _GUICtrlListView_SortItemsEx() to send a $LVM_SORTITEMSEX message in stead of a $LVM_SORTITEMS message. The $LVM_SORTITEMSEX message provides the item index in the $nItem1 and $nItem2 parameters of the callback function in stead of the item param provided by the $LVM_SORTITEMS message. Using $LVM_SORTITEMSEX you can skip the calculation of the index from the param. There are more modifications to __GUICtrlListView_SortEx(). The first half of the modifications is just to delete the code used to calculate the index from the param. The second half of the modifications is to add the code to do the sorting. An example is provided in the zip. Run SortListView.au3. The columns are sorted properly by strings, by numbers and by dates. The other file in the zip SortListViewFuncs.au3 contains the modified sort functions. LarsJ. The zip can be opened with 7-Zip. SortListView.zip Edited August 7, 2012 by LarsJ Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
BrewManNH Posted August 7, 2012 Share Posted August 7, 2012 Hi jcpetu, I understand your problems with sorting of the ListView. If you are using a native ListView you can register your own sorting callback function with GUICtrlRegisterListViewSort(). But if you are creating ListView's with the functions in GuiListView.au3 it's apparently not possible to use your own callback function with _GUICtrlListView_RegisterSortCallBack(). It's absolutely possible to sort a LV when using the UDF functions to create the items in the listview, you just have to know what you're doing when creating the items. Here's the same example that I posted above, but using the UDF functions to add items to the listview instead of the native function. #include <GUIConstantsEx.au3> #include <GUIListView.au3> $gui = GUICreate("Listview sorter") $idListView = GUICtrlCreateListView("Column 1|Column 2", 10, 10, 300, 300) $hListView = GUICtrlGetHandle($idListView) For $I = 1 To 10 _GUICtrlListView_AddItem($hListView, $I * Random(1, 100, 1), -1, $I + 1000) ; <<<<<<<<<<<< add 1000 to the item $iParam so it will sort _GUICtrlListView_AddSubItem($hListView, $I - 1, $I * Random(1, 100, 1), 1) Next GUISetState() _GUICtrlListView_RegisterSortCallBack($hListView) While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_Event_CLose _GUICtrlListView_UnRegisterSortCallBack($hListView) Exit Case $idListView sortLV() EndSwitch WEnd Func sortLV() Local $iCol = GUICtrlGetState($idListView) _GUICtrlListView_BeginUpdate($hListView) _GUICtrlListView_SortItems($hListView, $iCol) _GUICtrlListView_EndUpdate($hListView) EndFunc ;==>sortLV BTW, if all you need is the column # for your custom sort routine, this line "Local $iCol = GUICtrlGetState($idListView)" will get the column number that was clicked. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
LarsJ Posted August 7, 2012 Share Posted August 7, 2012 (edited) Hi BrewManNH, I'm certainly not saying that you can't sort a LV using UDF functions. I'm saying that you can't supply a callback funtions without modifying the sort functions. This is the parameters for _GUICtrlListView_RegisterSortCallBack: _GUICtrlListView_RegisterSortCallBack( $hWnd [, $fNumbers = True [, $fArrows = True]] ) Where will you supply the callback function? Show me how to sort the example in the help file for _GUICtrlListView_RegisterSortCallBack properly by date in the third column. With GUICtrlRegisterListViewSort() for native LV's you can supply a callback function: GUICtrlRegisterListViewSort( controlID, "function" ). LarsJ. Edited August 7, 2012 by LarsJ Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
BrewManNH Posted August 7, 2012 Share Posted August 7, 2012 Here's example2 from the GUICtrlRegisterListViewSort example scripts showing that it's still quite possible to use that function in conjunction with UDF created items in a listview. I haven't altered anything other than removing example1 and the create item function that was included in the example. No alteration of the sort routine that is in the help file was done at all. I'll admit, it sometimes takes 2 clicks on the header to get it to sort, not sure why, but since this is only a proof-of-concept script I'm not going to get into figuring out why it does that. expandcollapse popup#include <GUIConstantsEx.au3> #include <ListViewConstants.au3> #include <GUIListview.au3> Global $nCurCol = -1 Global $nSortDir = 1 Global $bSet = 0 Global $nCol = -1 ;~ Example1() Example2() ; ******************************************************* ; Example 1 - sorting 3 column's different ; ******************************************************* ; 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[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 ; ******************************************************* ; Example 2 - sorting with selfcreated items by DllCall ; ******************************************************* Func Example2() Local $hGUI, $lv, $msg $nCurCol = -1 $nSortDir = 1 $bSet = 0 $nCol = -1 $hGUI = GUICreate("Test", 300, 200) $lv = GUICtrlCreateListView("Column1|Col2|Col3", 10, 10, 280, 180) GUICtrlRegisterListViewSort(-1, "LVSort2") ; Register the function "SortLV" for the sorting callback _GUICtrlListView_AddItem($lv,"ABC", -1, 1001) _GUICtrlListView_AddSubItem($lv, 0, "666", 1) _GUICtrlListView_AddSubItem($lv, 0, "10.05.2004", 2) _GUICtrlListView_AddItem($lv,"DEF", -1, 1002) _GUICtrlListView_AddSubItem($lv, 1, "444", 1) _GUICtrlListView_AddSubItem($lv, 1, "11.05.2005", 2) _GUICtrlListView_AddItem($lv,"CDE", -1, 1003) _GUICtrlListView_AddSubItem($lv, 2, "444", 1) _GUICtrlListView_AddSubItem($lv, 2, "12.05.2004", 2) For $i = 0 To 2 GUICtrlSendMsg($lv, $LVM_SETCOLUMNWIDTH, $i, -1) GUICtrlSendMsg($lv, $LVM_SETCOLUMNWIDTH, $i, -2) Next 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 ; Our sorting callback funtion Func LVSort2($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 ;==>LVSort2 ; Retrieve the text of a listview item in a specified column Func GetSubItemText2($nCtrlID, $nItemID, $nColumn) Local $stLvfi = DllStructCreate("uint;ptr;int;int[2];int") Local $stBuffer, $nIndex, $stLvi, $sItemText DllStructSetData($stLvfi, 1, $LVFI_PARAM) ; Find the item by our saved index 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 If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
jcpetu Posted August 7, 2012 Author Share Posted August 7, 2012 Hi LarsJ, I made the script modifications with yor indications and everything is working well. When I tried with BrewManNH it didn´t work. Thanks a lot two both of you for your help and regards. 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