Modify

Opened 11 years ago

Closed 11 years ago

Last modified 11 years ago

#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 Changed 11 years ago by Jpm

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

comment:2 Changed 11 years ago by Gary

  • Component changed from AutoIt to Standard UDFs
  • Resolution set to Rejected
  • Status changed from new to closed

Learn how to use GUICtrlRegisterListView rather than a standard sort.

comment:3 Changed 11 years ago by anonymous

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 Changed 11 years ago by partypooper@…

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 Changed 11 years ago by Jpm

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 Changed 11 years ago by anonymous

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 Changed 11 years ago by TicketCleanup

  • Version 3.3.1.1 deleted

Automatic ticket cleanup.

Guidelines for posting comments:

  • You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
  • In-depth discussions should take place on the forum.

For more information see the full version of the ticket guidelines here.

Add Comment

Modify Ticket

Action
as closed The ticket will remain with no owner.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.