cvocvo Posted June 15, 2010 Share Posted June 15, 2010 I'm working with a checkbox tree and I'm having problems. When I check the Parent checkbox (drive c or drive d in this case) then it checks all of the boxes. When I uncheck the Parent checkbox then it unchecks all of the child boxes. So that works great. The problems lies in when I click a child checkbox. I want the child checkbox to only check that one, but it checks all of them including the parent. I also want when the parent is checked and all children are checked, if I click one of the children, I want it to uncheck the parent. Hopefully someone understand this checkbox tree stuff better than I do. Code Snippet: expandcollapse popupFunc ChooseFixes() $FormPassFail = GUICreate("Fix Drive: Options", 500, 350, 334, 140, $DS_MODALFRAME) Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES) Local $idTreeView = GUICtrlCreateTreeView(0, 0, 495, 200, $iStyle, $WS_EX_CLIENTEDGE) Global $hTreeView = GUICtrlGetHandle($idTreeView), $Bad _GUICtrlTreeView_BeginUpdate($hTreeView) $NextButtonChooseFix = GUICtrlCreateButton("Next", 376, 265, 105, 49, 0) GUICtrlSetOnEvent($NextButtonChooseFix, "NextButtonChooseFixClick") $Bad = 0 ;$OSVersion = "XP" ;$DState = "Bad" ;$EState = "Bad" ;$CState = "Good" If $DState = "Bad" Then Local $idParent1 = GUICtrlCreateTreeViewItem('Drive D', $idTreeView) GUICtrlSetOnEvent($idParent1, "DriveDAllClick") Local $hParent1 = GUICtrlGetHandle($idParent1) $idLevel2P1 = GUICtrlCreateTreeViewItem('Make Drive Letter D:\ Available for Use', $idParent1) GUICtrlSetOnEvent($idLevel2P1, "DriveDAvailClick") $idLevel3P1 = GUICtrlCreateTreeViewItem('Install RamDisk on Drive D', $idParent1) GUICtrlSetOnEvent($idLevel3P1, "DriveDRamdiskClick") If $OSVersion = "7" Then $idLevel4P1 = GUICtrlCreateTreeViewItem('Make New Partition from Another Drive [*If RamDisk is checked it will nullify this checkbox*]', $idParent1) GUICtrlSetOnEvent($idLevel4P1, "DriveDPartitionclick") EndIf _GUICtrlTreeView_SetState($hTreeView, $hParent1, $TVIS_EXPANDED) EndIf If $EState = "Bad" Then Local $idParent2 = GUICtrlCreateTreeViewItem('Drive E', $idTreeView) GUICtrlSetOnEvent($idParent2, "DriveEAll") Local $hParent2 = GUICtrlGetHandle($idParent2) $idLevel2P2 = GUICtrlCreateTreeViewItem('Make Drive Letter E:\ Available for Use', $idParent2) GUICtrlSetOnEvent($idLevel2P2, "DriveEAvailClick") If $OSVersion = "7" Then $idLevel3P2 = GUICtrlCreateTreeViewItem('Make New Partition from Another Drive' & @CRLF & '[*If RamDisk is checked it will nullify this checkbox*]', $idParent2) GUICtrlSetOnEvent($idLevel3P2, "DriveEPartitionclick") EndIf _GUICtrlTreeView_SetState($hTreeView, $hParent2, $TVIS_EXPANDED) EndIf If $OSVersion = "7" Then GUICtrlCreateLabel("If 'Make a New Partition from Another Drive' was selected above, select a drive to take space from.", 10, 210, 495, 20) If $CState = "Good" Then $radioC = GUICtrlCreateRadio("Drive C", 10, 225, 60, 20) GUICtrlSetOnEvent($radioC, "RadioCClick") $FreeCSpace = Round(DriveSpaceFree("C:\"), 0) $TotalCSpace = Round(DriveSpaceTotal("C:\"), 0) $PercentCFree = $FreeCSpace * 100 / $TotalCSpace $PercentCFree = Round($PercentCFree, 1) & "%)" GUICtrlCreateLabel("(" & $FreeCSpace & " of " & $TotalCSpace & "MB Free " & $PercentCFree, 75, 228, 350, 20) EndIf If $DState = "Good" Then $type = DriveGetType("D:\") If $type = "Fixed" Then $radioD = GUICtrlCreateRadio("Drive D", 10, 245, 120, 20) GUICtrlSetOnEvent($radioD, "RadioDClick") $FreeDSpace = Round(DriveSpaceFree("D:\"), 0) $TotalDSpace = Round(DriveSpaceTotal("D:\"), 0) $PercentDFree = $FreeDSpace * 100 / $TotalDSpace $PercentDFree = Round($PercentDFree, 1) & "%)" GUICtrlCreateLabel("(" & $FreeDSpace & " of " & $TotalDSpace & "MB Free " & $PercentDFree, 75, 248, 350, 20) EndIf EndIf If $EState = "Good" Then $radioE = GUICtrlCreateRadio("Drive E", 10, 265, 120, 20) GUICtrlSetOnEvent($radioE, "RadioEClick") $FreeESpace = Round(DriveSpaceFree("E:\"), 0) $TotalESpace = Round(DriveSpaceTotal("E:\"), 0) $PercentEFree = $FreeESpace * 100 / $TotalESpace $PercentEFree = Round($PercentEFree, 1) & "%)" GUICtrlCreateLabel("(" & $FreeESpace & " of " & $TotalESpace & "MB Free " & $PercentEFree, 75, 268, 350, 20) EndIf Else GUICtrlCreateLabel("You are using a Windows XP based operating system -- because of this we are unable to provide on-the-fly partition creation.", 10, 210, 350, 30) GUICtrlCreateLabel("We would suggest repartioning to specifications with a 3rd party utility or upgrade to a Windows 7/Vista based OS.",10,240,350,30) EndIf _GUICtrlTreeView_EndUpdate($hTreeView) GUISetOnEvent($GUI_EVENT_CLOSE, "TreeEvents") GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "TreeEvents") GUISetState() EndFunc ;;;;For All Drive D/E/Radio Buttons 1 is enabled and 0 is disabled #Region<----->Functions for RadioButtons/CheckBoxTree ;Global $DriveDAvail = 0, $DriveDRamdisk = 0, $DriveDPartition = 0, $DriveEAvail = 0, $DriveEPartition = 0, $RadioC = 0, $RadioD = 0, $RadioE = 0 Func DriveDAllClick() $DriveDAvail = 1 $DriveDRamdisk = 1 $DriveDPartition = 0 EndFunc Func DriveDAvailClick() $DriveDAvail = 1 EndFunc Func DriveDRamdiskClick() $DriveDRamdisk = 1 EndFunc Func DriveDPartitionclick() $DriveDPartition = 1 EndFunc Func DriveEAllClick() $DriveEAvail = 1 $DriveEPartition = 1 EndFunc Func DriveEAvailClick() $DriveEAvail = 1 EndFunc Func DriveEPartitionclick() $DriveEPartition = 1 EndFunc Func RadioCClick() $RadioC = 1 EndFunc Func RadioDClick() $RadioD = 1 EndFunc Func RadioEClick() $RadioE = 1 EndFunc Func NextButtonChooseFixClick() If $DriveDPartition = 1 Then If $RadioC = 1 Then FixChoices() ElseIf $RadioD = 1 Then FixChoices() ElseIf $RadioE = 1 Then FixChoices() Else MsgBox(0, "Error", "If you want to checkbox 'Make New Partition from Another Drive,' you must pick a drive below that to take space from.") EndIf ElseIf $DriveEPartition = 1 Then If $RadioC = 1 Then FixChoices() ElseIf $RadioD = 1 Then FixChoices() ElseIf $RadioE = 1 Then FixChoices() Else MsgBox(0, "Error", "If you want to checkbox 'Make New Partition from Another Drive,' you must pick a drive below that to take space from.") EndIf EndIf If $DriveDAvail = 1 Then FixChoices() ElseIf $DriveDRamdisk = 1 Then FixChoices() ElseIf $DriveDPartition = 1 Then FixChoices() ElseIf $DriveEAvail = 1 Then FixChoices() ElseIf $DriveEPartition = 1 Then FixChoices() Else $areyousure = MsgBox(4, "Are you sure?", "Are you sure you meant to not select any fixes and want to fix partitioning yourself?") If $areyousure = 6 Then Exit EndIf EndIf EndFunc #EndRegion<----->End Functions for RadioButtons/CheckBoxTree #Region <----->CHECKBOX TREE FUNCTIONALITY<-----> Func TreeEvents() Switch @GUI_CtrlId Case $GUI_EVENT_CLOSE _GUICtrlTreeView_Destroy($hTreeView) GUIDelete() Exit Case $GUI_EVENT_PRIMARYDOWN Local $tMPos = _WinAPI_GetMousePos(True, $hTreeView) Local $tHitTest = _GUICtrlTreeView_HitTestEx($hTreeView, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2)) Local $iFlags = DllStructGetData($tHitTest, "Flags") Select Case BitAND($iFlags, $TVHT_ONITEMSTATEICON) Local $hItem = _GUICtrlTreeView_HitTestItem($hTreeView, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2)) Local $fChecked = False If _GUICtrlTreeView_GetChecked($hTreeView, $hItem) Then $fChecked = True _TvCheckbox($hItem, $fChecked) EndSelect EndSwitch EndFunc ;==>TreeEvents Func _TvCheckbox($hTvItem, $fTvCheck) Local $hFirst, $hNext $hTvParent = _GUICtrlTreeView_GetParentHandle($hTreeView, $hTvItem) If $hTvParent = 0 Then $hTvParent = $hTvItem If $hTvParent Then _GUICtrlTreeView_SetChecked($hTreeView, $hTvParent, $fTvCheck) $hFirst = _GUICtrlTreeView_GetFirstChild($hTreeView, $hTvParent) If $hFirst Then $hNext = $hFirst While $hNext _GUICtrlTreeView_SetChecked($hTreeView, $hNext, $fTvCheck) If _GUICtrlTreeView_GetChildren($hTreeView, $hNext) Then _ _TvCheckbox(_GUICtrlTreeView_GetFirstChild($hTreeView, $hNext), $fTvCheck) $hNext = _GUICtrlTreeView_GetNextSibling($hTreeView, $hNext) WEnd EndIf EndFunc ;==>_TvCheckbox #EndRegion<----->END CHECKBOX TREE FUNCTIONALITY<-----> #EndRegion <----->End Choose Fixes<-----> Thanks Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted June 15, 2010 Moderators Share Posted June 15, 2010 cvocvo, Me again - seems we have met a lot today! I think this does what you want: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GuiTreeView.au3> #include <TreeViewConstants.au3> Global $fGeneralState = False, $fDisplayState = False, $fAllGeneralChecked = False, $fAllDisplayChecked = False Global $aGeneralChildren[3], $aDisplayChildren[2] $hGUI = GUICreate("Test", 500, 500) GUISetState() $hTreeView = _GUICtrlTreeView_Create($hGUI, 10, 10, 200, 150, BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES), $WS_EX_CLIENTEDGE) _GUICtrlTreeView_BeginUpdate($hTreeView) $hGeneralItem = _GUICtrlTreeView_Add($hTreeView, 0, "General") $aGeneralChildren[0] = _GUICtrlTreeView_AddChild($hTreeView, $hGeneralItem, "About") $aGeneralChildren[1] = _GUICtrlTreeView_AddChild($hTreeView, $hGeneralItem, "Computer") $aGeneralChildren[2] = _GUICtrlTreeView_AddChild($hTreeView, $hGeneralItem, "User") $hDisplayItem = _GUICtrlTreeView_Add($hTreeView, 0, "Display") $aDisplayChildren[0] = _GUICtrlTreeView_AddChild($hTreeView, $hDisplayItem, "Rsolution") $aDisplayChildren[1] = _GUICtrlTreeView_AddChild($hTreeView, $hDisplayItem, "Other") _GUICtrlTreeView_EndUpdate($hTreeView) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch ; If General root checked, check all children and vice versa If _GUICtrlTreeView_GetChecked($hTreeView, $hGeneralItem) = True And $fGeneralState = False Then $fGeneralState = True For $i = 0 To UBound($aGeneralChildren) - 1 _GUICtrlTreeView_SetChecked($hTreeView, $aGeneralChildren[$i], True) $fAllGeneralChecked = True Next ElseIf _GUICtrlTreeView_GetChecked($hTreeView, $hGeneralItem) = False And $fGeneralState = True Then $fGeneralState = False For $i = 0 To UBound($aGeneralChildren) - 1 _GUICtrlTreeView_SetChecked($hTreeView, $aGeneralChildren[$i], False) $fAllGeneralChecked = False Next EndIf ; Count number of General children checked $iCount = 0 For $i = 0 To UBound($aGeneralChildren) - 1 If _GUICtrlTreeView_GetChecked($hTreeView, $aGeneralChildren[$i]) = True Then $iCount += 1 Next ; If none checked - uncheck General root If $iCount = 0 And $fGeneralState = True Then _GUICtrlTreeView_SetChecked($hTreeView, $hGeneralItem, False) $fGeneralState = False ; If at least one checked - check General root if needed ElseIf $iCount > 0 And $fGeneralState = False Then _GUICtrlTreeView_SetChecked($hTreeView, $hGeneralItem, True) $fGeneralState = True EndIf ; If all children checked - set flag If $iCount = UBound($aGeneralChildren) Then $fAllGeneralChecked = True ; If flag was set and now not all are checked - uncheck General root and all children ElseIf $iCount = UBound($aGeneralChildren) - 1 Then If $fAllGeneralChecked = True Then $fGeneralState = False _GUICtrlTreeView_SetChecked($hTreeView, $hGeneralItem, False) $fAllGeneralChecked = True For $i = 0 To UBound($aGeneralChildren) - 1 _GUICtrlTreeView_SetChecked($hTreeView, $aGeneralChildren[$i], False) $fAllGeneralChecked = False Next EndIf EndIf ; Do the same for the Display root/branch If _GUICtrlTreeView_GetChecked($hTreeView, $hDisplayItem) = True And $fDisplayState = False Then $fDisplayState = True For $i = 0 To UBound($aDisplayChildren) - 1 _GUICtrlTreeView_SetChecked($hTreeView, $aDisplayChildren[$i], True) $fAllDisplayChecked = True Next ElseIf _GUICtrlTreeView_GetChecked($hTreeView, $hDisplayItem) = False And $fDisplayState = True Then $fDisplayState = False For $i = 0 To UBound($aDisplayChildren) - 1 _GUICtrlTreeView_SetChecked($hTreeView, $aDisplayChildren[$i], False) $fAllDisplayChecked = False Next EndIf $iCount = 0 For $i = 0 To UBound($aDisplayChildren) - 1 If _GUICtrlTreeView_GetChecked($hTreeView, $aDisplayChildren[$i]) = True Then $iCount += 1 Next If $iCount = 0 And $fDisplayState = True Then _GUICtrlTreeView_SetChecked($hTreeView, $hDisplayItem, False) $fDisplayState = False ElseIf $iCount > 0 And $fDisplayState = False Then _GUICtrlTreeView_SetChecked($hTreeView, $hDisplayItem, True) $fDisplayState = True EndIf If $iCount = UBound($aDisplayChildren) Then $fAllDisplayChecked = True ElseIf $iCount = UBound($aDisplayChildren) - 1 Then If $fAllDisplayChecked = True Then $fDisplayState = False _GUICtrlTreeView_SetChecked($hTreeView, $hDisplayItem, False) $fAllDisplayChecked = True For $i = 0 To UBound($aDisplayChildren) - 1 _GUICtrlTreeView_SetChecked($hTreeView, $aDisplayChildren[$i], False) $fAllDisplayChecked = False Next EndIf EndIf WEnd There must be an easier way - I will look again tomorrow after a night's sleep and a round of golf to clear the brain. M23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
cvocvo Posted June 15, 2010 Author Share Posted June 15, 2010 (edited) You are an autoit ninja -- that works well enough for what I'll be using it for. Now I just need to implement it. Thanks Edit: So, I've implemented it, but we have a problem. Because I'm putting all of this within a function, that While loop makes everything get stuck. Consequently, the rest of the window doesn't load and the button on my GUI window doesn't work because everything is stuck in a loop. For this reason I had everything working in a couple functions, but they aren't working like I want them to. The other thing I want is to make sure the checkbox tree opens expanded. Edited June 16, 2010 by cvocvo Link to comment Share on other sites More sharing options...
Authenticity Posted June 16, 2010 Share Posted June 16, 2010 expandcollapse popup#include <GUIConstantsEx.au3> #include <GUITreeView.au3> #include <WindowsConstants.au3> #include <Constants.au3> Local $hGUI, $hTree, $hItem, $hSubItem, $hSubZero $hGUI = GUICreate("Test", 220, 300) $hTree = _GUICtrlTreeView_Create($hGUI, 20, 20, 200, 260, BitOR($GUI_SS_DEFAULT_TREEVIEW, $TVS_CHECKBOXES)) GUISetState() _GUICtrlTreeView_BeginUpdate($hTree) For $x = 1 To 10 $hItem = _GUICtrlTreeView_Add($hTree, 0, StringFormat("[%02d] New Item", $x)) _GUICtrlTreeView_SetChecked($hTree, $hItem) For $y = 1 To 5 $hSubItem = _GUICtrlTreeView_AddChild($hTree, $hItem, StringFormat("[%02d] New Child", $y), 0) _GUICtrlTreeView_SetChecked($hTree, $hSubItem) For $z = 1 To 3 $hSubZero = _GUICtrlTreeView_AddChild($hTree, $hSubItem, StringFormat("[%02d] New Grandchild", $z), 0) _GUICtrlTreeView_SetChecked($hTree, $hSubZero) _GUICtrlTreeView_Expand($hTree, $hSubZero) Next Next Next _GUICtrlTreeView_EndUpdate($hTree) GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() 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) _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) $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) $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 Link to comment Share on other sites More sharing options...
cvocvo Posted June 16, 2010 Author Share Posted June 16, 2010 (edited) expandcollapse popup#include <GUIConstantsEx.au3> #include <GUITreeView.au3> #include <WindowsConstants.au3> #include <Constants.au3> Local $hGUI, $hTree, $hItem, $hSubItem, $hSubZero $hGUI = GUICreate("Test", 220, 300) $hTree = _GUICtrlTreeView_Create($hGUI, 20, 20, 200, 260, BitOR($GUI_SS_DEFAULT_TREEVIEW, $TVS_CHECKBOXES)) GUISetState() _GUICtrlTreeView_BeginUpdate($hTree) For $x = 1 To 10 $hItem = _GUICtrlTreeView_Add($hTree, 0, StringFormat("[%02d] New Item", $x)) _GUICtrlTreeView_SetChecked($hTree, $hItem) For $y = 1 To 5 $hSubItem = _GUICtrlTreeView_AddChild($hTree, $hItem, StringFormat("[%02d] New Child", $y), 0) _GUICtrlTreeView_SetChecked($hTree, $hSubItem) For $z = 1 To 3 $hSubZero = _GUICtrlTreeView_AddChild($hTree, $hSubItem, StringFormat("[%02d] New Grandchild", $z), 0) _GUICtrlTreeView_SetChecked($hTree, $hSubZero) _GUICtrlTreeView_Expand($hTree, $hSubZero) Next Next Next _GUICtrlTreeView_EndUpdate($hTree) GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() 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) _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) $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) $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 I'm afraid yours suffers similar downfalls as other implementations. The loop breaks my Next button because I am putting all of this inside a function. I am also unsure how I would implement differently named parents with different variables (like I did in my original post) so that I can map each checkbox to a variable. --> You just have a loop that creates each new item, where as I need to conditionally populate two different parents each with a different variable and then conditionally populate different children with different variables. What yours does do though is have a reliable, working implementation of a properly functioning checkbox tree. Edit: Upon further tweaking, I am able to get your implementation to work with the Next button by commenting out: ;Do ;Until GUIGetMsg() = $GUI_EVENT_CLOSE ;GUIDelete() (Not really sure if that's necessary) That just leaves the question how would I be able conditionally populate two different parents each with a different variable and then conditionally populate different children with different variables? Edited June 16, 2010 by cvocvo Link to comment Share on other sites More sharing options...
Authenticity Posted June 16, 2010 Share Posted June 16, 2010 Examples should be demonstrative. I've never seen a real world code example in MSDN site that does anything else other then explaining how to achieve or implement the subject in hand. You can build the tree using loops with arrays, or fill in the tree items one by one; whatever suites your case. Link to comment Share on other sites More sharing options...
cvocvo Posted June 16, 2010 Author Share Posted June 16, 2010 Let me restructure my question/concern a little bit with a simple example. Currently we have something that looks like this: $hItem = _GUICtrlTreeView_Add($hTree, 0, StringFormat("[%02d] New Item", $x)) _GUICtrlTreeView_SetChecked($hTree, $hItem) For $y = 1 To 5 $hSubItem = _GUICtrlTreeView_AddChild($hTree, $hItem, StringFormat("[%02d] New Child", $y), 0) _GUICtrlTreeView_SetChecked($hTree, $hSubItem) For $z = 1 To 3 $hSubZero = _GUICtrlTreeView_AddChild($hTree, $hSubItem, StringFormat("[%02d] New Grandchild", $z), 0) _GUICtrlTreeView_SetChecked($hTree, $hSubZero) _GUICtrlTreeView_Expand($hTree, $hSubZero) As you can see $hItem, $hSubItem, and $hSubZero are the variables being set for each of the checkbox tree items. I can't go in and change $hItem to $hItem1 and $hItem2 because the functions aren't looking for those, they're only interested in $hItem. So if I can't change those, how would I go about getting a value from each checked checkbox. Or stated differently, I want to set a variable equal to each box that gets checked, as it gets checked or unchecked. Link to comment Share on other sites More sharing options...
Authenticity Posted June 16, 2010 Share Posted June 16, 2010 expandcollapse popup#include <GUIConstantsEx.au3> #include <GUITreeView.au3> #include <WindowsConstants.au3> #include <Constants.au3> Opt("GUIOnEventMode", 1) Local $hGUI, $Tree, $hTree, $hItems[40][2] = [[0]] ; [hItem, Function] Local $DriveDAvail, $DriveDRamdisk, $DriveDPartition, $DriveEAvail, $DriveEPartition Local $Bad, $OSVersion, $CState, $DState, $EState Local $idParent1, $idLevel2P1, $idLevel3P1, $idLevel4P1, $idParent2, $idLevel2P2, $idLevel3P2 $hGUI = GUICreate("Test", 400, 400) GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit") $Tree = GUICtrlCreateTreeView(20, 20, 360, 360, BitOR($GUI_SS_DEFAULT_TREEVIEW, $TVS_CHECKBOXES)) $hTree = GUICtrlGetHandle($Tree) $Bad = 0 $OSVersion = "XP" $CState = "Good" $DState = "Bad" $EState = "Bad" _GUICtrlTreeView_BeginUpdate($hTree) If $DState = "Bad" Then $idParent1 = GUICtrlCreateTreeViewItem('Drive D', $Tree) $hItems[0][0] += 1 $hItems[$hItems[0][0]][0] = GUICtrlGetHandle($idParent1) $hItems[$hItems[0][0]][1] = "DriveDAllClick" $idLevel2P1 = GUICtrlCreateTreeViewItem('Make Drive Letter D:\ Available for Use', $idParent1) $hItems[0][0] += 1 $hItems[$hItems[0][0]][0] = GUICtrlGetHandle($idLevel2P1) $hItems[$hItems[0][0]][1] = "DriveDAvailClick" $idLevel3P1 = GUICtrlCreateTreeViewItem('Install RamDisk on Drive D', $idParent1) $hItems[0][0] += 1 $hItems[$hItems[0][0]][0] = GUICtrlGetHandle($idLevel3P1) $hItems[$hItems[0][0]][1] = "DriveDRamdiskClick" If $OSVersion = "7" Then $idLevel4P1 = GUICtrlCreateTreeViewItem('Make New Partition from Another Drive [*If RamDisk is checked it will nullify this checkbox*]', $idParent1) $hItems[0][0] += 1 $hItems[$hItems[0][0]][0] = GUICtrlGetHandle($idLevel4P1) $hItems[$hItems[0][0]][1] = "DriveDPartitionclick" EndIf _GUICtrlTreeView_Expand($hTree, GUICtrlGetHandle($idParent1)) EndIf If $EState = "Bad" Then $idParent2 = GUICtrlCreateTreeViewItem('Drive E', $Tree) $hItems[0][0] += 1 $hItems[$hItems[0][0]][0] = GUICtrlGetHandle($idParent2) $hItems[$hItems[0][0]][1] = "DriveEAllClick" $idLevel2P2 = GUICtrlCreateTreeViewItem('Make Drive Letter E:\ Available for Use', $idParent2) $hItems[0][0] += 1 $hItems[$hItems[0][0]][0] = GUICtrlGetHandle($idLevel2P2) $hItems[$hItems[0][0]][1] = "DriveEAvailClick" If $OSVersion = "7" Then $idLevel3P2 = GUICtrlCreateTreeViewItem('Make New Partition from Another Drive' & @CRLF & '[*If RamDisk is checked it will nullify this checkbox*]', $idParent2) $hItems[0][0] += 1 $hItems[$hItems[0][0]][0] = GUICtrlGetHandle($idLevel3P2) $hItems[$hItems[0][0]][1] = "DriveEPartitionclick" EndIf _GUICtrlTreeView_Expand($hTree, GUICtrlGetHandle($idParent2)) EndIf _GUICtrlTreeView_EndUpdate($hTree) ReDim $hItems[$hItems[0][0]+1][2] GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY") GUISetState() While 1 Sleep(20) WEnd Func _Quit() ConsoleWrite(StringFormat("%d %d %d %d %d\n", $DriveDAvail, $DriveDRamdisk, $DriveDPartition, $DriveEAvail, $DriveEPartition)) Exit EndFunc Func DriveDAllClick() $DriveDAvail = 1 $DriveDRamdisk = 1 $DriveDPartition = 0 EndFunc Func DriveDAvailClick() $DriveDAvail = 1 EndFunc Func DriveDRamdiskClick() $DriveDRamdisk = 1 EndFunc Func DriveDPartitionclick() $DriveDPartition = 1 EndFunc Func DriveEAllClick() $DriveEAvail = 1 $DriveEPartition = 1 EndFunc Func DriveEAvailClick() $DriveEAvail = 1 EndFunc Func DriveEPartitionclick() $DriveEPartition = 1 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 You need to implement the uncheck function calls. As it's now, once $DriveDPartition, etc.. is set, nothing updates the variable back to uncheck. Link to comment Share on other sites More sharing options...
cvocvo Posted June 16, 2010 Author Share Posted June 16, 2010 Ah, gotcha. Well, thank you -- that seems to be just what I need. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now