Modify

#1107 closed Feature Request (Rejected)

Ability to sort hexadecimal numbers using in a Listview

Reported by: partypooper@… 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:1 by J-Paul Mesnage, on Aug 4, 2009 at 4:13:58 PM

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

comment:2 by Gary, on Aug 4, 2009 at 9:04:33 PM

Component: AutoItStandard UDFs
Resolution: Rejected
Status: newclosed

Learn how to use GUICtrlRegisterListView rather than a standard sort.

comment:3 by anonymous, 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 partypooper@…, 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 J-Paul Mesnage, 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 anonymous, 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.

comment:7 by TicketCleanup, on Aug 7, 2009 at 4:21:30 PM

Version: 3.3.1.1

Automatic ticket cleanup.

Modify Ticket

Action
as closed The ticket will remain with no owner.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.