Modify

Opened 8 years ago

Closed 7 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 Changed 7 years ago by trancexx

  • Component changed from AutoIt to Standard UDFs

comment:2 Changed 7 years ago by guinness

  • Milestone set to 3.3.9.5
  • Owner set to guinness
  • Resolution set to Fixed
  • Status changed from new to closed

Fixed by revision [7271] in version: 3.3.9.5

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 owner will remain guinness.
Author


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

 
Note: See TracTickets for help on using tickets.