Modify ↓
Opened 14 years ago
Closed 13 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 13 years ago by trancexx
- Component changed from AutoIt to Standard UDFs
comment:2 Changed 13 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
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.
Note: See
TracTickets for help on using
tickets.

Fixed by revision [7271] in version: 3.3.9.5