Sign in to follow this  
Followers 0
PartyPooper

How to select subitems in a listview?

8 posts in this topic

Ok, I would like to be able to select subitems from a listview and launch an on-event action. The code below is a modified sample taken out of the help file. As you can see, you can select items in Column 1 easily enough, but not Column 2 or 3. What changes to the code do I need to make it so I can select items in those columns?

#AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>

Opt('MustDeclareVars', 1)

$Debug_LV = False ; Check ClassName being passed to ListView functions, set to True and use a handle to another control to see it work

_Main()

Func _Main()
    Local $hImage, $hListView

    ; Create GUI
    GUICreate("ListView Set Extended Style", 400, 300)
    $hListView = GUICtrlCreateListView("", 2, 2, 394, 268)
    _GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_DOUBLEBUFFER, $LVS_EX_SUBITEMIMAGES))
    GUISetState()

    ; Load images
    $hImage = _GUIImageList_Create()
    _GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($hListView, 0xFF0000, 16, 16))
    _GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($hListView, 0x00FF00, 16, 16))
    _GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($hListView, 0x0000FF, 16, 16))
    _GUICtrlListView_SetImageList($hListView, $hImage, 1)

    ; Add columns
    _GUICtrlListView_InsertColumn($hListView, 0, "Column 1", 100)
    _GUICtrlListView_InsertColumn($hListView, 1, "Column 2", 100)
    _GUICtrlListView_InsertColumn($hListView, 2, "Column 3", 100)

    ; Add items
    _GUICtrlListView_AddItem($hListView, "Row 1: Col 1", 0)
    _GUICtrlListView_AddSubItem($hListView, 0, "Row 1: Col 2", 1, 1)
    _GUICtrlListView_AddSubItem($hListView, 0, "Row 1: Col 3", 2, 2)
    _GUICtrlListView_AddItem($hListView, "Row 2: Col 1", 1)
    _GUICtrlListView_AddSubItem($hListView, 1, "Row 2: Col 2", 1, 2)
    _GUICtrlListView_AddItem($hListView, "Row 3: Col 1", 2)

    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
EndFunc   ;==>_Main

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

If you want to know what subitems the user has selected please have a look at the example in the help file for _GUICtrlListView_Create. It shows (among other info) the item and subitem selected by the user. This might be a good starting point.

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Unfortunately it only shows how to do full row selects, not single sub item selects like I want, but it does point to WM_NOTIFY as a means to identify which subitem has been clicked so thanks for that.

Share this post


Link to post
Share on other sites

Running the example using SciTe I get the following result when clicking on row 2 column 2:

-->Line(0335): $NM_CLICK

--> hWndFrom: 0x00020654

-->IDFrom: 10000

-->Code: -2

-->Index: 1

-->SubItem: 1

-->NewState: 0

-->OldState: 1031

-->Changed: 0

-->ActionX: 0

-->ActionY: 0

-->lParam: 9237424

-->KeyFlags: 0

So Index and SubItem should give you the info you need. Or do I misinterpret something?

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Working out which subitem pressed isn't a problem, it's highlighting or 'selecting' the subitem on the GUI that I can't seem to work out. The code I posted above will give you the idea if you run it.

Share this post


Link to post
Share on other sites

Anyone?

Share this post


Link to post
Share on other sites

_GUICtrlListView_SetItemEx let you define the SubItem member. So you can apply the $LVIS_SELECTED to individual subitems.

However subitems stay in that state until deselected. First row items get deselected automatically.

Maybe a global $LastSelectedItem variable is useful here to deselect the old item when a new one is being selected.

The GDI draw example with rightclick may also be helpful.

#AutoIt3Wrapper_au3check_parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>




$Debug_LV = False ; Check ClassName being passed to ListView functions, set to True and use a handle to another control to see it work



; Create GUI
GUICreate("ListView Set Extended Style", 400, 300)
$ListView = GUICtrlCreateListView("", 2, 2, 394, 268);, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS), BitOR($LVS_EX_HEADERDRAGDROP, $LVS_EX_FULLROWSELECT,$LVS_EX_GRIDLINES,$LVS_EX_DOUBLEBUFFER,$LVS_EX_SUBITEMIMAGES))
$hListView = GUICtrlGetHandle($ListView)
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_DOUBLEBUFFER, $LVS_EX_SUBITEMIMAGES))
GUIRegisterMsg($WM_NOTIFY, "MY_WM_NOTIFY")
GUISetState()

; Load images
$hImage = _GUIImageList_Create()
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($ListView, 0xFF0000, 16, 16))
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($ListView, 0x00FF00, 16, 16))
_GUIImageList_Add($hImage, _GUICtrlListView_CreateSolidBitMap($ListView, 0x0000FF, 16, 16))
_GUICtrlListView_SetImageList($ListView, $hImage, 1)

; Add columns
_GUICtrlListView_InsertColumn($ListView, 0, "Column 1", 100)
_GUICtrlListView_InsertColumn($ListView, 1, "Column 2", 100)
_GUICtrlListView_InsertColumn($ListView, 2, "Column 3", 100)

; Add items
For $i = 0 To 10
    _GUICtrlListView_AddItem($ListView, "Row "&$i&": Col 1", 0)
    _GUICtrlListView_AddSubItem($ListView, $i, "Row "&$i&": Col 2", 1, 1)
    _GUICtrlListView_AddSubItem($ListView, $i, "Row "&$i&": Col 3", 2, 2)
next




; Loop until user exits
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

GUIDelete()

 
 
 
 Func MY_WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $tNMHDR, $hWndFrom, $iCode
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    
    Switch $hWndFrom
        Case $hListView
            Switch $iCode
                Case $NM_RCLICK
                    
                    $aHit = _GUICtrlListView_SubItemHitTest($hWndFrom)
                    $LVEIP_Item = $aHit[0]
                    $LVEIP_SubItem = $aHit[1]
                    
                    If ($LVEIP_Item <> -1) And ($LVEIP_SubItem = 0) Then
;~                      ConsoleWrite("0 $LVEIP_Item: "&$LVEIP_Item&", $LVEIP_SubItem: "&$LVEIP_SubItem& @CRLF)
                        Local $aPos = _GUICtrlListView_GetItemRect($hWndFrom, $LVEIP_Item, 2)
                    ElseIf ($LVEIP_Item <> -1) And ($LVEIP_SubItem > 0) Then
;~                      ConsoleWrite("1 $LVEIP_Item: "&$LVEIP_Item&", $LVEIP_SubItem: "&$LVEIP_SubItem& @CRLF)
                        Local $aPos = _GUICtrlListView_GetSubItemRect($hWndFrom, $LVEIP_Item, $LVEIP_SubItem) ; does consider dropped items, needs Subitem
                    Else
                        Return $GUI_RUNDEFMSG
                    EndIf


;~                  ConsoleWrite($aPos[0]&","& $aPos[1]&","& $aPos[2] &","& $aPos[3] & @CRLF)
;~                     Local $iX = $aPos[0] + $aRect[0]
;~                     Local $iY = $aPos[1] + $aRect[1] + 1
;~                      $iW = $aPos[0] + $aRect[2] - $iX
;~                      $iH = $aPos[1] + $aRect[3] - $iY
;~                  ConsoleWrite($iX&","& $iY&","& $iW &","& $iH  & @CRLF)
                    $LVEIP_hDC = _WinAPI_GetWindowDC($hWndFrom)
;~                  _WinAPI_SetBkColor($LVEIP_hDC, 0x0000FF)
                    $LVEIP_hBrush = _WinAPI_CreateSolidBrush(0x0000FF)
                    FrameRect($LVEIP_hDC, $aPos[0], $aPos[1],$aPos[2],$aPos[3],$LVEIP_hBrush)
                    _WinAPI_DeleteObject($LVEIP_hBrush)
                    _WinAPI_ReleaseDC($hWndFrom,$LVEIP_hDC)

                Case $NM_CLICK

                    $aHit = _GUICtrlListView_SubItemHitTest($hWndFrom)
                    $LVEIP_Item = $aHit[0]
                    $LVEIP_SubItem = $aHit[1]

                    ConsoleWrite("Leftclick LV: "&$hWndFrom&", $LVEIP_Item: "&$LVEIP_Item&", $LVEIP_SubItem: "&$LVEIP_SubItem& @CRLF)

                    Local $tItem
                    $tItem = DllStructCreate($tagLVITEM)
                    DllStructSetData($tItem, "Mask", $LVIF_STATE)
                    DllStructSetData($tItem, "Item", $LVEIP_Item)
                    DllStructSetData($tItem, "SubItem", $LVEIP_SubItem)
                    DllStructSetData($tItem, "State", $LVIS_SELECTED)
                    DllStructSetData($tItem, "StateMask", $LVIS_SELECTED)
                    _GUICtrlListView_SetItemEx($hWndFrom, $tItem)

                Case $LVN_ITEMCHANGING
                    Return 1 ; prevent LV from selecting through mouseclick

                EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Func FrameRect($hDC, $nLeft, $nTop, $nRight, $nBottom, $LVEIP_hBrush)
    Local $stRect = DllStructCreate("int;int;int;int")
    DllStructSetData($stRect, 1, $nLeft)
    DllStructSetData($stRect, 2, $nTop)
    DllStructSetData($stRect, 3, $nRight)
    DllStructSetData($stRect, 4, $nBottom)
    DllCall("user32.dll", "int", "FrameRect", "hwnd", $hDC, "ptr", DllStructGetPtr($stRect), "hwnd", $LVEIP_hBrush)
;~  ConsoleWrite("urg:"&$nRight&", "&$nBottom & @CRLF)
EndFunc

Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite

Share this post


Link to post
Share on other sites

Cool, thanks qsek, it'll give me something to work with now I know it's possible. :D

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