Jump to content



Photo

Issue Returning Treeview Child and Parent info


  • Please log in to reply
4 replies to this topic

#1 fcgnewbie

fcgnewbie

    Seeker

  • Active Members
  • 11 posts

Posted 19 April 2012 - 09:55 PM

Hi,

I'm trying to return information from all the items that are checked in the treeview. I would like to return if the parent is checked and any children that are checked if the parent isnt checked, either postition (i.e Parent2|Child3|Sibling1 or 2,3,1) or text would work. Ive been trying various "_GUICtrlTree..." functions with little success.

Any direction would be greatly appreciated.

I did find this gem that automaticaly checks child items if the parent is selected. Much respect to Melba23 and Authenticity for that.

http://www.autoitscript.com/forum/topic/...tparenthandle__fromsearch__1#e

I've posted the code that I'm working on.

Plain Text         
#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <TreeViewConstants.au3> #include <GuiTreeView.au3> #include <ButtonConstants.au3> Local $hGUI, $Tree, $hTree, $hItems[40][2] = [[0]] $Form1_1 = GUICreate("Form1", 616, 532, 192, 124) $string = StringSplit("parent1,child1,child2,child3,sibling1,parent2,child1,child2,child3,sibling1",",") $button1 = GUICtrlCreateButton("Select", 40, 200, 100, 50) $List1 = GUICtrlCreateTreeView(40, 260, 530, 200, BitOR($GUI_SS_DEFAULT_TREEVIEW,$TVS_EDITLABELS,$TVS_CHECKBOXES), $WS_EX_CLIENTEDGE) GUISetState(@SW_SHOW) $hTree = GUICtrlGetHandle($List1) $hImage = _GUIImageList_Create(16, 16, 5, 3)     _GUIImageList_AddIcon($hImage, "shell32.dll", 8)     _GUIImageList_AddIcon($hImage, "shell32.dll", 166)     _GUICtrlTreeView_SetNormalImageList($List1, $hImage) _GUICtrlTreeView_BeginUpdate($List1) For $x = 0 To ubound($string) - 1 if StringInStr($string[$x],"parent",0) > 0 Then $tree_disk = _GUICtrlTreeView_Add($List1, 0, $string[$x], 0) EndIf if StringInStr($string[$x],"child",0) > 0 Then $tree_Part =  _GUICtrlTreeView_AddChild($List1, $tree_disk,$string[$x], 1,1) EndIf if StringInStr($string[$x],"sibling",0) > 0 Then     $tree_logical =  _GUICtrlTreeView_AddChild($List1,$tree_Part, $string[$x], 1, 1) EndIf Next    _GUICtrlTreeView_EndUpdate($List1) GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") While 1     $nMsg = GUIGetMsg()     Switch $nMsg         Case $GUI_EVENT_CLOSE             Exit         Case $button1             MsgBox(0,"",_GUICtrlTreeView_GetCount($hTree))     EndSwitch WEnd Func _WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)     Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR     Local $iPos, $iX, $iY, $tPt, $iHitTest, $fWasChecked     Local $hItem     $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)     $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))     $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")     $iCode = DllStructGetData($tNMHDR, "Code")     Switch $hWndFrom         Case $hTree             Switch $iCode                 Case $NM_CLICK                     $iPos = _WinAPI_GetMessagePos()                     $iX = BitAND($iPos, 0xFFFF)                     $iY = BitShift($iPos, 16)                     $tPt = DllStructCreate($tagPOINT)                     DllStructSetData($tPt, "X", $iX)                     DllStructSetData($tPt, "Y", $iY)                     _WinAPI_ScreenToClient($hTree, $tPt)                     $iX = DllStructGetData($tPt, "X")                     $iY = DllStructGetData($tPt, "Y")                     $tTVHTInfo = _GUICtrlTreeView_HitTestEx($hTree, $iX, $iY)                     If DllStructGetData($tTVHTInfo, "Flags") = $TVHT_ONITEMSTATEICON Then                         $hItem = DllStructGetData($tTVHTInfo, "Item")                         $fWasChecked = _GUICtrlTreeView_GetChecked($hTree, $hItem)                         If $fWasChecked Then                             _GUICtrlTreeView_BeginUpdate($hTree)                             _Uncheck($hItem)                             _GUICtrlTreeView_EndUpdate($hTree)                         Else                             _GUICtrlTreeView_BeginUpdate($hTree)                             _CallItemFunc($hItem)                             _Check($hItem)                             _GUICtrlTreeView_EndUpdate($hTree)                         EndIf                     EndIf             EndSwitch     EndSwitch     Return $GUI_RUNDEFMSG EndFunc Func _Uncheck($hItem)     Local $hParent, $hItemCur, $iLevel     $iLevel = _GUICtrlTreeView_Level($hTree, $hItem)     $hItemCur = _GUICtrlTreeView_GetFirstChild($hTree, $hItem)     While $hItemCur And _GUICtrlTreeView_Level($hTree, $hItemCur) > $iLevel         _GUICtrlTreeView_SetChecked($hTree, $hItemCur, False)         $hItemCur = _GUICtrlTreeView_GetNext($hTree, $hItemCur)     WEnd     $hParent = _GUICtrlTreeView_GetParentHandle($hTree, $hItem)     If $hParent Then         While $hParent             If $hParent <> $hItem Then _GUICtrlTreeView_SetChecked($hTree, $hParent, False)             $hParent = _GUICtrlTreeView_GetParentHandle($hTree, $hParent)         WEnd     EndIf EndFunc Func _Check($hItem)     Local $hParent, $hItemCur, $iLevel     $iLevel = _GUICtrlTreeView_Level($hTree, $hItem)     $hItemCur = _GUICtrlTreeView_GetFirstChild($hTree, $hItem)     While $hItemCur And _GUICtrlTreeView_Level($hTree, $hItemCur) > $iLevel         _GUICtrlTreeView_SetChecked($hTree, $hItemCur)         _CallItemFunc($hItemCur)         $hItemCur = _GUICtrlTreeView_GetNext($hTree, $hItemCur)     WEnd     $hParent = _GUICtrlTreeView_GetParentHandle($hTree, $hItem)     While $hParent         $hItemCur = _GUICtrlTreeView_GetFirstChild($hTree, $hParent)         While $hItemCur             If Not _GUICtrlTreeView_GetChecked($hTree, $hItemCur) And $hItemCur <> $hItem Then ExitLoop 2             $hItemCur = _GUICtrlTreeView_GetNextSibling($hTree, $hItemCur)         WEnd         _GUICtrlTreeView_SetChecked($hTree, $hParent)         _CallItemFunc($hParent)         $hParent = _GUICtrlTreeView_GetParentHandle($hTree, $hParent)     WEnd EndFunc Func _WinAPI_GetMessagePos()     Local $aResult = DllCall("user32.dll", "uint", "GetMessagePos")     If @error Then Return SetError(@error, @extended, 0)     Return $aResult[0] EndFunc Func _CallItemFunc($hItem)     For $i = 1 To $hItems[0][0]         If $hItem = $hItems[$i][0] Then             Call($hItems[$i][1])             ExitLoop         EndIf     Next EndFunc








#2 LarsJ

LarsJ

    Adventurer

  • Active Members
  • PipPip
  • 143 posts

Posted 23 April 2012 - 07:41 AM

Hi fcgnewbie,

If you can assume that checking an item means that all the items in the entire subbranch is checked (and it seems as if that is what you do) then I think this will do it.

Plain Text         
#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <TreeViewConstants.au3> #include <GuiTreeView.au3> #include <ButtonConstants.au3> #include <Array.au3> Local $hGUI, $Tree, $hTree, $hItems[40][2] = [[0]] $Form1_1 = GUICreate("Form1", 616, 532, 192, 124) $string = StringSplit("parent1,child1,child2,child3,sibling1,parent2,child1,child2,child3,sibling1",",") $button1 = GUICtrlCreateButton("Select", 40, 200, 100, 50) $List1 = GUICtrlCreateTreeView(40, 260, 530, 200, BitOR($GUI_SS_DEFAULT_TREEVIEW,$TVS_EDITLABELS,$TVS_CHECKBOXES), $WS_EX_CLIENTEDGE) GUISetState(@SW_SHOW) $hTree = GUICtrlGetHandle($List1) $hImage = _GUIImageList_Create(16, 16, 5, 3)     _GUIImageList_AddIcon($hImage, "shell32.dll", 8)     _GUIImageList_AddIcon($hImage, "shell32.dll", 166)     _GUICtrlTreeView_SetNormalImageList($List1, $hImage) _GUICtrlTreeView_BeginUpdate($List1) For $x = 0 To ubound($string) - 1 if StringInStr($string[$x],"parent",0) > 0 Then $tree_disk = _GUICtrlTreeView_Add($List1, 0, $string[$x], 0) EndIf if StringInStr($string[$x],"child",0) > 0 Then $tree_Part =  _GUICtrlTreeView_AddChild($List1, $tree_disk,$string[$x], 1,1) EndIf if StringInStr($string[$x],"sibling",0) > 0 Then     $tree_logical =  _GUICtrlTreeView_AddChild($List1,$tree_Part, $string[$x], 1, 1) EndIf Next    _GUICtrlTreeView_EndUpdate($List1) GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") While 1     $nMsg = GUIGetMsg()     Switch $nMsg         Case $GUI_EVENT_CLOSE             Exit         Case $button1       _ArrayDisplay( GetChecked(), "Checked items" )             ;MsgBox(0,"",_GUICtrlTreeView_GetCount($hTree))     EndSwitch WEnd Func GetChecked() Local $item, $aArray[100], $iArray = 0 $item = _GUICtrlTreeView_GetFirstItem( $hTree ) While $item   If _GUICtrlTreeView_GetChecked( $hTree, $item ) Then    $aArray[$iArray] = "Checked: " & GetPath( $hTree, $item )    $iArray += 1    $item = GetNextItem( $hTree, $item )    If $item Then     $aArray[$iArray] = "Next to test: " & GetPath( $hTree, $item )     $iArray += 1    Else     $aArray[$iArray] = "No more items to test"     $iArray += 1    EndIf   Else    $item = _GUICtrlTreeView_GetNext( $hTree, $item )   EndIf WEnd If $iArray = 0 then   $aArray[$iArray] = "No items checked"   $iArray += 1 EndIf ReDim $aArray[$iArray] Return $aArray EndFunc Func GetPath( $hTV, $item ) Local $path = _GUICtrlTreeView_GetText( $hTV, $item ) Local $parent = _GUICtrlTreeView_GetParentHandle( $hTV, $item ) While $parent   $path = _GUICtrlTreeView_GetText( $hTV, $parent ) & "|" & $path   $parent = _GUICtrlTreeView_GetParentHandle( $hTV, $parent ) WEnd Return $path EndFunc Func GetNextItem( $hTV, $subBranch ) ; Find the first item outside this subbranch Local $item = $subBranch, $nextItem = _GUICtrlTreeView_GetNextChild( $hTV, $item ) While Not $nextItem   $item = _GUICtrlTreeView_GetParentHandle( $hTV, $item )  ; Parent item   If Not $item Then ExitLoop                ; No more items   $nextItem = _GUICtrlTreeView_GetNextChild( $hTV, $item ) ; Next item WEnd Return $nextItem EndFunc Func _WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)     Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR     Local $iPos, $iX, $iY, $tPt, $iHitTest, $fWasChecked     Local $hItem     $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)     $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))     $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")     $iCode = DllStructGetData($tNMHDR, "Code")     Switch $hWndFrom         Case $hTree             Switch $iCode                 Case $NM_CLICK                     $iPos = _WinAPI_GetMessagePos()                     $iX = BitAND($iPos, 0xFFFF)                     $iY = BitShift($iPos, 16)                     $tPt = DllStructCreate($tagPOINT)                     DllStructSetData($tPt, "X", $iX)                     DllStructSetData($tPt, "Y", $iY)                     _WinAPI_ScreenToClient($hTree, $tPt)                     $iX = DllStructGetData($tPt, "X")                     $iY = DllStructGetData($tPt, "Y")                     $tTVHTInfo = _GUICtrlTreeView_HitTestEx($hTree, $iX, $iY)                     If DllStructGetData($tTVHTInfo, "Flags") = $TVHT_ONITEMSTATEICON Then                         $hItem = DllStructGetData($tTVHTInfo, "Item")                         $fWasChecked = _GUICtrlTreeView_GetChecked($hTree, $hItem)                         If $fWasChecked Then                             _GUICtrlTreeView_BeginUpdate($hTree)                             _Uncheck($hItem)                             _GUICtrlTreeView_EndUpdate($hTree)                         Else                             _GUICtrlTreeView_BeginUpdate($hTree)                             _CallItemFunc($hItem)                             _Check($hItem)                             _GUICtrlTreeView_EndUpdate($hTree)                         EndIf                     EndIf             EndSwitch     EndSwitch     Return $GUI_RUNDEFMSG EndFunc Func _Uncheck($hItem)     Local $hParent, $hItemCur, $iLevel     $iLevel = _GUICtrlTreeView_Level($hTree, $hItem)     $hItemCur = _GUICtrlTreeView_GetFirstChild($hTree, $hItem)     While $hItemCur And _GUICtrlTreeView_Level($hTree, $hItemCur) > $iLevel         _GUICtrlTreeView_SetChecked($hTree, $hItemCur, False)         $hItemCur = _GUICtrlTreeView_GetNext($hTree, $hItemCur)     WEnd     $hParent = _GUICtrlTreeView_GetParentHandle($hTree, $hItem)     If $hParent Then         While $hParent             If $hParent <> $hItem Then _GUICtrlTreeView_SetChecked($hTree, $hParent, False)             $hParent = _GUICtrlTreeView_GetParentHandle($hTree, $hParent)         WEnd     EndIf EndFunc Func _Check($hItem)     Local $hParent, $hItemCur, $iLevel     $iLevel = _GUICtrlTreeView_Level($hTree, $hItem)     $hItemCur = _GUICtrlTreeView_GetFirstChild($hTree, $hItem)     While $hItemCur And _GUICtrlTreeView_Level($hTree, $hItemCur) > $iLevel         _GUICtrlTreeView_SetChecked($hTree, $hItemCur)         _CallItemFunc($hItemCur)         $hItemCur = _GUICtrlTreeView_GetNext($hTree, $hItemCur)     WEnd     $hParent = _GUICtrlTreeView_GetParentHandle($hTree, $hItem)     While $hParent         $hItemCur = _GUICtrlTreeView_GetFirstChild($hTree, $hParent)         While $hItemCur             If Not _GUICtrlTreeView_GetChecked($hTree, $hItemCur) And $hItemCur <> $hItem Then ExitLoop 2             $hItemCur = _GUICtrlTreeView_GetNextSibling($hTree, $hItemCur)         WEnd         _GUICtrlTreeView_SetChecked($hTree, $hParent)         _CallItemFunc($hParent)         $hParent = _GUICtrlTreeView_GetParentHandle($hTree, $hParent)     WEnd EndFunc Func _WinAPI_GetMessagePos()     Local $aResult = DllCall("user32.dll", "uint", "GetMessagePos")     If @error Then Return SetError(@error, @extended, 0)     Return $aResult[0] EndFunc Func _CallItemFunc($hItem)     For $i = 1 To $hItems[0][0]         If $hItem = $hItems[$i][0] Then             Call($hItems[$i][1])             ExitLoop         EndIf     Next EndFunc


Try to check/uncheck some of the items and click the button. Remember to delete the "Checked items" window before a new button click.

LarsJ

#3 fcgnewbie

fcgnewbie

    Seeker

  • Active Members
  • 11 posts

Posted 23 April 2012 - 03:36 PM

LarsJ,

Thank you for the response. I do get an error when running the updated code; See below. However, If I continue any way it returns exactly what I was looking for, Perfect thanks.

I:\Autoit\forum.au3(41,54) : ERROR: _ArrayDisplay() called with expression on Const ByRef-param(s)
_ArrayDisplay( GetChecked(), &quot;Checked items&quot; )

C:\Program Files (x86)\AutoIt3\Include\Array.au3(322,163) : REF: definition of _ArrayDisplay().
Func _ArrayDisplay(Const ByRef $avArray, $sTitle = &quot;Array: ListView Display&quot;, $iItemLimit = -1, $iTranspose = 0, $sSeparator = &quot;&quot;, $sReplace = &quot;|&quot;, $sHeader = &quot;&quot;)

fcgnewbie

Edited by fcgnewbie, 23 April 2012 - 03:39 PM.


#4 LarsJ

LarsJ

    Adventurer

  • Active Members
  • PipPip
  • 143 posts

Posted 23 April 2012 - 09:43 PM

I am using Notepad++ and not Scite so I'm not always seeing all these errors and warnings.

Just replace the line

_ArrayDisplay( GetChecked(), "Checked items" )

with these 2 lines

Local $aArray = GetChecked()
_ArrayDisplay( $aArray, "Checked items" )

and you will not get any errors.

#5 fcgnewbie

fcgnewbie

    Seeker

  • Active Members
  • 11 posts

Posted 23 April 2012 - 10:53 PM

LarsJ,

Thanks again for the quick reply. It works without any errors now.

I saw your post AutoItObject example: Enumerating and Browsing the Desktop http://www.autoitscript.com/forum/topic/...le-enumerating-and-browsing-th

and its an awesome piece of code. I have been looking for ability to have a treeview in a listview, so thanks for that. Now I need to piece it all together and to get what I ultimately want to end up with, Something like this.

Posted Image

Many thanks again.

fcgnewbie




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users