Sign in to follow this  
Followers 0
Jaque

_GUICtrlListViewSort

4 posts in this topic

Hello,

I think _GUICtrlListViewSort contains a bug. Could you please have a look at the example script below. If I select the checkbox in front of "222" and next I sort on column 2 by pressing "Column 2", then the checkboxes and its checked state don't sort along, the checkboxes and its checked state stay were they are. All the other items are sorted. Is this a bug, or can I overcome this.

I am using AutoIt v3.1.1.127 (beta).

Thank you.

Jaque

#include <GUIConstants.au3>
#include <GuiListView.au3>
#Include <GuiList.au3>

$gui=GUICreate("TEST APP!",-1,-1,-1,-1,$WS_CAPTION+$WS_POPUP+$WS_MAXIMIZEBOX+$WS_MINIMIZEBOX+$WS_SIZEBOX+$WS_MAXIMIZE)
$listview = GUICtrlCreateListView("Column 1|Column 2|Column3",0,50,500,400,$WS_VSCROLL,$LVS_EX_CHECKBOXES+$LVS_EX_GRIDLINES)
GUICtrlCreateListViewItem("444|444|444",$listview)
GUICtrlCreateListViewItem("333|333|333",$listview)
GUICtrlCreateListViewItem("222|222|222",$listview)
GUICtrlCreateListViewItem("111|111|111",$listview)
GUISetState(@SW_SHOW,$gui)

Dim $B_DESCENDING[_GUICtrlListViewGetSubItemsCount($listview)]
While 1
  $msg = GUIGetMsg()
  Select
    Case $msg = $GUI_EVENT_CLOSE
      ExitLoop
    Case $msg = $listview
      _GUICtrlListViewSort($listview, $B_DESCENDING, GUICtrlGetState($listview))
  EndSelect
Wend

Share this post


Link to post
Share on other sites



Not a bug, this sort is a simple sort, it does not work with check boxes/images etc... only the data

if you want a complex sort that works with other than just the data I suggest looking into GUICtrlRegisterListViewSort function


SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites

Here's an example of your script using the GUICtrlRegisterListViewSort function

#include <GUIConstants.au3>

Global Const $LVFI_PARAM = 0x0001
Global Const $LVIF_TEXT = 0x0001
Global Const $LVM_FIRST = 0x1000
Global Const $LVM_GETITEM = $LVM_FIRST + 5
Global Const $LVM_FINDITEM = $LVM_FIRST + 13
Global Const $LVM_SETSELECTEDCOLUMN = $LVM_FIRST + 140

Dim $nCurCol = -1
Dim $nSortDir = 1
Dim $bSet = 0
Dim $nCol = -1

$gui = GUICreate("TEST APP!", -1, -1, -1, -1, $WS_CAPTION + $WS_POPUP + $WS_MAXIMIZEBOX + $WS_MINIMIZEBOX + $WS_SIZEBOX + $WS_MAXIMIZE)
$listview = GUICtrlCreateListView("Column 1|Column 2|Column3", 0, 50, 500, 400, $WS_VSCROLL, $LVS_EX_CHECKBOXES + $LVS_EX_GRIDLINES)
GUICtrlRegisterListViewSort(-1, "LVSort") ; Register the function "SortLV" for the sorting callback
GUICtrlCreateListViewItem("444|444|444", $listview)
GUICtrlCreateListViewItem("333|333|333", $listview)
GUICtrlCreateListViewItem("222|222|222", $listview)
GUICtrlCreateListViewItem("111|111|111", $listview)
GUISetState(@SW_SHOW, $gui)

While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
        Case $msg = $listview
            $bSet = 0
            $nCurCol = $nCol
            GUICtrlSendMsg($listview, $LVM_SETSELECTEDCOLUMN, GUICtrlGetState($listview), 0)
            DllCall("user32.dll", "int", "InvalidateRect", "hwnd", GUICtrlGetHandle($listview), "int", 0, "int", 1)
    EndSelect
WEnd

; Our sorting callback funtion
Func LVSort($hWnd, $nItem1, $nItem2, $nColumn)
    Local $nSort
    
    ; 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($listview, $nItem1, $nColumn)
    $val2 = GetSubItemText($listview, $nItem2, $nColumn)
    
    $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")
    DllStructSetData($stLvfi, 1, $LVFI_PARAM)
    DllStructSetData($stLvfi, 3, $nItemID)
    
    Local $stBuffer = DllStructCreate("char[260]")
    
    $nIndex = GUICtrlSendMsg($nCtrlID, $LVM_FINDITEM, -1, DllStructGetPtr($stLvfi));
    
    Local $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_GETITEM, 0, DllStructGetPtr($stLvi));
    
    $sItemText = DllStructGetData($stBuffer, 1)
    
    $stLvi = 0
    $stLvfi = 0
    $stBuffer = 0
    
    Return $sItemText
EndFunc   ;==>GetSubItemText

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites

@gafrost

Thanks for your quick response and the great example on how to deal with this!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0