Forcer les cochage des pères dans une Treeview quand les fils sont cohés

Signaler
Messages postés
32
Date d'inscription
jeudi 10 mai 2007
Statut
Membre
Dernière intervention
27 janvier 2013
-
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
-
Salut à tous,
je cherche 2 fonctions pour ma treeview avec checkbox, avec une urgence pour la première :

1) J'aimerai que quand un noeud fils est coché dans le treeview, ses pères soient eux-aussi obligatoirement cochés.

2) Je voudrai aussi que quand la totalité des fils d'un treeview ne sont pas cochés, la checkbox du père est "coché grisée". Et quand la totalité des fils sont cochés, la checkbox du père est "cohée blanche".

Autant on trouve facilement des fonctions pour cocher automatiquement les enfants, autant je n'arrive vraiment pas a trouver de fonction pour forcer le cochage des noeuds parents quand un ou plusieurs des enfants sont cochées, pouvez-vous maider ?

Merci d'avance !

<!-- / message -->
<!-- edit note -->
A voir également:

30 réponses

Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
en interne, quand tu coche une case, le controle mémorise l'etat coché, t'en préviens en déclenchant l'evenement NodeCheck et restaure l'état coché...

une possibilité est de sous-classer le treeview.

pour le checkbox grisé, voir TVM_SETIMAGELIST (sur MSDN) et tous les messages associés
Messages postés
32
Date d'inscription
jeudi 10 mai 2007
Statut
Membre
Dernière intervention
27 janvier 2013

Sous-classer le treeviw ?
Je ne comprends pas...
Ca donne quoi en code stp ?
Messages postés
7393
Date d'inscription
mercredi 23 avril 2003
Statut
Membre
Dernière intervention
6 avril 2012
56
Re,
>[auteur/SUPERTOMS/1058141.aspx supertoms] (le prends pas mal): On va pas te mâcher tout le travail, commence par assimiler ce que tu viens de voir. et ensuite tu chercheras ce que veux dire sous-Classer. et là tu reviendras.

Le forum ne se résume pas à : "Ca donne quoi en code stp?"

@+: Ju£i?n
Pensez: Réponse acceptée
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
voir ce code, par exemple:
http://www.vbfrance.com/codes/MODULE-SUBCLASSER_38442.aspx

et toute la doc sur les treeview, sur tu trouveras sur MSDN
Messages postés
32
Date d'inscription
jeudi 10 mai 2007
Statut
Membre
Dernière intervention
27 janvier 2013

Qu'est ce que MSDN stp ?
Sinon je suis désolé mais je ne comprend rien à ton code et surtout je ne vois pas le rapport avec des chexkbox en treeview.
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
la MSDN: http://msdn2.microsoft.com/en-us/library/bb773596(VS.85).aspx

l'idée serait de jouer avec le "state" des TVITEM (Nodes)

mon code (subclasser) permet de jouer avec les messages recus par les controles. Ici, tu dois pouvoir intercepter le cochage d'un noeud, et jouer plus finement.
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
je suis parvenu à lui forcer la main...
je peux même aisément intégrer le grisage des checkboxes
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
Voici le même algo que vu précédemment, mais utilisant cette fois le subclassing...

Ajoutes ISubclasser.cls et ModSubclasser.bas dans ton projet
Code de Form1 :

Option Explicit

Private Type TVITEM
mask As Long
hItem As Long
state As Long
stateMask As Long
pszText As String
cchTextMax As Long
iImage As Long
iSelectedImage As Long
cChildren As Long
lParam As Long
End Type

Private Const TV_FIRST = &H1100
Private Const TVM_GETNEXTITEM = (TV_FIRST + 10)
Private Const TVM_GETITEMRECT As Long = (TV_FIRST + 4)
Private Const TVM_GETITEMSTATE As Long = (TV_FIRST + 39)
Private Const TVM_GETITEMA As Long = (TV_FIRST + 12)

Private Const TVGN_PARENT As Long = &H3
Private Const TVGN_NEXT = &H1
Private Const TVGN_CHILD = &H4

Private Const TVIF_HANDLE As Long = &H10
Private Const TVIF_STATE As Long = &H8
Private Const TVSIL_STATE As Long = 2
Private Const TVIS_STATEIMAGEMASK As Long = &HF000&

Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)

Implements ISubclasser

Private mtTree As SubClassedWindow

Private Sub Form_Load()
Dim a As Long
Dim b As Long
Dim c As Long
For a = 0 To 5
TreeView1.Nodes.Add Key:="node" & a, Text:="node" & a
For b = 0 To 5
TreeView1.Nodes.Add "node" & a, tvwChild, "node" & a & ";" & b, Text:="node" & a & ";" & b
For c = 0 To 5
TreeView1.Nodes.Add "node" & a & ";" & b, tvwChild, , Text:="node" & a & ";" & b & ";" & c
Next c
Next b
Next a

'SendMessage TreeView1.hWnd, TVM_SETIMAGELIST, TVSIL_STATE, ByVal CcImlState.hImageList
InitiateSubClassing mtTree, Me, TreeView1.hWnd
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
TerminateSubClassing mtTree
End Sub

Private Function ISubclasser_WindowProc(ByVal hWnd As Long, ByVal uMsg As MessageConstants, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim tItem As TVITEM
Dim nCheckState As Long
Dim hNode As Long
If uMsg = TVM_SETITEMA Then
CopyMemory tItem, ByVal lParam, 16
If (tItem.mask And TVIF_STATE) = TVIF_STATE Then
If (tItem.stateMask And TVIS_STATEIMAGEMASK) = TVIS_STATEIMAGEMASK Then
nCheckState = (tItem.state And TVIS_STATEIMAGEMASK)
'# Si l'item est coché...
If nCheckState = &H2000& Then
'# On récupère le noeud parent
hNode = SendMessage(hWnd, TVM_GETNEXTITEM, TVGN_PARENT, ByVal tItem.hItem)
'# S'il y en a un...
If hNode Then
'# Et on le coche a son tour (qui cochera delui même son noeud parent, et ainsi de suite)
SetItemCheckState hWnd, hNode, &H2000&
End If
ElseIf nCheckState = &H1000& Then
hNode = SendMessage(hWnd, TVM_GETNEXTITEM, TVGN_CHILD, ByVal tItem.hItem)
Do While hNode
If GetItemCheckState(hWnd, hNode) = &H2000& Then
tItem.state = (tItem.state Xor nCheckState) Or &H2000&
Exit Do
End If
hNode = SendMessage(hWnd, TVM_GETNEXTITEM, TVGN_NEXT, ByVal hNode)
Loop
End If
CopyMemory ByVal lParam, tItem, 16
End If
End If
End If

ISubclasser_WindowProc = CallOldProc(mtTree, hWnd, uMsg, wParam, lParam)
End Function

Private Function GetItemCheckState(ByVal vhTreeWnd As Long, ByVal vhItem As Long) As Long
Dim tItem As TVITEM
With tItem
.hItem = vhItem
.mask = TVIF_STATE Or TVIF_HANDLE
.stateMask = TVIS_STATEIMAGEMASK
SendMessage vhTreeWnd, TVM_GETITEMA, 0, tItem

GetItemCheckState = (.state And TVIS_STATEIMAGEMASK)
End With
End Function

Private Sub SetItemCheckState(ByVal vhTreeWnd As Long, ByVal vhItem As Long, ByVal vnChecked As Long)
Dim tItem As TVITEM
Dim nCurrentState As Long
With tItem
.hItem = vhItem
.mask = TVIF_STATE Or TVIF_HANDLE
.stateMask = TVIS_STATEIMAGEMASK
SendMessage vhTreeWnd, TVM_GETITEMA, 0, tItem

nCurrentState = .state And TVIS_STATEIMAGEMASK
.state = (.state Xor nCurrentState) Or (vnChecked)

SendMessage vhTreeWnd, TVM_SETITEMA, 0, tItem
End With
End Sub

-------------------------------------------------------

je n'ai pas intégré les cases grisées... je te laisse le faire.
pour cela, il te suffit simplement de donner la valeur &h3000& au CheckState de ton Item.
ca affichera pour le moment une icone blanche.
pour que ca corresponde a l'icone grisée, a toi de personnaliser les checkboxes, via un controle ImageList.

tu as juste a spécifier l'imagelist utilisé pour les checkbox via la ligne:

SendMessage TreeView1.hWnd, TVM_SETIMAGELIST, TVSIL_STATE, ByVal CcImlState.hImageList
(ici, l'imagelist est CcImlState)


NB: Tout ce qui se trouve dans le code ci-dessus est documenté sur MSDN, n'hesites pas a aller y jeter un oeil
Messages postés
32
Date d'inscription
jeudi 10 mai 2007
Statut
Membre
Dernière intervention
27 janvier 2013

Merci j'ai hate de tester ça tu es impressionnant !
Mais question :
Je trouve ou ISubclasser.cls et ModSubclasser.bas ? Et je les ajoute ou dans le projet ?
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
69
pardon. dispos dans le lien filé plus tot, mais je te l'avais pas dit ^^

http://www.vbfrance.com/codes/MODULE-SUBCLASSER_38442.aspx

Ctrl+D pour les ajouter

en fait, ce code, c'est ce qui se passe en coulisses, en APIs...
ca nous donne plus de controle que ce que nous permet de faire le controle Treeview, qui encapsule habituellement ces fonctionnalités