Jump to content
Sign in to follow this  
PartyPooper

How to select subitems in a listview?

Recommended Posts

PartyPooper

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
water

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
PartyPooper

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
water

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
PartyPooper

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
qsek

_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
PartyPooper

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  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.