Opened on Aug 4, 2009 at 10:37:47 AM
Closed on Aug 4, 2009 at 9:04:33 PM
Last modified on Aug 7, 2009 at 4:21:30 PM
#1107 closed Feature Request (Rejected)
Ability to sort hexadecimal numbers using in a Listview
| Reported by: | Owned by: | ||
|---|---|---|---|
| Milestone: | Component: | Standard UDFs | |
| Version: | Severity: | None | |
| Keywords: | _GUICtrlListView_SortItems | Cc: |
Description
I've looked in the helpfile but there doesn't seem to be a way to sort hexadecimal numbers correctly in a listview. When it tries to sort them, it invariably places the numbers containing non-alphabetical characters (eg. 12345679) at the end of the sorted list rather than in their correct position (in this case, between 1234566f and 1234567a).
Attachments (0)
Change History (7)
comment:2 by , on Aug 4, 2009 at 9:04:33 PM
| Component: | AutoIt → Standard UDFs |
|---|---|
| Resolution: | → Rejected |
| Status: | new → closed |
Learn how to use GUICtrlRegisterListView rather than a standard sort.
comment:3 by , on Aug 5, 2009 at 3:45:09 AM
Gary, the Help file doesn't list a "GUICtrlRegisterListView" command, only a "GUICtrlRegisterListViewSort" command. Did you mean that one?
Currently, I call the following on a list view sort:
_GUICtrlListView_RegisterSortCallBack($h_ListLV)
_GUICtrlListView_SortItems($h_CheaterLV, GUICtrlGetState($h_ListLV))
_GUICtrlListView_UnRegisterSortCallBack($h_ListLV)
comment:4 by , on Aug 5, 2009 at 4:36:52 AM
Here's an example using GUICtrlRegisterListViewSort failing to sort hex correctly. 12345678 should always be between 104a76e3 and 1a34f478 regardless of which way it is sorted.
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
Opt('MustDeclareVars', 1)
Global $nCurCol = -1
Global $nSortDir = 1
Global $bSet = 0
Global $nCol = -1
Example1()
; *******************************************************
; Example 1 - sorting 3 column's different
; *******************************************************
Func Example1()
Local $hGUI, $lv, $lvi1, $lvi2, $lvi3, $msg
$hGUI = GUICreate("Test", 300, 200)
$lv = GUICtrlCreateListView("Column1|Col2|Col3", 10, 10, 280, 180)
GUICtrlRegisterListViewSort(-1, "LVSort") ; Register the function "SortLV" for the sorting callback
$lvi1 = GUICtrlCreateListViewItem("ABC|666|1a34f478", $lv)
GUICtrlSetImage(-1, "shell32.dll", 7)
$lvi2 = GUICtrlCreateListViewItem("DEF|444|12345678", $lv)
GUICtrlSetImage(-1, "shell32.dll", 12)
$lvi3 = GUICtrlCreateListViewItem("CDE|444|104a76e3", $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 $nSort, $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
Be nice if it had an option to sort either alphabetically (which is does by default I believe) or numerically.
comment:5 by , on Aug 5, 2009 at 9:56:28 PM
Just do inside LVSort the right comparison after the conversion you want.
For me there is really no BUG with this GUICtrlRegisterListViewSort() which allow you to take in account the data as you want
comment:6 by , on Aug 6, 2009 at 12:23:06 AM
Ahh Ok, I see what you guys mean. GUICtrlRegisterListViewSort() is a little more work than the _GUICtrlListView_SortItems() I was using but I'll give it a go. Thanks.

can you post a complete repro script as suggested by the writring of a track report?
Thanks