Sign in to follow this  
Followers 0
Terenz

ListView callback by checkbox

4 posts in this topic

This is my last subject about listview for a long time :D

I'd try to orded the list by state of the checkbox. In theory i know how to do, pratically:

1) Check the state of the checkbox

2) Assign a value based on the checkbox state ( like 1 for True and 0 for False ) 

3) If $val1 < $val2 Then $nResult = -1

4) $val1 > $val2 Then $nResult = 1

The problem is i can't check the value of the checkbox in the callback, the script:

#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <GuiListView.au3>

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

Example1()

; *******************************************************
; Example 1 - sorting 2 column with checkbox
; *******************************************************
Func Example1()
    Local $lv, $msg

    GUICreate("Test", 300, 200)

    $lv = GUICtrlCreateListView("|Col2", 10, 10, 280, 180, -1, $LVS_EX_CHECKBOXES)
    GUICtrlRegisterListViewSort(-1, "LVSort") ; Register the function "SortLV" for the sorting callback

    GUICtrlCreateListViewItem("|ABC", $lv)
    GUICtrlCreateListViewItem("|DEF", $lv)
    GUICtrlCreateListViewItem("|CDE", $lv)
    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

    GUIDelete()
EndFunc   ;==>Example1

; Our sorting callback funtion
Func LVSort($hWnd, $nItem1, $nItem2, $nColumn)
    Local $val1, $val2, $nResult

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

    ; If it is the zero colum (column starts with 0) then order the checkbox
    If $nColumn = 0 Then
        $aItem1 = _GUICtrlListView_GetItem($hWnd, $nItem1)
        $aItem2 = _GUICtrlListView_GetItem($hWnd, $nItem2)
        ConsoleWrite(_GUICtrlListView_GetItemChecked($hWnd, $aItem1[4]) & @CRLF)
        ConsoleWrite(_GUICtrlListView_GetItemChecked($hWnd, $aItem2[4]) & @CRLF)
    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")
    Local $nIndex, $stBuffer, $stLvi, $sItemText

    DllStructSetData($stLvfi, 1, $LVFI_PARAM)
    DllStructSetData($stLvfi, 3, $nItemID)

    $stBuffer = DllStructCreate("char[260]")

    $nIndex = GUICtrlSendMsg($nCtrlID, $LVM_FINDITEM, -1, DllStructGetPtr($stLvfi));

    $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_GETITEMA, 0, DllStructGetPtr($stLvi));

    $sItemText = DllStructGetData($stBuffer, 1)

    $stLvi = 0
    $stLvfi = 0
    $stBuffer = 0

    Return $sItemText
EndFunc   ;==>GetSubItemText

The result of _GetItem + GetItemChecked is always False or always True, maybe is not the better approach.

Thanks for any help


Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Share this post


Link to post
Share on other sites



Hi,

I quickly looked your code and I doubt you are using the _GUICtrlListView_GetItemChecked function correctly, the second parameter is the item index and your code seems complicated.

If it's not the case tell me I'll take a deeper look.

Br, FireFox.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

_GetItem in theory return the index of the item ( [4] - 0-based item image index ) and i'm using that index for _GetItemChecked, i'm wrong?

And if i'm wrong how i can check the index from the item?

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

I have a partially resolved, yes i have made a mistake with the index:

If $nColumn = 0 Then
        $val1 = GetItemIndex($hWnd, $nItem1)
        $val2 = GetItemIndex($hWnd, $nItem2)
        If _GUICtrlListView_GetItemChecked($hWnd, $val1) = False Then $val1 = -1
        If _GUICtrlListView_GetItemChecked($hWnd, $val2) = False Then $val2 = -1
        If _GUICtrlListView_GetItemChecked($hWnd, $val1) = True Then $val1 = 1
        If _GUICtrlListView_GetItemChecked($hWnd, $val2) = True Then $val2 = 1
    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 index of a listview item
Func GetItemIndex($nCtrlID, $nItemID)
    Local $stLvfi = DllStructCreate("uint;ptr;int;int[2];int")
    Local $nIndex, $stBuffer
    DllStructSetData($stLvfi, 1, $LVFI_PARAM)
    DllStructSetData($stLvfi, 3, $nItemID)
    $stBuffer = DllStructCreate("char[260]")
    $nIndex = GUICtrlSendMsg($nCtrlID, $LVM_FINDITEM, -1, DllStructGetPtr($stLvfi));
    Return $nIndex
EndFunc   ;==>GetItemIndex

Yeah i can sort for checkbox :thumbsup:

But now i have a question, after i have order for checkbox i want to order for name the second column, how? Because you can have:

checked - DFE

checked - CDE

Not checked - ABC

Instead of

checked - CDE

checked - DFE

Not checked - ABC

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

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