Page 1 sur 1

Impossible de coloriser la dernière ligne si SetGadgetState

Publié : lun. 09/mars/2026 11:41
par Francois
Bonjour,

Je n'arrive pas dans un CallBack à coloriser la dernière ligne d'une ListIconGadget si j'utilise la fonction SetGadgetState.
Pour illustrer mon soucis, j'ai largement épuré mon code pour aller à l'essentiel, ce qui peut expliquer certaines lourdeurs comme l'emploi d'un callback :

Code : Tout sélectionner

; *************************
; * Déclarations diverses *
; *************************

CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
  CompilerError "Ce programme fonctionne que sous Windows !"
CompilerEndIf

; Déclaration et chargement des polices de caractères
; -> Pour l'affichage des logs
Global Log_Font_Reg.l                                   ; Identifie la police "regular"
Global Log_Font_Bold.l                                  ; Identifie la police "gras"
Log_Font_Name.s  = "Comic Sans MS"                           ; Nom de la police
Log_Font_Size.l  = 11                                    ; Taille de la police
Log_Font_Reg     = FontID(LoadFont(#PB_Any, Log_Font_Name, Log_Font_Size)) 
Log_Font_Bold    = FontID(LoadFont(#PB_Any, Log_Font_Name, Log_Font_Size, #PB_Font_Bold))


; **************************
; * Déclaration de la form *
; **************************
Global hWnd_Windows_main
Global hWnd_Lst_Log

Procedure OpenhWnd_Windows_main(x = 0, y = 0, width = 1190, height = 630)
  
  hWnd_Windows_main = OpenWindow(#PB_Any, x, y, width, height, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  hWnd_Lst_Log = ListIconGadget(#PB_Any, 10, 10, 850, 110, "Column 1", 100, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)

EndProcedure

Procedure hWnd_Windows_main_Events(event)
  Select event
    Case #PB_Event_CloseWindow
      ProcedureReturn #False
      
    Case #PB_Event_Menu
      Select EventMenu()
      EndSelect
      
    Case #PB_Event_Gadget
      Select EventGadget()
      EndSelect
  EndSelect
  ProcedureReturn #True
EndProcedure

; *********************
; * Autres procèdures *
; *********************

Procedure.l MainCallback(hWnd, uMsg, wParam, lParam) 
  
  lResult = #PB_ProcessPureBasicEvents
  
  Select uMsg
    Case #WM_NOTIFY
      *hdr.NMHDR = lParam
      
      Select *hdr\code
        Case #NM_CUSTOMDRAW
          *nml.NMLVCUSTOMDRAW = lParam
          hwndFrom = GetProp_(*nml\nmcd\hdr\hwndFrom, "PB_ID")
          
          Select hwndFrom
            Case hWnd_Lst_Log
              
              Select *nml\nmcd\dwDrawStage
                Case #CDDS_PREPAINT
                  lResult = #CDRF_NOTIFYITEMDRAW
                  
                Case #CDDS_ITEMPREPAINT
                  lResult = #CDRF_NOTIFYSUBITEMDRAW
                  
                Case #CDDS_SUBITEM | #CDDS_ITEMPREPAINT
                  
                  ; On personnalise l'arrière plan de chaque cellule du gadget Lst_Log
                  Lst_Log_Row.l = *nml\nmcd\dwItemSpec           ; Numéro de la ligne de la Case à colorier
                  Lst_Log_Col.l = *nml\iSubItem                  ; Numéro de la colonne de la case à colorier
                  
                  If Lst_Log_Col = 0
                    SetGadgetItemData(hWnd_Lst_Log, Lst_Log_Row, Val(Mid(GetGadgetItemText(hWnd_Lst_Log, Lst_Log_Row, 0),2,1)))
                  EndIf
                  
                  If (Lst_Log_Row/2) * 2 = Lst_Log_Row           ; Si c'est une ligne paire, première ligne (0) et les suivantes (2, 4...)
                                                                 ; (ça fonctionne car le numéro de ligne commence à 0 et est déclaré de type entier)
                    *nml\clrTextBk = RGB($C5, $E0, $B3)          ; -> Vert foncé
                  Else                                           ; Si c'est une ligne impaire, deuxième (1) et les suivantes (3, 5...)
                    *nml\clrTextBk = RGB($E2, $EF, $D9)          ; -> Vert clair
                  EndIf                 
                  
                  ; On personnalise la police de chaque cellule du gadget Lst_Log
                  If Lst_Log_Col = 0                             ; C'est la colonne qui recevra le code d'erreur
                    SelectObject_(*nml\nmcd\hDC, Log_Font_Bold)
                  Else                                           ; C'est la colonne qui recevra le libellé de l'événement
                    SelectObject_(*nml\nmcd\hDC, Log_Font_Reg)
                  EndIf 
                  
                  ; On change la couleur de la police de chaque ligne en fonction du code Severity (colonne 0)
                  *nml\clrText = RGB(255,0,0) ; -> Tous les lignes seront écrites en rouge

                  lResult = #CDRF_NEWFONT
                  
              EndSelect
              
          EndSelect
          
      EndSelect
      
  EndSelect
  
  ProcedureReturn lResult
EndProcedure

Procedure.l WLog(Log_Event$, Log_Severity)
  
  Log_Event_Pgm$ = "(" + Str(Log_Severity) + ")" + #LF$ + Log_Event$
  AddGadgetItem(hWnd_Lst_Log, -1, Log_Event_Pgm$)
  
  ProcedureReturn 0
EndProcedure

; ***********************
; * Programme principal *
; ***********************

; Ouverture de la fenêtre principale. (La fenêtre a été déclarée cachée lors de sa conception)
OpenhWnd_Windows_main()

; -> Lst_Log : Mise en forme du gadget
                                                                                            ;    - 1er colonne (codes d'erreur)
SetGadgetItemAttribute(hWnd_Lst_Log, 0, #PB_ListIcon_ColumnWidth, 50)                       ; Fixe la largeur
SetGadgetItemText(hWnd_Lst_Log, -1, "", 0)                                                  ; Largeur + entête de la colonne
SetGadgetItemAttribute(hWnd_Lst_Log, 0, #PB_ListIcon_ColumnAlignment, #PB_ListIcon_Center)  ; Alignement de la colonne
                                                                                            ;    - 2ème colonne (description du message)
AddGadgetColumn(hWnd_Lst_Log, 1, "Événements.", 770)                                        ; Largeur + entête de la colonne

; Met en place la procèdure de CallBack pour la fenêtre principale
SetWindowCallback(@MainCallback(), hWnd_Windows_main)

; Remplissage des logs (randow() détermine la priorité -> donc la couleur de l'affichage)

For i = 1 To 3
  WLog("Message bidon " + Str(i),Random(3,1))
Next i

; On se positionne à la fin de la liste
SetGadgetState(hWnd_Lst_Log, CountGadgetItems(hWnd_Lst_Log) -1 )

; ***********************************
; * Boucle d'attente d'un évenement *
; ***********************************
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      End
  EndSelect
ForEver

; Fin du programme.
Fin_Pgm:

End
En gros, je rempli une List IconGadget et j'essaie de coloriser chaque ligne suivant certains critères.
Le problème vient de la ligne 139 qui me permet de me positionner sur le dernier élément :

Code : Tout sélectionner

SetWindowCallback(@MainCallback(), hWnd_Windows_main)
Si cette ligne est écrite, la dernière ligne du gadget n'est pas colorisé (fond + texte) alors que sa police a bien été changée.
Si cette ligne est retirée, toutes les lignes du gadget sont correctement colorisées et ont la bonne police.

Pourriez-vous m'expliquer ce que je fais de mal ?
Je vous en remercie par avance.

F.R.

Re: Impossible de coloriser la dernière ligne si SetGadgetState

Publié : lun. 09/mars/2026 12:06
par case
pour moi tout vas bien c'est juste que tu sélectionne la dernière ligne (par contre pas de surlignage comme avec un clic de la souris )si tu clique sur un autre élément il y a la bonne couleur sur la dernière ligne
si tu ajoute juste après la ligne suivante

Code : Tout sélectionner

SetGadgetState(hWnd_Lst_Log,   -1 )
cela désélectionne la ligne et la couleur est bonne.

Re: Impossible de coloriser la dernière ligne si SetGadgetState

Publié : lun. 09/mars/2026 14:18
par Francois
Merci beaucoup, cela fonctionne. Je n'y avais pas pensé.
Un grand merci.