[ RESOULU ] TreeGadget changement d'image

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Malo
Messages : 79
Inscription : dim. 09/août/2009 17:48

[ RESOULU ] TreeGadget changement d'image

Message par Malo »

Bonjour à tous

Gnozal m'avait transmit le code ci-dessous pour récupérer le numéro lors de l'appui sur la croix d'un nœud d'un TreeGadget.

1) J'ai ajouté une image "book.png" et je voudrais quelle soit remplacée par "book_open.png" quand le nœud est ouvert, a la manière de l'aide dans PB.

2) Je voudrais également, si cela est possible de pouvoir mettre en gras l'item du nœud ou se trouve l' image .

Merci par avance pour vos idées ou vos solutions......

Code : Tout sélectionner

#repert="C:\......\"

Enumeration
  #Fen
EndEnumeration

Enumeration
  #T_Gadget
  #ImageBord_1
  #ImageBord_2
EndEnumeration

Procedure.l Callback(hWnd, uMsg, wParam, lParam)
  Protected *pnmtv.NM_TREEVIEW
  Select uMsg
    Case #WM_NOTIFY
      *pnmtv = lParam
      Select *pnmtv\hdr\code
        Case #TVN_ITEMEXPANDED
          Select *pnmtv\action
            Case 1
              Debug "Noeud fermé " + Str(*pnmtv\itemNew\lParam)
            Case 2
              Debug "Noeud ouvert " + Str(*pnmtv\itemNew\lParam)
				
          EndSelect
      EndSelect
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

UsePNGImageDecoder() 
LoadImage(#ImageBord_1, #repert + "book.png")    ; "book.png" image de FamFamFam
           
LoadImage(#ImageBord_2, #repert + "book_open.png") ; "book_open.png" image de FamFamFam

image=ImageID(#ImageBord_1)
image2=ImageID(#ImageBord_2)

If OpenWindow(#Fen, 0, 0, 300, 500, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TreeGadget(#T_Gadget, 10, 10, 250, 450)                                     
 
 b=1
  For a = 0 To 3
    AddGadgetItem (#T_Gadget, -1, "Elément normal "+Str(a), 0, 0)
    AddGadgetItem (#T_Gadget, -1, "Noeud "+Str(a), image, 0) 
    AddGadgetItem (#T_Gadget, -1, "Sous-élément 1", 0, 1)         
    AddGadgetItem (#T_Gadget, -1, "Sous-élément 2", 0, 1)
    AddGadgetItem (#T_Gadget, -1, "Sous-élément 3", 0, 1)
    AddGadgetItem (#T_Gadget, -1, "Sous-élément 4", 0, 1)
    AddGadgetItem (#T_Gadget, -1, "Fichier "+Str(a), 0, 0)
  Next
 
  SetWindowCallback(@Callback())

    
  Repeat
   
    Select WaitWindowEvent()
      Case #PB_Event_Gadget
        Select EventGadget()
          Case #T_Gadget
            Debug GetGadgetState(#T_Gadget)
        EndSelect
    EndSelect
   
   
   
  Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Dernière modification par Malo le jeu. 05/janv./2012 23:34, modifié 1 fois.
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: TreeGadget changement d'image

Message par Mesa »

En bidouillant plusieurs codes trouvés sur les forums :

Code : Tout sélectionner

#Tree = 0
#Button = 1

UsePNGImageDecoder()

Procedure.l Callback(hWnd, uMsg, wParam, lParam)
  Protected *pnmtv.NM_TREEVIEW
  
;   typedef struct _NM_TREEVIEW { 
;   NMHDR hdr; 
;   UINT action; 
;   TV_ITEM itemOld; 
;   TV_ITEM itemNew; 
;   POINT ptDrag; 
; } NM_TREEVIEW;
; typedef NM_TREEVIEW FAR* LPNM_TREEVIEW;

; This Structure contains information about a message. 
; The pointer To this Structure is specified As the lParam member of the WM_NOTIFY message.
; typedef struct tagNMHDR { 
;   HWND hwndFrom; 
;   UINT idFrom; 
;   UINT code; 
; } NMHDR; 

; typedef struct _TV_ITEM { tvi
;   UINT mask; 
;   HTREEITEM hItem; 
;   UINT state; 
;   UINT stateMask; 
;   LPSTR pszText; 
;   int cchTextMax; 
;   int iImage; 
;   int iSelectedImage; **********C'est ici********
;   int cChildren; 
;   LPARAM lParam; } 
; TV_ITEM, FAR* LPTV_ITEM;
  
  Select uMsg
    Case #WM_NOTIFY
      *pnmtv = lParam
      Select *pnmtv\hdr\code
        Case #TVN_ITEMEXPANDED
          Select *pnmtv\action
            Case 1
              Debug "Noeud fermé " + Str(*pnmtv\itemNew\lParam)
              ;SetGadgetItemText(#Tree, *pnmtv\itemNew\lParam, "Replié")
              With tvi.TVITEM
                  \mask = #TVIF_IMAGE|#TVIF_HANDLE|#TVIF_SELECTEDIMAGE| #TVIF_STATE
                  \iImage = 1  ;Image index 3 (the 3rd icon - actually, it is the 4th icon, but that is another story!).
                  \iSelectedImage = 1
                  \state = \state And -1
                  \stateMask = #TVIS_BOLD
                EndWith
                i=0 ;For i = 0 To 1
                  tvi\hItem = GadgetItemID(#Tree, i)
                  SendMessage_(GadgetID(#TREE), #TVM_SETITEM, 0, tvi)
                ;Next
              
                
            Case 2
              Debug "Noeud ouvert " + Str(*pnmtv\itemNew\lParam)
              ;SetGadgetItemText(#Tree, *pnmtv\itemNew\lParam, "Déplié")
              
              With tvi.TVITEM
                  \mask = #TVIF_IMAGE|#TVIF_HANDLE|#TVIF_SELECTEDIMAGE| #TVIF_STATE
                  \iImage = 3  ;Image index 3 (the 3rd icon - actually, it is the 4th icon, but that is another story!).
                  \iSelectedImage = 3
                  \state = #TVIS_BOLD
                \stateMask = #TVIS_BOLD 
                EndWith
                i=0 ;For i = 0 To 1
                  tvi\hItem = GadgetItemID(#Tree, i)
                  SendMessage_(GadgetID(#TREE), #TVM_SETITEM, 0, tvi)
                  ;Next
              
            EndSelect
      EndSelect
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

;Images. Load your own here.
  img0 = LoadImage(0, "book.png")
  img1 = LoadImage(1, "book.png")
  img2 = LoadImage(2, "book_open.png")

;The following procedure cheats and uses PB to add our icons to the tree gadget's 'normal' image list prior to adding our normal
;items. It is usually easier to add all icons first before attempting to switch images etc.
  Procedure AddIconToTree(id, hImage)
    AddGadgetItem(id, 0, "", hImage)
    RemoveGadgetItem(id, 0)
  EndProcedure


If OpenWindow(0, 0, 0, 300, 300, "PureBasic Window",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered)

  TreeGadget(#Tree, 10, 10, 280, 250, #PB_Tree_AlwaysShowSelection)                       
    ;Add our 3 icons before adding items to the tree gadget.
      AddIconToTree(#Tree, img0)
      AddIconToTree(#Tree, img1)
      AddIconToTree(#Tree, img2)

  ;Add some items.
    AddGadgetItem(#Tree, -1, "Parent", img0, 0)
    AddGadgetItem(#Tree, -1, "Child", img1, 1)
     AddGadgetItem(#Tree, -1, "Child", img1, 0)
     
; Gras en permanence
;   tvi.TV_ITEM
;   tvi\mask = #TVIF_HANDLE | #TVIF_STATE
;   tvi\state = #TVIS_BOLD
;   tvi\stateMask = #TVIS_BOLD 
;   tvi\hItem = GadgetItemID(#Tree, 0) ; 0 ou numéro de l'item
;   SendMessage_(GadgetID(#Tree), #TVM_SETITEM, 0, tvi)



    SetWindowCallback(@Callback())
    
    
  Repeat
      eventID = WaitWindowEvent()
      Select eventID
        Case #PB_Event_CloseWindow
          Quit = 1
     
       
      EndSelect
   Until Quit = 1
EndIf
End 
Mesa.
Mesa
Messages : 1126
Inscription : mer. 14/sept./2011 16:59

Re: TreeGadget changement d'image

Message par Mesa »

J'ai ajouté la couleur et le changement de font mais j'ai un problème avec "child2" qui se trouve être tronqué sur mon xp.

Vous avez la même chose ?

Code : Tout sélectionner

#Tree = 0
#Button = 1

UsePNGImageDecoder()

Global hFont, hfont2
hFont = LoadFont(0, "Arial", 8, #PB_Font_Underline|#PB_Font_Italic)
hfont2 = LoadFont(0, "Arial", 8, #PB_Font_StrikeOut|#PB_Font_Bold)

Procedure.l Callback(hWnd, uMsg, wParam, lParam)
  Protected *pnmtv.NM_TREEVIEW
  
;   typedef struct _NM_TREEVIEW { 
;   NMHDR hdr; 
;   UINT action; 
;   TV_ITEM itemOld; 
;   TV_ITEM itemNew; 
;   POINT ptDrag; 
; } NM_TREEVIEW;
; typedef NM_TREEVIEW FAR* LPNM_TREEVIEW;

; This Structure contains information about a message. 
; The pointer To this Structure is specified As the lParam member of the WM_NOTIFY message.
; typedef struct tagNMHDR { 
;   HWND hwndFrom; 
;   UINT idFrom; 
;   UINT code; 
; } NMHDR; 

; typedef struct _TV_ITEM { tvi
;   UINT mask; 
;   HTREEITEM hItem; 
;   UINT state; 
;   UINT stateMask; 
;   LPSTR pszText; 
;   int cchTextMax; 
;   int iImage; 
;   int iSelectedImage; **********C'est ici********
;   int cChildren; 
;   LPARAM lParam; } 
; TV_ITEM, FAR* LPTV_ITEM;
  
  Select uMsg
    Case #WM_NOTIFY
      *pnmtv = lParam
      
      ;================================================================================
      
      
      ;==============================================================================
      Select *pnmtv\hdr\code
        Case #TVN_ITEMEXPANDED
          Select *pnmtv\action
            Case 1
              Debug "Noeud fermé " + Str(*pnmtv\itemNew\lParam)
              ;SetGadgetItemText(#Tree, *pnmtv\itemNew\lParam, "Replié")
              With tvi.TVITEM
                  \mask = #TVIF_IMAGE|#TVIF_HANDLE|#TVIF_SELECTEDIMAGE| #TVIF_STATE
                  \iImage = 1  ;Image index 3 (the 3rd icon - actually, it is the 4th icon, but that is another story!).
                  \iSelectedImage = 1
                  \state = \state And -1
                  \stateMask = #TVIS_BOLD
                EndWith
                i=0 ;For i = 0 To 1
                  tvi\hItem = GadgetItemID(#Tree, i)
                  SendMessage_(GadgetID(#TREE), #TVM_SETITEM, 0, tvi)
                ;Next
              
                
            Case 2
              Debug "Noeud ouvert " + Str(*pnmtv\itemNew\lParam)
              ;SetGadgetItemText(#Tree, *pnmtv\itemNew\lParam, "Déplié")
              
              With tvi.TVITEM
                  \mask = #TVIF_IMAGE|#TVIF_HANDLE|#TVIF_SELECTEDIMAGE| #TVIF_STATE
                  \iImage = 3  ;Image index 3 (the 3rd icon - actually, it is the 4th icon, but that is another story!).
                  \iSelectedImage = 3
                  \state = #TVIS_BOLD
                \stateMask = #TVIS_BOLD 
                EndWith
                i=0 ;For i = 0 To 1
                  tvi\hItem = GadgetItemID(#Tree, i)
                  SendMessage_(GadgetID(#TREE), #TVM_SETITEM, 0, tvi)
                  ;Next
                EndSelect
                
            ;Couleur et font  
            Case  #NM_CUSTOMDRAW 
              If *pnmtv\hdr\hwndFrom = GadgetID(#Tree)
                *pTVcd.NMTVCUSTOMDRAW = lparam
                Select *pTVcd\nmcd\dwDrawStage
                  Case #CDDS_PREPAINT
                    result = #CDRF_NOTIFYITEMDRAW
                  Case #CDDS_ITEMPREPAINT
                    ; --> Here we get the text of the TreeGadget item being drawn
                    tvi.TVITEM\mask = #TVIF_TEXT | #TVIF_HANDLE
                    tviText$ = Space(100)
                    tvi.TVITEM\pszText = @tviText$
                    tvi\cchTextMax = 100
                    tvi\hItem = *pTVcd\nmcd\dwItemSpec
                    SendMessage_(*pnmtv\hdr\hwndFrom, #TVM_GETITEM, 0, @tvi)
                    ; --> Now we underline "Item 0" and "Item 4" in blue
                    Select tviText$
                      Case "Child"
                        ; --> Select underlined font & blue
                        SelectObject_(*pTVcd\nmcd\hdc, hFont)
                        SetTextColor_(*pTVcd\nmcd\hdc, RGB(0, 0, 255))
                        result = #CDRF_NEWFONT
                      Case "Child2"
                        ; --> Select strikeout & bold
                        SelectObject_(*pTVcd\nmcd\hdc, hFont2)
                        SetTextColor_(*pTVcd\nmcd\hdc, RGB(255, 0, 255))
                        SetBkColor_(*pTVcd\nmcd\hdc, RGB(0, 0, 0))
                        result = #CDRF_NEWFONT
                      Default
                        result = #CDRF_DODEFAULT
                    EndSelect
                EndSelect
              EndIf
       ;EndIf       
      EndSelect
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

;Images. Load your own here.
  img0 = LoadImage(0, "book.png")
  img1 = LoadImage(1, "book.png")
  img2 = LoadImage(2, "book_open.png")

;The following procedure cheats and uses PB to add our icons to the tree gadget's 'normal' image list prior to adding our normal
;items. It is usually easier to add all icons first before attempting to switch images etc.
  Procedure AddIconToTree(id, hImage)
    AddGadgetItem(id, 0, "", hImage)
    RemoveGadgetItem(id, 0)
  EndProcedure


If OpenWindow(0, 0, 0, 300, 300, "PureBasic Window",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered)

  TreeGadget(#Tree, 10, 10, 280, 250, #PB_Tree_AlwaysShowSelection)                       
    ;Add our 3 icons before adding items to the tree gadget.
      AddIconToTree(#Tree, img0)
      AddIconToTree(#Tree, img1)
      AddIconToTree(#Tree, img2)

  ;Add some items.
    AddGadgetItem(#Tree, -1, "Parent", img0, 0)
    AddGadgetItem(#Tree, -1, "Child", img1, 1)
     AddGadgetItem(#Tree, -1, "Child2", img1, 0)
     
; Gras en permanence
;   tvi.TV_ITEM
;   tvi\mask = #TVIF_HANDLE | #TVIF_STATE
;   tvi\state = #TVIS_BOLD
;   tvi\stateMask = #TVIS_BOLD 
;   tvi\hItem = GadgetItemID(#Tree, 0) ; 0 ou numéro de l'item
;   SendMessage_(GadgetID(#Tree), #TVM_SETITEM, 0, tvi)



    SetWindowCallback(@Callback())
    
    
  Repeat
      eventID = WaitWindowEvent()
      Select eventID
        Case #PB_Event_CloseWindow
          Quit = 1
     
       
      EndSelect
   Until Quit = 1
EndIf
End 
Mesa.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: TreeGadget changement d'image

Message par Le Soldat Inconnu »

J'ai remis à jour un vieux code PB 3.94 pour te servir d'exemple. Tu trouveras ton bonheur dedans.

Code : Tout sélectionner

Enumeration
	#RechercheFichier_Tree
	
	;- Images
	; TreeGadget
	#Fichier0
	#Fichier1
	#Dossier0
	#Dossier1
	#Fichier0_Selected
	#Fichier1_Selected
	#Dossier0_Selected
	#Dossier1_Selected
	#Tree_Glyph_Closed
	#Tree_Glyph_Opened
EndEnumeration

;- Contantes et variables de paramétrage
Global RechercheFichier_Espace.l
Global ColorBackGround_Selected.l, ColorBackGround_Normal.l, ColorBorder_Selected.l, ColorBorder_Normal.l
#RechercheFichier_EspacePx = 8

#CheckBox_Size = 12 ; Taille des boite à cocher
#ColorBackGround_Selected = $707070 ; Couleur de fond du texte sélectionné
#ColorBackGround_Normal = $E0FFFF ; Couleur de fond du texte normal
#ColorBorder_Normal = $FFFFFF ; Couleur de bordure du texte sélectionné
#ColorBorder_Selected = 0 ; Couleur de bordure du texte normal
#ColorText_NormalSelected = $FFFFFF ; Couleur du texte sélectionné
#ColorText_Normal = 0 ; couleur du texte normal
ColorBackGround_Selected = CreateSolidBrush_(#ColorBackGround_Selected)
ColorBackGround_Normal = CreateSolidBrush_(#ColorBackGround_Normal)
ColorBorder_Selected = CreateSolidBrush_(#ColorBorder_Selected)
ColorBorder_Normal = CreateSolidBrush_(#ColorBorder_Normal)
#ColorCheckBox_Element = $74C274 ; Couleur de l'élement signifiant que la case est cochée
#ColorCheckBox_Border = 0 ; Couleur de bordure des boites à cocher
#ColorCheckBox_Selected = $74D6FF ; Coleur des boites à cocher sélectionnées

#Tree_Glyph_Space = 19 ; décalage en pixel après chaque noeuds

;- Polices de caractère
Global FontID_Defaut.l
FontID_Defaut = GetStockObject_(#DEFAULT_GUI_FONT)


; Cette liste va recevoir le contenu du dossier dans lequel on a lancé la recherche
Structure InfoFichier
	Nom.s
	Type.l
	Info1.l
	Info2.l
	Niveau.l
EndStructure
Global NewList RechercheFichier.InfoFichier()
Global DossierRecherche.s

Procedure.l TreeGadget_CustomDraw(WindowID.l, Message.l, wParam.l, lParam.l)
	#NM_CUSTOMDRAW = #NM_FIRST - 12
	#CDDS_ITEM = $10000
	#CDDS_SUBITEM = $20000
	#CDDS_PREPAINT = $1
	#CDDS_POSTPAINT = $2
	#CDDS_ITEMPREPAINT = #CDDS_ITEM | #CDDS_PREPAINT
	#CDDS_ITEMPOSTPAINT = #CDDS_ITEM | #CDDS_POSTPAINT
	#CDDS_SUBITEMPREPAINT = #CDDS_SUBITEM | #CDDS_ITEMPREPAINT
	#CDRF_DODEFAULT = $0
	#CDRF_NEWFONT = $2
	#CDRF_SKIPDEFAULT = $4
	#CDRF_NOTIFYITEMDRAW = $20
	#CDRF_NOTIFYPOSTPAINT = $10
	#CDRF_NOTIFYSUBITEMDRAW = $20
	#CDRF_NOTIFYPOSTERASE = $40
	#CDIS_SELECTED = $1
	#CDIS_CHECKED = $8
	
	Select Message
		Case #WM_NOTIFY
			*TVCDHeader.NMTVCUSTOMDRAW = lParam
			If *TVCDHeader\nmcd\hdr\hWndFrom = GadgetID(#RechercheFichier_Tree) And *TVCDHeader\nmcd\hdr\code = #NM_CUSTOMDRAW
				Select *TVCDHeader\nmcd\dwDrawStage
						
					Case #CDDS_PREPAINT
						ProcedureReturn #CDRF_NOTIFYITEMDRAW
						
					Case #CDDS_ITEMPREPAINT
						; Modifier la couleur de fond
						; *TVCDHeader\clrTextBk = RGB(255, 255, 223)
						; Modifier la couleur du texte
						; *TVCDHeader\clrText = RGB(0, 0, 0)
						; Modifier la police
						; SelectObject_(*TVCDHeader\nmcd\hDC, FontBold)
						
						; Le numéro de la ligne affichée
						Item = -1
						For n = 0 To CountGadgetItems(#RechercheFichier_Tree) - 1
							If GadgetItemID(#RechercheFichier_Tree, n) = *TVCDHeader\nmcd\dwItemSpec
								Item = n
								Break
							EndIf
						Next
						If Item >= 0 And *TVCDHeader\nmcd\rc\Right <> 0
							; *TVCDHeader\nmcd\rc\Right <> 0
							; Quand le TreeGadget est trop petit pour afficher le texte en entier, un ToolTip apparait et dans ce cas la zone de dessin est nulle
							; il faut donc filtrer cet affichage
							
							Level.l = *TVCDHeader\iLevel ; Le niveau de l'item (dans combien de noeuds il se trouve)
							*TVCDHeader\nmcd\rc\Left - GetScrollPos_(GadgetID(#RechercheFichier_Tree), #SB_HORZ) ; Prendre en compte le décalage horizontal (la ScrollBar horizontale)
							
							; On sélectionne l'élément dans la liste
							SelectElement(RechercheFichier(), Item)
							
							; On regarde si on a associé un icône à l'élément
							pitem.TV_ITEM\mask = #TVIF_IMAGE
							pitem\hItem = *TVCDHeader\nmcd\dwItemSpec
							SendMessage_(GadgetID(#RechercheFichier_Tree), #TVM_GETITEM, 0, pitem)
							If pitem\iImage = 0 ; Si pas d'icône
								Fichier.s = DossierRecherche + RechercheFichier()\Nom ; on récupère le nom du fichier
								SHGetFileInfo_(Fichier, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_ICON | #SHGFI_SMALLICON) ; on extrait l'icône associé au fichier
								pitem.TV_ITEM\mask = #TVIF_IMAGE | #TVIF_SELECTEDIMAGE
								pitem\iImage = InfosFile\iIcon
								pitem\iSelectedImage = InfosFile\iIcon
								SendMessage_(GadgetID(#RechercheFichier_Tree), #TVM_SETITEM, 0, pitem) ; On mets l'icône sur l'item
							EndIf
							
							; Le niveau de l'item (on décale l'affichage en fonction du nombre de noeuds avant l'item)
							*TVCDHeader\nmcd\rc\Left + Level * #Tree_Glyph_Space
							
							; On dessine les textes sans couleur de fond
							SetBkMode_(*TVCDHeader\nmcd\hDC, #TRANSPARENT)
							
							ItemExpanded = GetGadgetItemState(#RechercheFichier_Tree, Item)
							ItemSelected = ItemExpanded & #PB_Tree_Selected ; Si la ligne est sélectionnée
							ItemExpanded = ItemExpanded & #PB_Tree_Expanded ; Si la ligne est déployée (pour les dossier)
							
							; On choisi les couleurs du cadre autour du texte et la couleur du texte
							If ItemSelected
								ColorBackGround = ColorBackGround_Selected ; Couleur de fond
								ColorBorder = ColorBorder_Selected ; Couleur de bordure
								SetTextColor_(*TVCDHeader\nmcd\hDC, #ColorText_NormalSelected) ; Couleur du texte
							Else
								ColorBackGround = ColorBackGround_Normal
								ColorBorder = ColorBorder_Normal
								SetTextColor_(*TVCDHeader\nmcd\hDC, #ColorText_Normal)
							EndIf
							
							; On choisi les images des boites à cocher
							If RechercheFichier()\Type = 1 ; Si on a un fichier
								If ItemSelected
									If RechercheFichier()\Info1
										Image1 = #Fichier1_Selected
									Else
										Image1 = #Fichier0_Selected
									EndIf
									If RechercheFichier()\Info2
										Image2 = #Fichier1_Selected
									Else
										Image2 = #Fichier0_Selected
									EndIf
								Else
									If RechercheFichier()\Info1
										Image1 = #Fichier1
									Else
										Image1 = #Fichier0
									EndIf
									If RechercheFichier()\Info2
										Image2 = #Fichier1
									Else
										Image2 = #Fichier0
									EndIf
								EndIf
							Else ; Si on a un dossier
								If ItemSelected
									If RechercheFichier()\Info1
										Image1 = #Dossier1_Selected
									Else
										Image1 = #Dossier0_Selected
									EndIf
									If RechercheFichier()\Info2
										Image2 = #Dossier1_Selected
									Else
										Image2 = #Dossier0_Selected
									EndIf
								Else
									If RechercheFichier()\Info1
										Image1 = #Dossier1
									Else
										Image1 = #Dossier0
									EndIf
									If RechercheFichier()\Info2
										Image2 = #Dossier1
									Else
										Image2 = #Dossier0
									EndIf
								EndIf
								
								; On dessine le noeud
								If ItemExpanded
									Image = #Tree_Glyph_Opened
								Else
									Image = #Tree_Glyph_Closed
								EndIf
								DrawState_(*TVCDHeader\nmcd\hDC, 0, 0, ImageID(Image), 0, *TVCDHeader\nmcd\rc\Left, *TVCDHeader\nmcd\rc\Top, 19, 16, #DST_BITMAP | #DSS_NORMAL)
							EndIf
							
							*TVCDHeader\nmcd\rc\Left + #Tree_Glyph_Space
							
							; On dessine les boites à cocher
							DrawState_(*TVCDHeader\nmcd\hDC, 0, 0, ImageID(Image1), 0, *TVCDHeader\nmcd\rc\Left, *TVCDHeader\nmcd\rc\Top + (16 - #CheckBox_Size) / 2, #CheckBox_Size, #CheckBox_Size, #DST_BITMAP | #DSS_NORMAL)
							DrawState_(*TVCDHeader\nmcd\hDC, 0, 0, ImageID(Image2), 0, *TVCDHeader\nmcd\rc\Left + #CheckBox_Size + 1, *TVCDHeader\nmcd\rc\Top + (16 - #CheckBox_Size) / 2, #CheckBox_Size, #CheckBox_Size, #DST_BITMAP | #DSS_NORMAL)
							
							; On dessine l'icône
							himl = SendMessage_(GadgetID(Gadget), #TVM_GETIMAGELIST, #TVSIL_NORMAL, 0)
							ImageList_Draw_(himl, pitem\iImage, *TVCDHeader\nmcd\hDC, *TVCDHeader\nmcd\rc\Left + 2 * #CheckBox_Size + 8, *TVCDHeader\nmcd\rc\Top, #ILD_NORMAL)
							
							; On regarde la longueur en pixel du texte
							Txt.s = GetFilePart(RechercheFichier()\Nom)
							GetTextExtentPoint32_(*TVCDHeader\nmcd\hDC, Txt, Len(Txt), TxtSize.SIZE)
							
							; On dessine le cadre autour du texte
							*TVCDHeader\nmcd\rc\Left + 2 * #CheckBox_Size + 8 + 16 + 3
							*TVCDHeader\nmcd\rc\Right = *TVCDHeader\nmcd\rc\Left + 6 + TxtSize\cx
							FillRect_(*TVCDHeader\nmcd\hDC, *TVCDHeader\nmcd\rc, ColorBackGround) ; Le fond
							FrameRect_(*TVCDHeader\nmcd\hDC, *TVCDHeader\nmcd\rc, ColorBorder) ; La bordure
							
							; On dessine le texte
							*TVCDHeader\nmcd\rc\Left + 3
							DrawTextEx_(*TVCDHeader\nmcd\hDC, Txt, -1, *TVCDHeader\nmcd\rc, #DT_EXPANDTABS | #DT_VCENTER | #DT_SINGLELINE | Alignement, 0)
						EndIf
						ProcedureReturn #CDRF_SKIPDEFAULT
						
				EndSelect
			EndIf
			
	EndSelect
	
	ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Procedure AddTreeGadgetImageList(Gadget)
	himl = SendMessage_(GadgetID(Gadget), #TVM_GETIMAGELIST, #TVSIL_NORMAL, 0)
	If himl = 0 ; Pas d'imagelist associé au TreeGadget
		himl = SHGetFileInfo_("", 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_SYSICONINDEX | #SHGFI_SMALLICON)
		SendMessage_(GadgetID(Gadget), #TVM_SETIMAGELIST, #TVSIL_NORMAL, himl) ; On associe l'imagelist avec le gadget
		SetWindowCallback(@TreeGadget_CustomDraw()) ; Cette callback sert à personnaliser l'apparence du TreeGadget
	EndIf
EndProcedure

Procedure AnalyseDossier(Num, Dossier.s)
	If Right(Dossier, 1) <> "\" : Dossier + "\" : EndIf
	
	; Le dossier 2
	Dossier2.s = RemoveString(Dossier, DossierRecherche)
	Dossier3.s = ReplaceString(Left(Dossier2, Len(Dossier2) - 1), "\", "\?1?")
	; on met ?1? devant le nom des dossier et ?2? devant le nom des fichiers
	; Ainsi lors du tri des données, les dossiers seront placés avant les fichiers
	; Il suffira ensuite de supprimer les ?1? et ?2? des noms de fichiers ou dossiers
	; Le caratère ? n'étant pas utilisable dans les noms de fichiers, cet ajout ne présente aucun problème
	If Dossier3
		Dossier3 = "?1?" + Dossier3 + "\"
	EndIf
	
	If ExamineDirectory(Num, Dossier, "*.*")
		While NextDirectoryEntry(Num)
			Select DirectoryEntryType(Num)
				Case #PB_DirectoryEntry_File
					; On a un fichier
					Name.s = DirectoryEntryName(Num)
					AddElement(RechercheFichier())
					RechercheFichier()\Nom = Dossier3 + "?2?" + Name
					RechercheFichier()\Type = 1
					
				Case #PB_DirectoryEntry_Directory
					; On a un dossier
					Name.s = DirectoryEntryName(Num)
					If Name <> "." And Name <> ".."
						AddElement(RechercheFichier())
						RechercheFichier()\Nom = Dossier3 + "?1?" + Name
						RechercheFichier()\Type = 2
						
						; On lance l'analyse sur ce nouveau dossier (analyse récursive)
						AnalyseDossier(Num + 1, Dossier + Name)
						
					EndIf
			EndSelect
			
		Wend
		FinishDirectory(Num)
	EndIf
EndProcedure

Procedure RechercheFichiers(Dossier.s)
	
	If Right(Dossier, 1) <> "\" : Dossier + "\" : EndIf ; On s'assure qu'il y a bien un \ à la fin du nom du dossier
	
	AddTreeGadgetImageList(#RechercheFichier_Tree)
	ClearGadgetItemList(#RechercheFichier_Tree)
	ClearList(RechercheFichier())
	
	DossierRecherche = Dossier
	
	AnalyseDossier(0, Dossier)
	
	; On tri les noms de fichiers et dossiers
	; Je passe ici par un SortStructuredList car SortList à une erreur dans PB 3.93 avec le tri de listes chainés contenant du texte, ceci doit-être résolu pour les future version.
	SortStructuredList(RechercheFichier(), 2, 0, #PB_Sort_String)
	
	; On retire les ?1? et ?2?, et également l'adresse du dossier d'origine
	ForEach RechercheFichier()
		RechercheFichier()\Nom = RemoveString(RemoveString(RechercheFichier()\Nom, "?1?"), "?2?")
	Next
	
	; On rempli la liste de fichier
	HideGadget(#RechercheFichier_Tree, 1) ; Le fait de cacher le gadget permet de le remplir plus rapidement
	Nb_Dossier = 0
	n = 0
	Txt.s = Space(RechercheFichier_Espace)
	ForEach RechercheFichier()
		RechercheFichier()\Niveau = CountString(RechercheFichier()\Nom, "\") ; On regarde le niveau de l'élément
		AddGadgetItem(#RechercheFichier_Tree, n, Txt + GetFilePart(RechercheFichier()\Nom) + Txt, 0, RechercheFichier()\Niveau)
		SetGadgetItemState(#RechercheFichier_Tree, n - 1, #PB_Tree_Expanded)
		n + 1
	Next
	
	; Les icônes ne sont pas affichées ici, elles sont gérer par la callback
	; Pourquoi ?
	; Les icônes sont très long à charger, donc plutot que de récupérer les icônes de tous les éléments
	; La callback récupère les icônes uniquement pour les éléments affichés
	; Ce qui donne un gain de temps considérable
	
	SetGadgetState(#RechercheFichier_Tree, 0) ; On sélectionne le premier élément
	
	HideGadget(#RechercheFichier_Tree, 0)
	
EndProcedure








; Ouvre une fenêtre
If OpenWindow(0, 0, 0, 200, 250, "Recherche fichiers", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered) = 0
	End
EndIf


;{ Nombre d'espace nécessaire au décalage des textes du TreeGadget
; A quoi sert ceci ?
; Comme je dessine entièreement le TreeGadget, la longueur de la ligne n'est pas forcément identiques à la ligne standard
; Alors j'ajoute des espaces pour ajusté la longueur
StartDrawing(WindowOutput(0))
	DrawingFont(FontID_Defaut)
	RechercheFichier_Espace = 0
	Repeat
		RechercheFichier_Espace + 1
	Until TextWidth(Space(RechercheFichier_Espace)) >= (#RechercheFichier_EspacePx + 2 * #CheckBox_Size) / 2
StopDrawing()
;} 
;{ Création des images du TreeGadget
CreateImage(#Fichier0, #CheckBox_Size, #CheckBox_Size)
StartDrawing(ImageOutput(#Fichier0))
	Box(0, 0, #CheckBox_Size, #CheckBox_Size, $FFFFFF)
	DrawingMode(#PB_2DDrawing_Outlined)
	Box(0, 0, #CheckBox_Size, #CheckBox_Size, #ColorCheckBox_Border)
StopDrawing()
CreateImage(#Fichier1, #CheckBox_Size, #CheckBox_Size)
StartDrawing(ImageOutput(#Fichier1))
	Box(0, 0, #CheckBox_Size, #CheckBox_Size, $FFFFFF)
	Box(2, 2, #CheckBox_Size - 4, #CheckBox_Size - 4, #ColorCheckBox_Element)
	DrawingMode(#PB_2DDrawing_Outlined)
	Box(0, 0, #CheckBox_Size, #CheckBox_Size, #ColorCheckBox_Border)
StopDrawing()

CreateImage(#Dossier0, #CheckBox_Size, #CheckBox_Size)
StartDrawing(ImageOutput(#Dossier0))
	Box(0, 0, #CheckBox_Size, #CheckBox_Size, $FFFFFF)
	DrawingMode(#PB_2DDrawing_Outlined)
	Circle(#CheckBox_Size / 2, #CheckBox_Size / 2, #CheckBox_Size / 2 - 1, #ColorCheckBox_Border)
StopDrawing()
CreateImage(#Dossier1, #CheckBox_Size, #CheckBox_Size)
StartDrawing(ImageOutput(#Dossier1))
	Box(0, 0, #CheckBox_Size, #CheckBox_Size, $FFFFFF)
	Circle(#CheckBox_Size / 2, #CheckBox_Size / 2, #CheckBox_Size / 2 - 3, #ColorCheckBox_Element)
	DrawingMode(4)
	Circle(#CheckBox_Size / 2, #CheckBox_Size / 2, #CheckBox_Size / 2 - 1, #ColorCheckBox_Border)
StopDrawing()

CreateImage(#Fichier0_Selected, #CheckBox_Size, #CheckBox_Size)
StartDrawing(ImageOutput(#Fichier0_Selected))
	Box(0, 0, #CheckBox_Size, #CheckBox_Size, $FFFFFF)
	Box(1, 1, #CheckBox_Size - 2, #CheckBox_Size - 2, #ColorCheckBox_Selected)
	DrawingMode(#PB_2DDrawing_Outlined)
	Box(0, 0, #CheckBox_Size, #CheckBox_Size, #ColorCheckBox_Border)
StopDrawing()
CreateImage(#Fichier1_Selected, #CheckBox_Size, #CheckBox_Size)
StartDrawing(ImageOutput(#Fichier1_Selected))
	Box(0, 0, #CheckBox_Size, #CheckBox_Size, $FFFFFF)
	Box(1, 1, #CheckBox_Size - 2, #CheckBox_Size - 2, #ColorCheckBox_Selected)
	Box(2, 2, #CheckBox_Size - 4, #CheckBox_Size - 4, #ColorCheckBox_Element)
	DrawingMode(#PB_2DDrawing_Outlined)
	Box(0, 0, #CheckBox_Size, #CheckBox_Size, #ColorCheckBox_Border)
StopDrawing()

CreateImage(#Dossier0_Selected, #CheckBox_Size, #CheckBox_Size)
StartDrawing(ImageOutput(#Dossier0_Selected))
	Box(0, 0, #CheckBox_Size, #CheckBox_Size, $FFFFFF)
	Circle(#CheckBox_Size / 2, #CheckBox_Size / 2, #CheckBox_Size / 2, #ColorCheckBox_Selected)
	DrawingMode(#PB_2DDrawing_Outlined)
	Circle(#CheckBox_Size / 2, #CheckBox_Size / 2, #CheckBox_Size / 2 - 1, #ColorCheckBox_Border)
StopDrawing()
CreateImage(#Dossier1_Selected, #CheckBox_Size, #CheckBox_Size)
StartDrawing(ImageOutput(#Dossier1_Selected))
	Box(0, 0, #CheckBox_Size, #CheckBox_Size, $FFFFFF)
	Circle(#CheckBox_Size / 2, #CheckBox_Size / 2, #CheckBox_Size / 2, #ColorCheckBox_Selected)
	Circle(#CheckBox_Size / 2, #CheckBox_Size / 2, #CheckBox_Size / 2 - 3, #ColorCheckBox_Element)
	DrawingMode(#PB_2DDrawing_Outlined)
	Circle(#CheckBox_Size / 2, #CheckBox_Size / 2, #CheckBox_Size / 2 - 1, #ColorCheckBox_Border)
StopDrawing()

CreateImage(#Tree_Glyph_Closed, 19, 16)
StartDrawing(ImageOutput(#Tree_Glyph_Closed))
	Box(0, 0, 19, 16, $FFFFFF)
	DrawingMode(#PB_2DDrawing_Outlined)
	Box(5, 4, 9, 9, 0)
	Line(9, 6, 1, 5, 0)
	Line(7, 8, 5, 1, 0)
StopDrawing()

CreateImage(#Tree_Glyph_Opened, 19, 16)
StartDrawing(ImageOutput(#Tree_Glyph_Opened))
	Box(0, 0, 19, 16, $FFFFFF)
	DrawingMode(#PB_2DDrawing_Outlined)
	Box(5, 4, 9, 9, 0)
	Line(7, 8, 5, 1, 0)
StopDrawing()

;} 


TreeGadget(#RechercheFichier_Tree, 0, 0, 200, 200, #PB_Tree_AlwaysShowSelection)

Temps1 = ElapsedMilliseconds()

; On lance la recherche
; Vous devez mettre ici le dossier de votre choix
; 3700 fichiers en 16 secondes sur mon 900mhz
RechercheFichiers("e:\purebasic\")

Temps2 = ElapsedMilliseconds()

TextGadget(#PB_Any, 0, 200, 200, 15, Str(CountList(RechercheFichier())) + " fichiers et dossiers")
TextGadget(#PB_Any, 0, 215, 200, 15, Str(Temps2 - Temps1) + " ms")

Repeat
	Event = WaitWindowEvent()
	
	Select Event
		Case #PB_Event_Gadget
			Select EventGadget()
				Case #RechercheFichier_Tree
					Select EventType()
						Case #PB_EventType_LeftClick
							GetCursorPos_(@MouseClic.TV_HITTESTINFO\pt) ; Coordonnée de la souris
							ScreenToClient_(GadgetID(#RechercheFichier_Tree), @MouseClic\pt) ; On convertit les coordonnées par rapport au gadget
							SendMessage_(GadgetID(#RechercheFichier_Tree), #TVM_HITTEST, 0, MouseClic) ; On récupère le handle de l'élément cliqué
							; On récupère le numéro de l'item cliqué
							Item = -1
							For n = 0 To CountGadgetItems(#RechercheFichier_Tree) - 1
								If GadgetItemID(#RechercheFichier_Tree, n) = MouseClic\hItem
									Item = n
									Break
								EndIf
							Next
							If Item >= 0
								SetGadgetState(#RechercheFichier_Tree, Item) ; On sélectionne l'item (FULLROWSELECT)
								
								SelectElement(RechercheFichier(), Item) ; on récupère l'élément de la liste
								
								MouseClic\pt\X + GetScrollPos_(GadgetID(#RechercheFichier_Tree), #SB_HORZ) ; prise en compte du décalage du à la ScrollBar verticale
								
								; Si on clique sur la première case à cocher
								If MouseClic\pt\X >= RechercheFichier()\Niveau * #Tree_Glyph_Space + #Tree_Glyph_Space And MouseClic\pt\X < RechercheFichier()\Niveau * #Tree_Glyph_Space + #Tree_Glyph_Space + #CheckBox_Size
									; On change l'état de la case à cocher
									RechercheFichier()\Info1 = 1 - RechercheFichier()\Info1
									InvalidateRect_(GadgetID(#RechercheFichier_Tree), 0, 0) ; On dit de redessiner le gadget
									
									; Si on clique sur la deuxième case à cocher
								ElseIf MouseClic\pt\X >= RechercheFichier()\Niveau * #Tree_Glyph_Space + #Tree_Glyph_Space + #CheckBox_Size + 1 And MouseClic\pt\X < RechercheFichier()\Niveau * #Tree_Glyph_Space + #Tree_Glyph_Space + #CheckBox_Size * 2 + 1
									; On change l'état de la case à cocher
									RechercheFichier()\Info2 = 1 - RechercheFichier()\Info2
									InvalidateRect_(GadgetID(#RechercheFichier_Tree), 0, 0) ; On dit de redessiner le gadget
								EndIf
							EndIf
					EndSelect
			EndSelect
	EndSelect
	
Until Event = #PB_Event_CloseWindow
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
kernadec
Messages : 1606
Inscription : ven. 25/avr./2008 11:14

Re: TreeGadget changement d'image

Message par kernadec »

bonsoir
merci, pour les codes
@Mesa avec des icônes ton code fonctionne
Sinon! comme toi... sous XP child2 apparait sans image png

cordialement
Malo
Messages : 79
Inscription : dim. 09/août/2009 17:48

Re: TreeGadget changement d'image

Message par Malo »

Merci pour vos réponses, et à Mesa et Le Soldat Inconnu pour ces différents codes.

j'ai réadapté quelques lignes du code de Mesa (je viens de prendre connaissance du tiens LSI que je vais testé avec intérêt également) et élagué à partir de ";Couleur et font"
ou effectivement il y a un problème sur "Child2". Sous vista "Child2" est barré avec un trait et incomplet.

Ce qui m'a surpris c'est la Procedure AddIconToTree(id, hImage) ou on ajoute et supprime les images et que malgré tout elles reste en mémoire dans #Tree, ou il y a quelque chose que je n'ai pas compris dans le fonctionnement.

Voici le code qui répond à ma demande

Code : Tout sélectionner

#Tree = 0
#Button = 1

UsePNGImageDecoder()

Global hFont, hfont2
hFont = LoadFont(0, "Arial", 8, #PB_Font_Underline|#PB_Font_Italic)
hfont2 = LoadFont(0, "Arial", 12, #PB_Font_StrikeOut|#PB_Font_Bold)

Procedure.l Callback(hWnd, uMsg, wParam, lParam)
  Protected *pnmtv.NM_TREEVIEW

 
  Select uMsg
    Case #WM_NOTIFY
      *pnmtv = lParam
    
      Select *pnmtv\hdr\code
        Case #TVN_ITEMEXPANDED
          Select *pnmtv\action

            Case 1
              Debug "Noeud fermé " + Str(*pnmtv\itemNew\lParam)
              ;SetGadgetItemText(#Tree, *pnmtv\itemNew\lParam, "Replié")
              With tvi.TV_ITEM
                  \mask = #TVIF_IMAGE|#TVIF_HANDLE|#TVIF_SELECTEDIMAGE| #TVIF_STATE
                  \iImage = 1  ;Image index 3 (the 3rd icon - actually, it is the 4th icon, but that is another story!).
                  \iSelectedImage = 1
                  \state = state And -1
                  \stateMask = #TVIS_BOLD
                EndWith
                i=*pnmtv\itemNew\lParam;0 ;For i = 0 To 1
                  tvi\hItem = GadgetItemID(#Tree, i)
                  SendMessage_(GadgetID(#TREE), #TVM_SETITEM, 0, tvi)
				  SetGadgetItemColor(#TREE, i, #PB_Gadget_FrontColor, -1)

                
             
               
            Case 2
              Debug "Noeud ouvert " + Str(*pnmtv\itemNew\lParam)
              ;SetGadgetItemText(#Tree, *pnmtv\itemNew\lParam, "Déplié")
             
              With tvi.TV_ITEM
                  \mask = #TVIF_IMAGE|#TVIF_HANDLE|#TVIF_SELECTEDIMAGE| #TVIF_STATE
                  \iImage = 2  ;Image index 3 (the 3rd icon - actually, it is the 4th icon, but that is another story!).
                  \iSelectedImage = 2
                  \state = #TVIS_BOLD
                \stateMask = #TVIS_BOLD
                EndWith
                i=*pnmtv\itemNew\lParam;0 ;For i = 0 To 1
                  tvi\hItem = GadgetItemID(#Tree, i)
                  SendMessage_(GadgetID(#TREE), #TVM_SETITEM, 0, tvi)
					SetGadgetItemColor(#TREE, i, #PB_Gadget_FrontColor, $FF0000)

                 
             EndSelect
               
    
       EndSelect
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

;Images. Load your own here.
  ;img0 = LoadImage(0, "book.png")
  img1 = LoadImage(1, "book.png")
  img2 = LoadImage(2, "book_open.png")

;The following procedure cheats and uses PB to add our icons to the tree gadget's 'normal' image list prior to adding our normal
;items. It is usually easier to add all icons first before attempting to switch images etc.
  Procedure AddIconToTree(id, hImage)
    AddGadgetItem(id, 0, "", hImage)
    RemoveGadgetItem(id, 0)
  EndProcedure


If OpenWindow(0, 0, 0, 300, 300, "PureBasic Window",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered)

  TreeGadget(#Tree, 10, 10, 280, 250, #PB_Tree_AlwaysShowSelection)                       
    ;Add our 3 icons before adding items to the tree gadget.
    ;AddIconToTree(#Tree, img0)
	AddIconToTree(#Tree, img1)
	AddIconToTree(#Tree, img2)

	;Add some items.
	AddGadgetItem(#Tree, -1, "Parent", img1, 0)
	AddGadgetItem(#Tree, -1, "Fils1", 0, 1)
	AddGadgetItem(#Tree, -1, "Fils1", 0, 1)
	AddGadgetItem(#Tree, -1, "Parent 2",img1 , 0)
	AddGadgetItem(#Tree, -1, "Fils2", 0, 1)
	AddGadgetItem(#Tree, -1, "Fils2", 0, 1)
	AddGadgetItem(#Tree, -1, "Parent 3",img1 , 0)
	AddGadgetItem(#Tree, -1, "Fils3", 0, 1)
	AddGadgetItem(#Tree, -1, "Fils3", 0, 1)




     
; Gras en permanence
;   tvi.TV_ITEM
;   tvi\mask = #TVIF_HANDLE | #TVIF_STATE
;   tvi\state = #TVIS_BOLD
;   tvi\stateMask = #TVIS_BOLD
;   tvi\hItem = GadgetItemID(#Tree, 0) ; 0 ou numéro de l'item
;   SendMessage_(GadgetID(#Tree), #TVM_SETITEM, 0, tvi)

EndIf

    SetWindowCallback(@Callback())
   
   
  Repeat
      eventID = WaitWindowEvent()
      Select eventID
        Case #PB_Event_CloseWindow
          Quit = 1
     
       
      EndSelect
   Until Quit = 1

End 


Répondre