﻿id	summary	reporter	owner	description	type	status	milestone	component	version	severity	resolution	keywords	cc
1996	_GUICtrlListView_SimpleSort  -  no sort ItemParam	anonymous	guinness	"I've posted this as feature request (Ticket #1930). It was no answer there and i think more, it is a bug.

If you set an ItemParam and sort the listview with _GUICtrlListView_SimpleSort, the Itemparam depends always on the item index instead on the item content and so it is no sorted.

Here i've an example to show this and also an solution. Some changes in _GUICtrlListView_SimpleSort will solve the problem.


{{{
#include-once
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>

Opt('MustDeclareVars', 1)

Global $hWndLV
Local $listview, $button, $radio1, $radio2, $combo, $item1, $item2, $item3, $msg, $index

GUICreate(""different sort"", 220, 250, 100, 200)

$listview = GUICtrlCreateListView(""col1  |col2|col3  "", 10, 10, 200, 100)
$hWndLV = GUICtrlGetHandle($listview)
$button = GUICtrlCreateButton(""Get IParam Item Index:"", 10, 120, 130, 20)
$combo = GUICtrlCreateCombo('', 145, 120, 50, 20)
GUICtrlSetData(-1, '0|1|2', '0')
GUICtrlCreateLabel('Sort by column click with both functions', 10, 150)
GUICtrlCreateLabel('See the difference in IParam', 10, 175)
$radio1 = GUICtrlCreateRadio(""Sort, normal version"", 10, 200, 180, 20)
GUICtrlSetState(-1, $GUI_CHECKED)
$radio2 = GUICtrlCreateRadio(""Sort, modified version"", 10, 220, 180, 20)
$item1 = GUICtrlCreateListViewItem(""aaaaa|fffff|hhhhh"", $listview)
$item2 = GUICtrlCreateListViewItem(""bbbbb|eeeee|ggggg"", $listview)
$item3 = GUICtrlCreateListViewItem(""ccccc|ddddd|iiiii"", $listview)

; == ItemParam should depend on content of an listview item - not on the index
_GUICtrlListView_SetItemParam($hWndLV, 0, 990)
_GUICtrlListView_SetItemParam($hWndLV, 1, 991)
_GUICtrlListView_SetItemParam($hWndLV, 2, 992)

Global $B_DESCENDING[_GUICtrlListView_GetColumnCount($hWndLV)]

GUISetState()
GUIRegisterMsg($WM_NOTIFY, ""WM_NOTIFY"")


While True
    Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
			Exit
		Case $button
			$index = GUICtrlRead($combo)
			MsgBox(0, 'ItemParam LV-Item: ' & $combo, _GUICtrlListView_GetItemParam($hWndLV, $index), 2)
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $hWndFrom, $iCode, $tNMHDR, $tInfo
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, ""hWndFrom""))
    $iCode = DllStructGetData($tNMHDR, ""Code"")
	If $hWndFrom = $hWndLV And $iCode =  $LVN_COLUMNCLICK Then
		$tInfo = DllStructCreate($tagNMLISTVIEW, $lParam)
		If BitAND(GUICtrlRead($radio1), $GUI_CHECKED) Then
			_GUICtrlListView_SimpleSort($hWndFrom, $B_DESCENDING, DllStructGetData($tInfo, ""SubItem""))
			; == ItemParam is not sorted, depends on item index ==> it's a bug
		Else
			__GUICtrlListView_SimpleSort($hWndFrom, $B_DESCENDING, DllStructGetData($tInfo, ""SubItem""))
			; == now ItemParam depends on item content ==> that's what we want
		EndIf
	EndIf
	Return $GUI_RUNDEFMSG
EndFunc


; my modified version of _GUICtrlListView_SimpleSort:
Func __GUICtrlListView_SimpleSort($hWnd, ByRef $vDescending, $iCol)
	Local $x, $Y, $Z, $b_desc, $columns, $items, $v_item, $temp_item, $iFocused = -1
	Local $SeparatorChar = Opt('GUIDataSeparatorChar')
	If _GUICtrlListView_GetItemCount($hWnd) Then
		If (IsArray($vDescending)) Then
			$b_desc = $vDescending[$iCol]
		Else
			$b_desc = $vDescending
		EndIf
		$columns = _GUICtrlListView_GetColumnCount($hWnd)
		$items = _GUICtrlListView_GetItemCount($hWnd)
		For $x = 1 To $columns
			$temp_item = $temp_item & "" "" & $SeparatorChar
		Next
		$temp_item = StringTrimRight($temp_item, 1)
		Local $a_lv[$items][$columns + 2], $i_selected ; add column for IParam   ### MODIFIED ###

		$i_selected = StringSplit(_GUICtrlListView_GetSelectedIndices($hWnd), $SeparatorChar)
		For $x = 0 To UBound($a_lv) - 1 Step 1
			If $iFocused = -1 Then
				If _GUICtrlListView_GetItemFocused($hWnd, $x) Then $iFocused = $x
			EndIf
			_GUICtrlListView_SetItemSelected($hWnd, $x, False)
			For $Y = 0 To UBound($a_lv, 2) - 3 Step 1                          ;  ### MODIFIED ###
				$v_item = StringStripWS(_GUICtrlListView_GetItemText($hWnd, $x, $Y), 2)
				If (StringIsFloat($v_item) Or StringIsInt($v_item)) Then
					$a_lv[$x][$Y] = Number($v_item)
				Else
					$a_lv[$x][$Y] = $v_item
				EndIf
			Next
			$a_lv[$x][$Y] = $x
			$a_lv[$x][$Y+1] = _GUICtrlListView_GetItemParam($hWnd, $x)         ;  ### NEW ###
		Next
		_ArraySort($a_lv, $b_desc, 0, 0, $iCol)
		For $x = 0 To UBound($a_lv) - 1 Step 1
			For $Y = 0 To UBound($a_lv, 2) - 3 Step 1                          ;  ### MODIFIED ###
				_GUICtrlListView_SetItemText($hWnd, $x, $a_lv[$x][$Y], $Y)
			Next
			_GUICtrlListView_SetItemParam($hWnd, $x, $a_lv[$x][$Y+1])          ;  ### NEW ###
			For $Z = 1 To $i_selected[0]
				If $a_lv[$x][UBound($a_lv, 2) - 2] = $i_selected[$Z] Then      ;  ### MODIFIED ###
					If $a_lv[$x][UBound($a_lv, 2) - 2] = $iFocused Then        ;  ### MODIFIED ###
						_GUICtrlListView_SetItemSelected($hWnd, $x, True, True)
					Else
						_GUICtrlListView_SetItemSelected($hWnd, $x, True)
					EndIf
					ExitLoop
				EndIf
			Next
		Next
		If (IsArray($vDescending)) Then
			$vDescending[$iCol] = Not $b_desc
		Else
			$vDescending = Not $b_desc
		EndIf
	EndIf
EndFunc   ;==>__GUICtrlListView_SimpleSort
}}}
"	Bug	closed	3.3.9.5	Standard UDFs	3.3.6.1	None	Fixed	sort ItemParam	
