Sign in to follow this  
Followers 0
fisofo

_GUICtrlListViewSort and Listview colors

4 posts in this topic

*Sigh* maybe I'm just tired but I can't seem to figure this out. I am coloring rows depending on the contents of a column item, and I've just implemented sorting into my listview, which works great... but when I sort, the colors don't follow the rows.. is there an easy way around this?

Hope that makes sense :">

Share this post


Link to post
Share on other sites



The simple sort routine in the UDFs won't do that, you need to use GUICtrlRegisterListViewSort

For Example:

; *******************************************************
; Example 1 - sorting 3 column's different
; *******************************************************

#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

$hGUI = GUICreate("Test", 300, 200)

;*********************************************************************************
$lv = GUICtrlCreateListView("Column1|Col2|Col3", 10, 10, 280, 180)
GUICtrlSetStyle($lv, $LVS_SORTASCENDING) ; sort ascending on 1st column
;*********************************************************************************
GUICtrlSendMsg($lv, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
GUICtrlSendMsg($lv, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)

$lvi1 = GUICtrlCreateListViewItem("ABC|666|10.05.2004", $lv)
GUICtrlSetImage(-1, "shell32.dll", 7)
GUICtrlSetColor(-1, 0x0000ff)
$lvi2 = GUICtrlCreateListViewItem("DEF|444|11.05.2005", $lv)
GUICtrlSetImage(-1, "shell32.dll", 12)
GUICtrlSetColor(-1, 0xff0000)
$lvi3 = GUICtrlCreateListViewItem("CDE|444|12.05.2004", $lv)
GUICtrlSetImage(-1, "shell32.dll", 3)
;*********************************************************************************
GUICtrlSetStyle($lv, BitOR($LVS_SHOWSELALWAYS, $LVS_SINGLESEL, $LVS_REPORT)) ; turn off sorting
GUICtrlRegisterListViewSort($lv, "LVSort") ; Register the function "SortLV" for the sorting callback
;*********************************************************************************

GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop

        Case $lv
            $bSet = 0
            $nCurCol = $nCol
            GUICtrlSendMsg($lv, $LVM_SETSELECTEDCOLUMN, GUICtrlGetState($lv), 0)
            DllCall("user32.dll", "int", "InvalidateRect", "hwnd", GUICtrlGetHandle($lv), "int", 0, "int", 1)
    EndSwitch
WEnd

Exit


; 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($lv, $nItem1, $nColumn)
    $val2 = GetSubItemText($lv, $nItem2, $nColumn)

    ; If it is the 3rd colum (column starts with 0) then compare the dates
    If $nColumn = 2 Then
        $val1 = StringRight($val1, 4) & StringMid($val1, 4, 2) & StringLeft($val1, 2)
        $val2 = StringRight($val2, 4) & StringMid($val2, 4, 2) & StringLeft($val2, 2)
    EndIf

    $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

The simple sort routine in the UDFs won't do that, you need to use GUICtrlRegisterListViewSort

For Example:

thanks gary, i'll look into it!

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

:)

I have a question (probably a dumb one) ... Can GUICtrlRegisterListViewSort be used on more than one LV at a time?

I have an array of LVs (each contained within a tab) and the first one will sort fine but the rest seem to go thru the motion of sorting but nothing happens.

Func _CreateListView($id = 0, $label = '')
    If $id > UBound($cLV_List)-1 Then
        ReDim $cLV_List[$id+1]
    EndIf

    $cTAB_Name[$id] = GUICtrlCreateTabItem($label)
    $cLV_List[$id] = GUICtrlCreateListView('Col1|Col2|Col3|Col4|Col5|Col6|Col7|Col8|Col9', 9, 55, 575, 422)

    GUICtrlSetStyle($cLV_List[$id], $LVS_SORTASCENDING) ; sort ascending on 1st column
    GUICtrlSendMsg($cLV_List[$id], $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
    GUICtrlSendMsg($cLV_List[$id], $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_FULLROWSELECT, $LVS_EX_FULLROWSELECT)

    GUICtrlSetOnEvent($cLV_List[$id], '_OE_ListViewColumn')

    GUICtrlSetStyle($cLV_List[$id], BitOR($LVS_SHOWSELALWAYS, $LVS_SINGLESEL, $LVS_REPORT)) ; turn off sorting
    GUICtrlRegisterListViewSort($cLV_List[$id], "LVSort") ; Register the function "SortLV" for the sorting callback

    _GUICtrlListViewSetColumnWidth(-1, 0, 140)
    _GUICtrlListViewJustifyColumn(-1, 1, 2)

    For $i = 1 To 8
        _GUICtrlListViewJustifyColumn(-1, $i, 2)
    Next
EndFunc


Func _OE_ListViewColumn()
    $id = _GUICtrlTabGetCurSel($cTAB_Name)
    $bSet = 0
    $nCurCol = $nCol
    GUICtrlSendMsg($cLV_List[$id], $LVM_SETSELECTEDCOLUMN, GUICtrlGetState($cLV_List[$id]), 0)
    DllCall("user32.dll", "int", "InvalidateRect", "hwnd", GUICtrlGetHandle($cLV_List[$id]), "int", 0, "int", 1)
EndFunc

Func LVSort($hWnd, $nItem1, $nItem2, $nColumn)
    $id = _GUICtrlTabGetCurSel($cTAB_Name)
    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($cLV_List[$id], $nItem1, $nColumn)
    $val2 = GetSubItemText($cLV_List[$id], $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

Sorry ... for some reason the codebox stripped out my @CR so all the code is crammed together.

EDIT: Fixed cramming.

Edited by cjconstantine

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