Jump to content

Recommended Posts

Posted (edited)

Has anyone had any luck acquiring the latest checked state of items in a listview.  I can't find a good example.

From help: (This only shows a MsgBox when clicking on the header and it displays the column)

Copy to clipboard #include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <WindowsConstants.au3>

Example()

Func Example()
    GUICreate("listview items", 220, 250, 100, 200, -1, $WS_EX_ACCEPTFILES)
    GUISetBkColor(0x00E0FFFF) ; will change background color

    Local $idListview = GUICtrlCreateListView("col1  |col2|col3  ", 10, 10, 200, 150) ;,$LVS_SORTDESCENDING)
    Local $idButton = GUICtrlCreateButton("Value?", 75, 170, 70, 20)
    Local $idItem1 = GUICtrlCreateListViewItem("item2|col22|col23", $idListview)
    Local $idItem2 = GUICtrlCreateListViewItem("item1|col12|col13", $idListview)
    Local $idItem3 = GUICtrlCreateListViewItem("item3|col32|col33", $idListview)
    GUICtrlCreateInput("", 20, 200, 150)
    GUICtrlSetState(-1, $GUI_DROPACCEPTED) ; to allow drag and dropping
    GUISetState(@SW_SHOW)
    GUICtrlSetData($idItem2, "ITEM1")
    GUICtrlSetData($idItem3, "||COL33")
    GUICtrlDelete($idItem1)

    ; Loop until the user exits.
    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $idButton
                MsgBox($MB_SYSTEMMODAL, "listview item", GUICtrlRead(GUICtrlRead($idListview)), 2)

            Case $idListview
                MsgBox($MB_SYSTEMMODAL, "listview", "clicked=" & GUICtrlGetState($idListview), 2)

        EndSwitch
    WEnd
EndFunc   ;==>Example

From one of the examples: This looks perfect except it requires me to know a row I'd like to query for checkmark ahead of time. I am not sure how to receive the row which had a checkbox checked. 

 

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

Example()

Func Example()
    Local $iStylesEx = BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_CHECKBOXES), $idListview

    GUICreate("ListView Set Item Checked State", 400, 300)
    $idListview = GUICtrlCreateListView("", 2, 2, 394, 268)
    _GUICtrlListView_SetExtendedListViewStyle($idListview, $iStylesEx)
    GUISetState(@SW_SHOW)

    ; Add columns
    _GUICtrlListView_AddColumn($idListview, "Column 1", 100)
    _GUICtrlListView_AddColumn($idListview, "Column 2", 100)
    _GUICtrlListView_AddColumn($idListview, "Column 3", 100)

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

    ; Check item 2
    _GUICtrlListView_SetItemChecked($idListview, 2)
    MsgBox($MB_SYSTEMMODAL, "Information", "Item 2 Checked: " & _GUICtrlListView_GetItemChecked($idListview, 1)) ; Checks if row 2 is checked

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

If I can figure out how to enable a user to check a box and it call a function with the row number checked for that 2nd example, it will fit my current project needs 🙂

Thanks

Edited by NassauSky
Posted (edited)

Here is one solution but every time I click on a row checkbox, the resulting function is 1 check behind:

 

#include <GUIConstantsEx.au3>
#include <GuiImageList.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>

Global $g_hListView

Example()

Func Example()
    Local $iStylesEx = BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_CHECKBOXES), $idListview

    GUICreate("ListView Set Item Checked State", 400, 300)
    $g_hListView = GUICtrlCreateListView("", 2, 2, 394, 268)
    _GUICtrlListView_SetExtendedListViewStyle($g_hListView, $iStylesEx)
    GUISetState(@SW_SHOW)

    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

    ; Add columns
    _GUICtrlListView_AddColumn($g_hListView, "Column 1", 100)
    _GUICtrlListView_AddColumn($g_hListView, "Column 2", 100)
    _GUICtrlListView_AddColumn($g_hListView, "Column 3", 100)

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

    ; Check item 2
    _GUICtrlListView_SetItemChecked($g_hListView, 2)

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

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
    ; Local $tBuffer
    $hWndListView = $g_hListView
    If Not IsHWnd($g_hListView) Then $hWndListView = GUICtrlGetHandle($g_hListView)

    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndListView
            ;ConsoleWrite("$iCode: " & $iCode & @CRLF)
            Switch $iCode
                Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
                    $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
                    _DebugPrint("$NM_CLICK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
                            "-->Code:" & @TAB & $iCode & @CRLF & _
                            "-->RowIndex(0Based):" & @TAB & DllStructGetData($tInfo, "Index") & @CRLF & _
                            "-->ColSubItem(0Based):" & @TAB & DllStructGetData($tInfo, "SubItem") & @CRLF & _
                            "-->NewState:" & @TAB & DllStructGetData($tInfo, "NewState") & @CRLF & _
                            "-->OldState:" & @TAB & DllStructGetData($tInfo, "OldState") & @CRLF & _
                            "-->Changed:" & @TAB & DllStructGetData($tInfo, "Changed") & @CRLF & _
                            "-->ActionX:" & @TAB & DllStructGetData($tInfo, "ActionX") & @CRLF & _
                            "-->ActionY:" & @TAB & DllStructGetData($tInfo, "ActionY") & @CRLF & _
                            "-->lParam:" & @TAB & DllStructGetData($tInfo, "lParam") & @CRLF & _
                            "-->KeyFlags:" & @TAB & DllStructGetData($tInfo, "KeyFlags"))
                     _MyFunction()
                    ; No return value
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func _DebugPrint($s_Text, $sLine = @ScriptLineNumber)
    ConsoleWrite( _
            "!===========================================================" & @CRLF & _
            "+======================================================" & @CRLF & _
            "-->Line(" & StringFormat("%04d", $sLine) & "):" & @TAB & $s_Text & @CRLF & _
            "+======================================================" & @CRLF)
EndFunc   ;==>_DebugPrint

Func _GUICtrlListView_GetItemsArray($f_iCtrl)
    ; Get row and colum count
    Local $l_iRows = GUICtrlSendMsg($f_iCtrl, $LVM_GETITEMCOUNT, 0, 0)
    Local $l_iCols = _SendMessage(HWnd(GUICtrlSendMsg($f_iCtrl, $LVM_GETHEADER, 0, 0)), 0x1200)

    ; Error checking
    If $l_iRows * $l_iCols = 0 Then Return SetError(1)
    If IsHWnd($f_iCtrl) Then Return SetError(2)

    ; Create result array
    Local $l_aListView[$l_iRows][$l_iCols]

    ; Create structure and pointer
    Local $l_boUnicode = (GUICtrlSendMsg($f_iCtrl, $LVM_GETUNICODEFORMAT, 0, 0) <> 0)
    Local $l_hMessage = $l_boUnicode ? $LVM_GETITEMTEXTW : $LVM_GETITEMTEXTA
    Local $l_tBuffer = DllStructCreate($l_boUnicode ? "wchar Text[4096]" : "char Text[4096]")
    Local $l_pBuffer = DllStructGetPtr($l_tBuffer)
    Local $l_tItem = DllStructCreate($tagLVITEM)
    DllStructSetData($l_tItem, "TextMax", 4096)
    Local $l_pItem
    DllStructSetData($l_tItem, "Text", $l_pBuffer)

    ; Loop through listview
    For $l_iRow = 0 To $l_iRows - 1
        For $l_iCol = 0 To $l_iCols - 1
            ; Set data in structure
            DllStructSetData($l_tItem, "SubItem", $l_iCol)
            $l_pItem = DllStructGetPtr($l_tItem)
            DllStructSetData($l_tItem, "Text", $l_pBuffer)

            ;Get Data and populate array
            GUICtrlSendMsg($f_iCtrl, $l_hMessage, $l_iRow, $l_pItem)
            $l_aListView[$l_iRow][$l_iCol] = DllStructGetData($l_tBuffer, "Text")
        Next
    Next
    Return $l_aListView
EndFunc   ;==>_GUICtrlListView_GetItemsArray



Func _MyFunction()
      ConsoleWrite("Entered MyFunction" & @CRLF)
      ;$aListview = _GUICtrlListView_CreateArray($g_hListView)
      $aListview = _GUICtrlListView_GetItemsArray($g_hListView)
      ;_ArrayDisplay($aListview)
      For $x = 0 To UBound($aListview) - 1
         ConsoleWrite("Row[" & $x & "] checked: " & _GUICtrlListView_GetItemChecked($g_hListView, $x) & @CRLF)
      Next
EndFunc

 

Edited by NassauSky
Posted

Because it is triggered on Mouse Down.  Do it slowly by holding the mouse down a few sec.  See, it is triggered before the change happens.  There is multiple ways to solve this issue.  One way is to use dummy :

Spoiler
#include <GUIConstantsEx.au3>
#include <GuiImageList.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>

Global $g_hListView, $idDummy

Example()

Func Example()
  Local $iStylesEx = BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_CHECKBOXES), $idListview

  GUICreate("ListView Set Item Checked State", 400, 300)
  $g_hListView = GUICtrlCreateListView("", 2, 2, 394, 268)
  _GUICtrlListView_SetExtendedListViewStyle($g_hListView, $iStylesEx)
  GUISetState(@SW_SHOW)

  GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

  ; Add columns
  _GUICtrlListView_AddColumn($g_hListView, "Column 1", 100)
  _GUICtrlListView_AddColumn($g_hListView, "Column 2", 100)
  _GUICtrlListView_AddColumn($g_hListView, "Column 3", 100)

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

  ; Check item 2
  _GUICtrlListView_SetItemChecked($g_hListView, 2)

  $idDummy = GUICtrlCreateDummy()

  ; Loop until the user exits.
  While True
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        ExitLoop
      Case $idDummy
        _MyFunction()
    EndSwitch
  WEnd
EndFunc   ;==>Example

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
  #forceref $hWnd, $iMsg, $wParam
  Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
  ; Local $tBuffer
  $hWndListView = $g_hListView
  If Not IsHWnd($g_hListView) Then $hWndListView = GUICtrlGetHandle($g_hListView)

  $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
  $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
  $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
  $iCode = DllStructGetData($tNMHDR, "Code")
  Switch $hWndFrom
    Case $hWndListView
      ;ConsoleWrite("$iCode: " & $iCode & @CRLF)
      Switch $iCode
        Case $NM_CLICK         ; Sent by a list-view control when the user clicks an item with the left mouse button
          $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam)
          _DebugPrint("$NM_CLICK" & @CRLF & "--> hWndFrom:" & @TAB & $hWndFrom & @CRLF & _
              "-->IDFrom:" & @TAB & $iIDFrom & @CRLF & _
              "-->Code:" & @TAB & $iCode & @CRLF & _
              "-->RowIndex(0Based):" & @TAB & DllStructGetData($tInfo, "Index") & @CRLF & _
              "-->ColSubItem(0Based):" & @TAB & DllStructGetData($tInfo, "SubItem") & @CRLF & _
              "-->NewState:" & @TAB & DllStructGetData($tInfo, "NewState") & @CRLF & _
              "-->OldState:" & @TAB & DllStructGetData($tInfo, "OldState") & @CRLF & _
              "-->Changed:" & @TAB & DllStructGetData($tInfo, "Changed") & @CRLF & _
              "-->ActionX:" & @TAB & DllStructGetData($tInfo, "ActionX") & @CRLF & _
              "-->ActionY:" & @TAB & DllStructGetData($tInfo, "ActionY") & @CRLF & _
              "-->lParam:" & @TAB & DllStructGetData($tInfo, "lParam") & @CRLF & _
              "-->KeyFlags:" & @TAB & DllStructGetData($tInfo, "KeyFlags"))
          GUICtrlSendToDummy($idDummy)
          ; No return value
      EndSwitch
  EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func _DebugPrint($s_Text, $sLine = @ScriptLineNumber)
  ConsoleWrite( _
      "!===========================================================" & @CRLF & _
      "+======================================================" & @CRLF & _
      "-->Line(" & StringFormat("%04d", $sLine) & "):" & @TAB & $s_Text & @CRLF & _
      "+======================================================" & @CRLF)
EndFunc   ;==>_DebugPrint

Func _GUICtrlListView_GetItemsArray($f_iCtrl)
  ; Get row and colum count
  Local $l_iRows = GUICtrlSendMsg($f_iCtrl, $LVM_GETITEMCOUNT, 0, 0)
  Local $l_iCols = _SendMessage(HWnd(GUICtrlSendMsg($f_iCtrl, $LVM_GETHEADER, 0, 0)), 0x1200)

  ; Error checking
  If $l_iRows * $l_iCols = 0 Then Return SetError(1)
  If IsHWnd($f_iCtrl) Then Return SetError(2)

  ; Create result array
  Local $l_aListView[$l_iRows][$l_iCols]

  ; Create structure and pointer
  Local $l_boUnicode = (GUICtrlSendMsg($f_iCtrl, $LVM_GETUNICODEFORMAT, 0, 0) <> 0)
  Local $l_hMessage = $l_boUnicode ? $LVM_GETITEMTEXTW : $LVM_GETITEMTEXTA
  Local $l_tBuffer = DllStructCreate($l_boUnicode ? "wchar Text[4096]" : "char Text[4096]")
  Local $l_pBuffer = DllStructGetPtr($l_tBuffer)
  Local $l_tItem = DllStructCreate($tagLVITEM)
  DllStructSetData($l_tItem, "TextMax", 4096)
  Local $l_pItem
  DllStructSetData($l_tItem, "Text", $l_pBuffer)

  ; Loop through listview
  For $l_iRow = 0 To $l_iRows - 1
    For $l_iCol = 0 To $l_iCols - 1
      ; Set data in structure
      DllStructSetData($l_tItem, "SubItem", $l_iCol)
      $l_pItem = DllStructGetPtr($l_tItem)
      DllStructSetData($l_tItem, "Text", $l_pBuffer)

      ;Get Data and populate array
      GUICtrlSendMsg($f_iCtrl, $l_hMessage, $l_iRow, $l_pItem)
      $l_aListView[$l_iRow][$l_iCol] = DllStructGetData($l_tBuffer, "Text")
    Next
  Next
  Return $l_aListView
EndFunc   ;==>_GUICtrlListView_GetItemsArray



Func _MyFunction()
  ConsoleWrite("Entered MyFunction" & @CRLF)
  ;$aListview = _GUICtrlListView_CreateArray($g_hListView)
  $aListview = _GUICtrlListView_GetItemsArray($g_hListView)
  ;_ArrayDisplay($aListview)
  For $x = 0 To UBound($aListview) - 1
    ConsoleWrite("Row[" & $x & "] checked: " & _GUICtrlListView_GetItemChecked($g_hListView, $x) & @CRLF)
  Next
EndFunc   ;==>_MyFunction

 

 

Posted

Thanks @Nine. I got it to work for the time being with just using a double click to call my function.  Not sure exactly what you mean by using a dummy. I guess I'll go digging up what that means in reference to using a single click to select an item without a listview delay. Not exactly sure what search terms I'd use. 😕

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
×
×
  • Create New...