- Offizieller Beitrag
Hier ein paar zusätzliche Funktionen für Treeviews:
_GUICtrlTreeView_ExpandOneLevel
(Hatte ich bereits mal gepostet, jetzt nochmal überarbeitet)
- Ein/Ausklappen nur eines Levels unterhalb eines Item
_GUICtrlTreeView_CheckBoxAsRadio
- Alle Checkboxen in einem Treeview werden wie Radio-Ctrl behandelt
- Es kann immer nur eine Checkbox aktiv sein. Wird eine andere Checkbox aktiviert, wird automatisch die zuletzt gecheckte deaktiviert.
- Zeitgleich für verschiedene Treeview im Skript einsetzbar
_GUICtrlTreeView_CheckBoxAsRadioInLevel
- Checkboxen eines Levels in einem Treeview werden wie Radio-Ctrl behandelt
- Es kann immer nur eine Checkbox eines Item-Levels aktiv sein. Wird eine andere Checkbox aktiviert, wird automatisch die zuletzt gecheckte deaktiviert.
- Zeitgleich für verschiedene Treeview im Skript einsetzbar
_GUICtrlTreeView_GetCheckedInSelectionLevel
- Ermittelt alle Item-Handle mit aktivierter Checkbox im Level des aktuell selektierten Item
- Optional kann zu den Item-Handle auch gleich der Text ermittelt werden.
Die Funktionen zum Verwenden der Checkboxen als Radio müssen jeweils aufgerufen werden, wenn eine Aktion stattfindet, die eine Checkbox De/aktivieren könnte. Also bei Mausklick und Leertaste. Im Bsp. habe ich das auf den Mausklick beschränkt.
Vereinzelt kann es Auftreten, dass bei schnellem Klicken hintereinander das De/aktivieren fehlschlägt. Mal sehen, ob sich das noch zu 100 % ausschließen läßt.
Noch etwas zu den Radiofunktionen:
Gerade umfangreiche Installationen oder Einstellungsoberflächen lassen sich damit wesentlich vereinfachen. Ein Treeview ist effektiver im Platzverbrauch als die Verwendung von Groups, Radios und Checkboxen auf einer GUI und bei vielen Elementen auch übersichtlicher.
TreeViewEx.au3 (v0.1)
#Region - TimeStamp
; 2012-06-13 11:35:34 v 0.1
#EndRegion - TimeStamp
#include-once
#Include <GuiTreeView.au3>
Global Const $__MAX_COUNT_TREEVIEWCTRL = 100
[/autoit] [autoit][/autoit] [autoit];===============================================================================
; Function Name....: _GUICtrlTreeView_CheckBoxAsRadio
; Description......: Checkboxen in einem Treeview werden wie Radio-Ctrl behandelt
; .................: Es kann immer nur eine Checkbox aktiv sein. Wird eine andere Checkbox aktiviert,
; .................: wird automatisch die zuletzt gecheckte deaktiviert.
; .................: Zeitgleich für verschiedene Treeview im Skript einsetzbar
; Parameter(s).....: $_hWnd Das Handle des Treeviews
; .................: $_fFocus Wenn TRUE (Standard) wird Funktion nur ausgeführt bei Fokus auf dem Treeview
; Requirement(s)...: Treeview mit Style: $TVS_CHECKBOXES
; Return Value(s)..: Erfolg Handle des momentan selektierten Item (unabhängig ob gecheckt oder nicht)
; .................: Fehler 0 @error=1 Treeview hat nicht den Fokus
; Note.............: Die Funktion sollte sinnvollerweise immer initialisiert werden, wenn ein Event stattfindet,
; .................: das ein de/aktivieren der Checkboxen zur Folge haben könnte (Mausklick oder Leertaste)
; Author(s)........: BugFix ( [email='bugfix@autoit.de'][/email] )
;===============================================================================
Func _GUICtrlTreeView_CheckBoxAsRadio($_hWnd, $_fFocus=True)
If Not IsHWnd($_hWnd) Then $_hWnd = GUICtrlGetHandle($_hWnd)
If $_fFocus Then
Local $hCtrl = DllCall("user32.dll", "hwnd", "GetFocus")
If $hCtrl[0] <> $_hWnd Then Return SetError(1,0,0)
EndIf
Local Static $a_hWnd[$__MAX_COUNT_TREEVIEWCTRL][2] = [[0]] ; == [[hWnd,hLastCheck]]
Local $index_hWnd = 0, $hLastCheck = 0, $fFound = False
If $a_hWnd[0][0] = 0 Then ; == erstmaliger Aufruf der Funktion
$a_hWnd[0][0] = $_hWnd
Else ; == weitere Aufrufe
For $i = 0 To $__MAX_COUNT_TREEVIEWCTRL -1
If $a_hWnd[$i][0] = $_hWnd Then ; == für dieses Treeview erfolgte bereits ein Aufruf
$index_hWnd = $i
$hLastCheck = $a_hWnd[$i][1]
$fFound = True
ExitLoop
ElseIf $a_hWnd[$i][0] = '' Then
ExitLoop
EndIf
Next
If Not $fFound Then ; == für dieses Treeview erstmaliger Aufruf
$index_hWnd = $i
$a_hWnd[$index_hWnd][0] = $_hWnd
EndIf
EndIf
Local $aCheck = _GUICtrlTreeView_GetCheckedInSelectionLevel($_hWnd)
If $aCheck[0] = $hLastCheck Then ; == selektiertes Item war gecheckt
$a_hWnd[$index_hWnd][1] = 0
Else
_GUICtrlTreeView_SetChecked($_hWnd, $hLastCheck, False)
_GUICtrlTreeView_SetChecked($_hWnd, $aCheck[0], True)
$a_hWnd[$index_hWnd][1] = $aCheck[0]
EndIf
Return $aCheck[0]
EndFunc ;==>_GUICtrlTreeView_CheckBoxAsRadio
;===============================================================================
; Function Name....: _GUICtrlTreeView_CheckBoxAsRadioInLevel
; Description......: Checkboxen eines Levels in einem Treeview werden wie Radio-Ctrl behandelt
; .................: Es kann immer nur eine Checkbox eines Item-Levels aktiv sein. Wird eine andere Checkbox aktiviert,
; .................: wird automatisch die zuletzt gecheckte deaktiviert.
; .................: Zeitgleich für verschiedene Treeview im Skript einsetzbar
; Parameter(s).....: $_hWnd Das Handle des Treeviews
; .................: $_hLevelOnly Erstes Handle des Levels, für dessen Siblings ausschließlich die Funktion wirksam wird
; .................: $_fFocus Wenn TRUE (Standard) wird Funktion nur ausgeführt bei Fokus auf dem Treeview
; Requirement(s)...: Treeview mit Style: $TVS_CHECKBOXES
; Return Value(s)..: Erfolg Handle des momentan selektierten Item (unabhängig ob gecheckt oder nicht)
; .................: Fehler 0 @error=1 Treeview hat nicht den Fokus
; Note.............: Die Funktion sollte sinnvollerweise immer initialisiert werden, wenn ein Event stattfindet,
; .................: das ein De/aktivieren der Checkboxen zur Folge haben könnte (Mausklick oder Leertaste)
; Author(s)........: BugFix ( [email='bugfix@autoit.de'][/email] )
;===============================================================================
Func _GUICtrlTreeView_CheckBoxAsRadioInLevel($_hWnd, $_hLevelOnly=-1, $_fFocus=True)
If Not IsHWnd($_hWnd) Then $_hWnd = GUICtrlGetHandle($_hWnd)
If $_fFocus Then
Local $hCtrl = DllCall("user32.dll", "hwnd", "GetFocus")
If $hCtrl[0] <> $_hWnd Then Return SetError(1,0,0)
EndIf
Local Static $a_hWnd[$__MAX_COUNT_TREEVIEWCTRL][3] = [[0]] ; == [[hWnd,hParent,hLastCheck]]
Local $index_hWnd = 0, $hLastCheck = -1, $fFound = False, $hSel, $hParent, $hFirst, $aLvlOnly[1]
$hSel = _GUICtrlTreeView_GetSelection($_hWnd)
$hParent = _GUICtrlTreeView_GetParentHandle($_hWnd, $hSel)
If Not $hParent Then
$hParent = 'root'
$hFirst = _GUICtrlTreeView_GetFirstItem($_hWnd)
Else
$hFirst = _GUICtrlTreeView_GetFirstChild($_hWnd, $hParent)
EndIf
If $_hLevelOnly <> -1 Then
If Not IsArray($_hLevelOnly) Then
$aLvlOnly[0] = $_hLevelOnly
Else
$aLvlOnly = $_hLevelOnly
EndIf
For $i = 0 To UBound($aLvlOnly) -1
If $aLvlOnly[$i] = $hFirst Then Return
Next
EndIf
If $a_hWnd[0][0] = 0 Then ; == erstmaliger Aufruf der Funktion
$a_hWnd[0][0] = $_hWnd ; == TV-Handle
$a_hWnd[0][1] = $hParent ; == Parent-Handle ('root' bei Root)
Else ; == weitere Aufrufe
For $i = 0 To $__MAX_COUNT_TREEVIEWCTRL -1
If ($a_hWnd[$i][0] = $_hWnd And $a_hWnd[$i][1] = $hParent) Then ; == für dieses Treeview erfolgte bereits ein Aufruf
$index_hWnd = $i
$hLastCheck = $a_hWnd[$i][2]
$fFound = True
ExitLoop
ElseIf $a_hWnd[$i][0] = '' Then
ExitLoop
EndIf
Next
If Not $fFound Then ; == für dieses Treeview erstmaliger Aufruf
$index_hWnd = $i
$a_hWnd[$index_hWnd][0] = $_hWnd
$a_hWnd[$index_hWnd][1] = $hParent
EndIf
EndIf
Local $aCheck = _GUICtrlTreeView_GetCheckedInSelectionLevel($_hWnd)
If $aCheck[0] = $hLastCheck Then ; == selektiertes Item war gecheckt
$a_hWnd[$index_hWnd][2] = 0
Else
_GUICtrlTreeView_SetChecked($_hWnd, $hLastCheck, False)
_GUICtrlTreeView_SetChecked($_hWnd, $aCheck[0], True)
$a_hWnd[$index_hWnd][2] = $aCheck[0]
EndIf
Return $aCheck[0]
EndFunc ;==>_GUICtrlTreeView_CheckBoxAsRadioInLevel
;===============================================================================
; Function Name....: _GUICtrlTreeView_GetCheckedInSelectionLevel
; Description......: Ermittelt alle Item-Handle mit aktivierter Checkbox im Level des aktuell selektierten Item
; .................: Optional kann zu den Item-Handle auch gleich der Text ermittelt werden.
; Parameter(s).....: $_hWnd Das Handle des Treeviews
; ........optional.: $_fText FALSE (Standard) - nur Rückgabe der Handle; mit TRUE wird Array als 2D mit [[hWnd-Item, Text-Item]] zurückgegeben
; Requirement(s)...: Treeview mit Style: $TVS_CHECKBOXES
; Return Value(s)..: Array Pos[0] - Handle des aktuell selektierten Item (auch wenn Checkbox inaktiv!)
; .................: Pos[n..ff] - Handle aller Item mit aktiver Checkbox (also auch das aktuell selektierte nochmals, wenn gecheckt)
; .................: opt. 2D-Array mit Text des Item an [n][1]
; Author(s)........: BugFix ( [email='bugfix@autoit.de'][/email] )
;===============================================================================
Func _GUICtrlTreeView_GetCheckedInSelectionLevel($_hWnd, $_fText=False)
If Not IsHWnd($_hWnd) Then $_hWnd = GUICtrlGetHandle($_hWnd)
Local $hSel = _GUICtrlTreeView_GetSelection($_hWnd)
Local $aRet[1] = [$hSel], $hFirst, $hNext, $hParent
If $_fText Then
ReDim $aRet[1][2]
$aRet[0][0] = $hSel
$aRet[0][1] = _GUICtrlTreeView_GetText($_hWnd, $hSel)
EndIf
; == erstes Item dieses Levels suchen
$hParent = _GUICtrlTreeView_GetParentHandle($_hWnd, $hSel)
If $hParent Then
$hFirst = _GUICtrlTreeView_GetFirstChild($_hWnd, $hParent)
Else
$hFirst = _GUICtrlTreeView_GetFirstItem($_hWnd)
EndIf
; == erstes Item auf gecheckt prüfen
If _GUICtrlTreeView_GetChecked($_hWnd, $hFirst) Then
If $_fText Then
ReDim $aRet[UBound($aRet)+1][2]
$aRet[UBound($aRet)-1][0] = $hFirst
$aRet[UBound($aRet)-1][1] = _GUICtrlTreeView_GetText($_hWnd, $hFirst)
Else
ReDim $aRet[UBound($aRet)+1]
$aRet[UBound($aRet)-1] = $hFirst
EndIf
EndIf
; == restliche Item des Levels auf gecheckt prüfen
$hNext = $hFirst
While True
$hNext = _GUICtrlTreeView_GetNextSibling($_hWnd, $hNext)
If Not $hNext Then ExitLoop
If _GUICtrlTreeView_GetChecked($_hWnd, $hNext) Then
If $_fText Then
ReDim $aRet[UBound($aRet)+1][2]
$aRet[UBound($aRet)-1][0] = $hNext
$aRet[UBound($aRet)-1][1] = _GUICtrlTreeView_GetText($_hWnd, $hNext)
Else
ReDim $aRet[UBound($aRet)+1]
$aRet[UBound($aRet)-1] = $hNext
EndIf
EndIf
WEnd
Return $aRet
EndFunc ;==>_GUICtrlTreeView_GetCheckedInSelectionLevel
;==================================================================================================
; Function Name: _GUICtrlTreeView_ExpandOneLevel
; Description..: Aus/Einklappen nur EINER Ebene eines Items, analog zum Mausklick auf '+/-'
; Parameter(s).: $_hWnd Handle des TreeView
; .............: $_hParent Handle des Item, dessen Childs aus/einzuklappen sind
; .............: Standard 0 ==> Handle des ersten Item im TreeView
; .............: $_fExpand Standard TRUE ==> Ausklappen, Einklappen mit FALSE
; Return.......: Erfolg Handle des Item, dessen Childs aus/eingeklappt wurden
; .............: Fehler 0 @error 1 - TreeView enthält kein Item
; .............: @error 2 - Item hat keine Child-Item
; Note.........: Die Funktion sollte zwischen _GUICtrlTreeView_BeginUpdate() und _GUICtrlTreeView_EndUpdate()
; .............: ausgeführt werden um ein Flackern zu verhindern
; Author(s)....: BugFix ([email='bugfix@autoit.de'][/email])
;==================================================================================================
Func _GUICtrlTreeView_ExpandOneLevel($_hWnd, $_hParent=0, $_fExpand=True)
If Not IsHWnd($_hWnd) Then $_hWnd = GUICtrlGetHandle($_hWnd)
If $_hParent = 0 Then $_hParent = _GUICtrlTreeView_GetFirstItem($_hWnd)
If $_hParent = 0 Then Return SetError(1,0,0)
Local $hChild, $countChild = _GUICtrlTreeView_GetChildCount($_hWnd, $_hParent)
If $countChild = 0 Then Return SetError(2,0,0)
_GUICtrlTreeView_Expand($_hWnd, $_hParent, $_fExpand)
If Not $_fExpand Then Return $_hParent
For $i = 1 To $countChild
If $i = 1 Then
$hChild = _GUICtrlTreeView_GetFirstChild($_hWnd, $_hParent)
Else
$hChild = _GUICtrlTreeView_GetNextSibling($_hWnd, $hChild)
EndIf
If _GUICtrlTreeView_GetChildren($_hWnd, $hChild) Then _GUICtrlTreeView_Expand($_hWnd, $hChild, False)
Next
Return $_hParent
EndFunc ;==>_GUICtrlTreeView_ExpandOneLevel
Beispiel
#Region - TimeStamp
; 2012-06-13 11:54:52
#EndRegion - TimeStamp
#include <Array.au3>
#Include <GUIConstantsEx.au3>
#Include <WindowsConstants.au3>
#include 'TreeViewEx.au3'
Opt('MustDeclareVars', 1)
_Main_1()
_Main_2()
Exit
Func _Main_1()
Local $aChecked, $aNormalCheck[2], $hGui, $nTV1, $nTV2, $nTV3, $hItem
$hGui = GUICreate('Treeview - Alle Checkbox als Radio', 885, 430)
$nTV1 = GUICtrlCreateTreeView(15, 15, 275, 370, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES), $WS_EX_CLIENTEDGE)
GUICtrlCreateLabel('In Root und Childs von SubItem_1_2 normal, andere SubLevel als Radio', 15, 395, 275, 24)
$nTV2 = GUICtrlCreateTreeView(305, 15, 275, 370, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES), $WS_EX_CLIENTEDGE)
GUICtrlCreateLabel('Checkboxen im Root und SubLeveln als Radio, je Level nur eine Checkbox aktivierbar', 305, 395, 275, 24)
$nTV3 = GUICtrlCreateTreeView(595, 15, 275, 370, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES), $WS_EX_CLIENTEDGE)
GUICtrlCreateLabel('Checkboxen im ges. Treeview als eine Radio-Group, nur eine einzige Checkbox aktivierbar', 595, 395, 275, 24)
_AddItem($nTV1, 3, 1)
_AddItem($nTV2)
_AddItem($nTV3)
$hItem = _GUICtrlTreeView_ExpandOneLevel($nTV1) ; == erstes Root-Item ein Level ausklappen
; == 2.tes Child von erstem Root-Item und dessen 1.tes Child ein Level ausklappen
_GUICtrlTreeView_Expand($nTV1, _GUICtrlTreeView_GetItemByIndex($nTV1, _GUICtrlTreeView_ExpandOneLevel($nTV1, _GUICtrlTreeView_GetItemByIndex($nTV1, $hItem, 1)), 0))
For $i = 1 To 2 ; == restliche Root-Item ein Level ausklappen
$hItem = _GUICtrlTreeView_GetNextSibling($nTV1, $hItem)
_GUICtrlTreeView_ExpandOneLevel($nTV1, $hItem)
Next
; == alle Item der anderen Treeview ausklappen
_GUICtrlTreeView_Expand($nTV2)
_GUICtrlTreeView_Expand($nTV3)
GUISetState()
[/autoit] [autoit][/autoit] [autoit]While True
Switch GUIGetMsg()
Case -3
ExitLoop
Case $GUI_EVENT_PRIMARYUP
$aNormalCheck[0] = _GUICtrlTreeView_GetFirstItem($nTV1) ; == Root
$aNormalCheck[1] = _GUICtrlTreeView_GetItemByIndex($nTV1, _GUICtrlTreeView_GetItemByIndex($nTV1, $aNormalCheck[0], 1), 0) ; == unterhalb SubItem_1_2
_GUICtrlTreeView_CheckBoxAsRadioInLevel($nTV1, $aNormalCheck) ; == Root u. Childs von SubItem_1_2 Mehrfachauswahl, andere Sublevel als Radio
_GUICtrlTreeView_CheckBoxAsRadioInLevel($nTV2) ; == alle Siblings eines Parent im selben Level als Radio-Gruppe
_GUICtrlTreeView_CheckBoxAsRadio($nTV3) ; == alle Item als eine Radio-Gruppe
EndSwitch
WEnd
GUIDelete($hGui)
EndFunc
Func _Main_2()
Local $aChecked, $hGui, $nTV1, $bt_GetChecked
$hGui = GUICreate('Checkbox im Selektions-Level', 310, 470)
GUICtrlCreateLabel('Item mit aktiv. Checkbox im Selektions-Level ermitteln', 15, 15, 275)
$nTV1 = GUICtrlCreateTreeView(15, 35, 275, 370, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES), $WS_EX_CLIENTEDGE)
$bt_GetChecked = GUICtrlCreateButton('Get Checked Item', 15, 415, 100, 22)
GUICtrlCreateLabel('An Pos[0] im Rückgabe-Array ist das selektierte Item', 15, 445, 275)
_AddItem($nTV1, 5, 0, True)
_GUICtrlTreeView_Expand($nTV1)
GUISetState()
[/autoit] [autoit][/autoit] [autoit]While True
Switch GUIGetMsg()
Case -3
ExitLoop
Case $bt_GetChecked
$aChecked = _GUICtrlTreeView_GetCheckedInSelectionLevel($nTV1, True)
_ArrayDisplay($aChecked)
EndSwitch
WEnd
GUIDelete($hGui)
EndFunc
Func _AddItem($_hWnd, $_iLvl=5, $_fSub=0, $_fCheck=False)
If Not IsHWnd($_hWnd) Then $_hWnd = GUICtrlGetHandle($_hWnd)
Local $hItem, $hSubItem, $hTmp, $hTmpSub
For $i = 1 To $_iLvl
$hItem = _GUICtrlTreeView_Add($_hWnd, $_hWnd, 'Item_' & $i)
If $_fCheck Then _GUICtrlTreeView_SetChecked($_hWnd, $hItem, Random(0,1,1))
For $j = 1 To 3
$hSubItem = _GUICtrlTreeView_AddChild($_hWnd, $hItem, 'SubItem_' & $i & '_' & $j)
If $_fCheck Then _GUICtrlTreeView_SetChecked($_hWnd, $hSubItem, Random(0,1,1))
If $_fSub Then
For $n = 1 To 3
$hTmp = _GUICtrlTreeView_AddChild($_hWnd, $hSubItem, 'SubItem_' & $i & '_' & $j & '_' & $n)
If $_fCheck Then _GUICtrlTreeView_SetChecked($_hWnd, $hTmp, Random(0,1,1))
For $m = 1 To 2
$hTmpSub = _GUICtrlTreeView_AddChild($_hWnd, $hTmp, 'SubItem_' & $i & '_' & $j & '_' & $n & '_' & $m)
If $_fCheck Then _GUICtrlTreeView_SetChecked($_hWnd, $hTmpSub, Random(0,1,1))
Next
Next
EndIf
Next
Next
EndFunc