Modify

Opened 15 years ago

Closed 14 years ago

#1996 closed Bug (Fixed)

_GUICtrlListView_SimpleSort - no sort ItemParam

Reported by: anonymous Owned by: guinness
Milestone: 3.3.9.5 Component: Standard UDFs
Version: 3.3.6.1 Severity: None
Keywords: sort ItemParam Cc:

Description

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

Attachments (0)

Change History (2)

comment:1 by trancexx, 14 years ago

Component: AutoItStandard UDFs

comment:2 by guinness, 14 years ago

Milestone: 3.3.9.5
Owner: set to guinness
Resolution: Fixed
Status: newclosed

Fixed by revision [7271] in version: 3.3.9.5

Modify Ticket

Action
as closed The owner will remain guinness.

Add Comment


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