[R] Ajouter plusieurs niveaux à un Treeview (indenter)

Aide sur les Interfaces Graphique Utilisateurs (GUI).
Règles du forum
.
Répondre
CleM71
Niveau 2
Niveau 2
Messages : 24
Enregistré le : mer. 16 avr. 2008 08:58
Status : Hors ligne

[R] Ajouter plusieurs niveaux à un Treeview (indenter)

#1

Message par CleM71 »

Bonjour,

Je souhaiterais afficher une arborescence dans un TreeView, en filtrant uniquement par dossier.

Je n'ai pas de problèmes à lister de manière récursive tous les répertoires d'un chemin, puis tous les répertoires d'un répertoire du chemin ...

En revanche, je ne trouve pas comment les mettre en forme dans mon objet TreeView afin qu'une indentation soit mise en place, et qu'on puisse clairement identifier à quel répertoire parent appartient un répertoire fils.

Pour que vous compreniez mieux, voici ma problématique. Je dois copier des raccourcis dans les menu démarrer d'utilisateurs SAMBA dont le profil est déporté sur le réseau ("itinérant").

Un lecteur R:\ contient une arborescence qui représente à peu près le fonctionnement d'un établissement scolaire :

R:\

--Salle 1
----Eleves
--------Menu Démarrer
----Administrateurs
--------Menu Démarrer
----Professeurs
--------Menu Démarrer
--Salle 2
----Eleves
--------Menu Démarrer
----Administrateurs
--------Menu Démarrer
----Professeurs
-------Menu Démarrer

Je souhaiterais obtenir une interface TreeView qui offre des cases à cocher.
Exemple : si "Salle 1 est coché", alors toutes les cases à cocher filles sont cochées.

Je doute que celà soit possible via l'objet TreeView intégré à AutoIt via Koda, je suppose donc que je vais devoir passer par une API ?

Si vous pouvez m'avancer sur le sujet ...


Merci :)
Modifié en dernier par CleM71 le lun. 26 mai 2008 15:13, modifié 1 fois.
CleM71
Niveau 2
Niveau 2
Messages : 24
Enregistré le : mer. 16 avr. 2008 08:58
Status : Hors ligne

Re: [..] Ajouter plusieurs niveaux à un Treeview (indenter)

#2

Message par CleM71 »

Bon j'ai résolu tout seul comme un grand l'histoire de l'indentation.

J'avais pas lu le manuel officiel pour GUICtrlCreateTreeViewItem :arrow:

On peut donc ajouter un item dans l'objet TreeView (GUICtrlCreateTreeViewItem("blablabla", ObjTreeView) ou dans un Item de l'objet TreeView.

Voici une procédure récursive qui vous permet de lister une arborescence de répertoires :

Code : Tout sélectionner

ChkCreationFromComputersUsersAndSubFolers("R:", $TreeStartMenus)

Func ChkCreationFromComputersUsersAndSubFolers($SourceFolder, $ParentItem)
    Local $Search
    Local $File
    Local $FileAttributes
    Local $FullFilePath
    Local $ComputerGroup

    $Search = FileFindFirstFile($SourceFolder & "\*.*")
    While 1
        If $Search = -1 Then
            ExitLoop
        EndIf
        $File = FileFindNextFile($Search)
        If @error Then ExitLoop
        $FullFilePath = $SourceFolder & "\" & $File
        $FileAttributes = FileGetAttrib($FullFilePath)
        If StringInStr($FileAttributes,"D") Then
            $ComputerGroup = GUICtrlCreateTreeViewItem($File, $ParentItem)
            ChkCreationFromComputersUsersAndSubFolers($FullFilePath, $ComputerGroup)
        EndIf
    WEnd
    FileClose($Search)
EndFunc
 
En revanche je suis toujours preneur d'une solution pour les cases à cocher :)

Merci
CleM71
Niveau 2
Niveau 2
Messages : 24
Enregistré le : mer. 16 avr. 2008 08:58
Status : Hors ligne

Re: [..] Ajouter plusieurs niveaux à un Treeview (indenter)

#3

Message par CleM71 »

Je continue dans mon avancée

Je suis parvenu à insérer des CheckBox dans mon TreeView

Lors de la déclaration :

Code : Tout sélectionner

$TreeStartMenus = GUICtrlCreateTreeView(16, 160, 305, 240, BitOr ( $TVS_CHECKBOXES , $TVS_HASBUTTONS , $TVS_HASLINES , $TVS_LINESATROOT, $TVS_SINGLEEXPAND  ))
 
Il me manque une dernière fonctionnalité : incorporer le choix semi sélectif

:arrow: Si un parent est coché, tous les fils doivent être cochés
:arrow: Si tous les fils ne sont pas cochés, le parent ne doit pas être décoché, ni coché, mais doit être coché gris

J'ai lu cette documentation

http://msdn2.microsoft.com/en-us/librar ... S.85).aspx

Mais je ne parviens pas à trouver ...

Merci
Fichiers joints
tree.PNG
CleM71
Niveau 2
Niveau 2
Messages : 24
Enregistré le : mer. 16 avr. 2008 08:58
Status : Hors ligne

Re: [..] Ajouter plusieurs niveaux à un Treeview (indenter)

#4

Message par CleM71 »

Une petite remontée :) En vous remerciant pour l'aide que vous m'apporterez :)
Avatar du membre
tofu
Niveau 3
Niveau 3
Messages : 30
Enregistré le : mar. 15 avr. 2008 14:48
Status : Hors ligne

Re: [..] Ajouter plusieurs niveaux à un Treeview (indenter)

#5

Message par tofu »

Bonjour,

A vrai dire je ne connais pas trop l'utilisation des Treeview (pas encore eu besoin de les utiliser...), cependant en fouinant un peu je suis tombé sur des fonctions contenues dans l'UDF de gestion des Treeview.

Notamment ces deux fonctions ci:
#Include <GuiTreeView.au3>
_GUICtrlTreeView_GetFirstChild($hWnd, $hItem)

#Include <GuiTreeView.au3>
_GUICtrlTreeView_GetNextChild($hWnd, $hItem)
Si, en partant d'un Item précis lors de la détection du "check" de celui-ci, tu fais une récurrence comme pour la création de ton arborescence, puis utilises la fonction:
#Include <GuiTreeView.au3>
_GUICtrlTreeView_SetChecked($hWnd, $hItem[, $fCheck = True])
il devrait y avoir moyen de solutionner ce que tu cherches à faire non?
L'informatique, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi !
CleM71
Niveau 2
Niveau 2
Messages : 24
Enregistré le : mer. 16 avr. 2008 08:58
Status : Hors ligne

Re: [..] Ajouter plusieurs niveaux à un Treeview (indenter)

#6

Message par CleM71 »

Merci beaucoup !

Tu m'as encore bien avancé. Je sais pas comment tu fais pour trouver, mais tu trouves :)

Par contre la faisabilité est extrêmement compliquée. Je suis vraiment en train de me torturer les neurones, mais j'ai bon espoir.

Je posterai ma solution quand elle sera terminée.

PS : j'ai finalement choisi d'oublier ce que je demandais à propos de la sélection récursive, car la solution initiale correspond en fait mieux à l'utilisation qui sera faîte de l'application.

Pour ceux que ça intéresserait, sachez qu'une solution de sélection récursive existe. Voici le code :

Code : Tout sélectionner

#include <GuiTreeView.au3>
#Include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>

Global $hTreeView

$hGui = GUICreate("TreeView Check All", 460, 300)

$TreeView = GUICtrlCreateTreeView(20, 20, 420, 260, BitOR($GUI_SS_DEFAULT_TREEVIEW, $TVS_CHECKBOXES), BitOR($WS_EX_DLGMODALFRAME,$WS_EX_CLIENTEDGE))
$hTreeView = GUICtrlGetHandle($TreeView)
BuildExampleTree($TreeView) ;just a test

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Local $hWndFrom, $idFrom, $iCode, $tNMHDR = DllStructCreate("hwnd hwndFrom;int idFrom;int code", $lParam)
    $hWndFrom = DllStructGetData($tNMHDR, "hwndFrom")
    $iCode = DllStructGetData($tNMHDR, "code")
    If $hWndFrom = $hTreeView Then
        Switch $iCode
            Case $NM_CLICK
                ;;$tagTVHITTESTINFO = "int X;int Y;int Flags;int Item"
                Local $tMPos = _WinAPI_GetMousePos(True, $hWndFrom), $tHit = _GUICtrlTreeView_HitTestEx($hWndFrom, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2))
                Local $hItem = DllStructGetData($tHit, "Item"), $iFlags = DllStructGetData($tHit, "Flags")
                If $hItem <> 0 And BitAND($iFlags, $TVHT_ONITEMSTATEICON) Then
                    _TV_Checkbox_MultiSet($hWndFrom, $hItem, 1)
                EndIf
            Case $TVN_KEYDOWN
                Local $tNMTVKEY = DllStructCreate("hwnd;int;int;short key;uint", $lParam)
                Local $hSelected = _GUICtrlTreeView_GetSelection($hWndFrom)
                If DllStructGetData($tNMTVKEY, "key") = 0x20 And $hSelected Then ;;space
                    _TV_Checkbox_MultiSet($hWndFrom, $hSelected, 1)
                EndIf
            Case Else
        EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc
Func _TV_Checkbox_MultiSet($hWnd, $hItem, $fTop = 0)
    Local $fChecked = _GUICtrlTreeView_GetChecked($hWnd, $hItem)
    If $fTop Then $fChecked = Not $fChecked
    If _GUICtrlTreeView_GetChildren($hWnd, $hItem) Then
        Local $hChild = _GUICtrlTreeView_GetFirstChild($hWnd, $hItem)
        Do
            _GUICtrlTreeView_SetChecked($hWnd, $hChild, $fChecked)
            If _GUICtrlTreeView_GetChildren($hWnd, $hChild) Then
                _TV_Checkbox_MultiSet($hWnd, $hChild)
            EndIf
            $hChild = _GUICtrlTreeView_GetNextChild($hWnd, $hChild)
        Until $hChild = 0
    EndIf
EndFunc

Func BuildExampleTree($treeID)
    Local $ti, $tsi, $i, $j, $k
    $ti = GUICtrlCreateTreeViewItem("1", $treeID)
    For $i = 1 To 5
        $tsi = GUICtrlCreateTreeViewItem("1-" & $i, $ti)
        If $i = 3 Then
            For $j = 1 To 3
                $tssi = GUICtrlCreateTreeViewItem("1-" & $i & '-' & $j, $tsi)
                If $j = 2 Then
                    For $k = 1 To 4
                        GUICtrlCreateTreeViewItem("1-" & $i & '-' & $j & '-' & $k, $tssi)
                    Next
                EndIf
            Next
        EndIf
    Next
    GUICtrlCreateTreeViewItem("2", $treeID)
    ControlTreeView('', '', $treeID, "Expand", '#0')
    ControlTreeView('', '', $treeID, "Expand", '#0|#2')
    ControlTreeView('', '', $treeID, "Expand", '#0|#2|#1')
EndFunc
 
Répondre