Flickering Listicon

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
popstatic
Messages : 83
Inscription : lun. 20/sept./2004 18:21
Localisation : derriere toi fais gaffe!

Flickering Listicon

Message par popstatic »

Salut a tous!
Avant de vous exposer mon problème je tiens a préciser que j'ai epluché inttégralement les forums anglais et français a la recherche d'une solution, j'ai testé des dizaines de codes, d'api etc....sans succès

donc: soit il n'est pas possible de regler le probleme, soit je m'y prends comme un manche...

Contexte:
je rafraichi une listicon dont les données viennent d'une liste chainée, periodiquement grace à la fonction SetTimer_

Le probleme:
aléatoirement (cela doit dépendre de l'occupation du processeur ou autre) la listicon ou du moins son contenu se met à clignoter..... et c'est très genant...
cela peu arriver avec seulement 3-4 items dedans ou a partir de plus... la seule constante est que si j'utilise le programme, la listicon se met forcement à clignoter a un moment ou un autre.

ca n'est pas un probleme de variable qui devient enorme dans une boucle.
J'ai retiré le panelgadget que j'avais mis pour faire joli, mais cela ne change rien.

j'ai essayé de changer la frequence de rafraichissement, mais que ça soit 100 ms ou 1s ca revien au même.

j'ai essayer de reduire au maximum la taille de la boucle de refresh, mais avec 10 "if" ou aucun cela revient au meme...

tous les codes "antiflickering" que j'ai pu trouver ne concernent que le flickering lors d'un resize, et pas d'un simple update...

alors peut etre que je m'y prends mal pour l'update des données ou autre mais là je suis collé, et je suis odnc jaloux de tous les programmes que j'ai pu voir qui ont des listicons géantes qui se refresh nickel....

voila ci joint un exemple....

Code : Tout sélectionner

Enumeration
  #Window_0
EndEnumeration

;- Gadget Constants
;
Enumeration
  #Frame3D_0
  #String_0
  #Frame3D_1
  #ListIcon_0
  #Frame3D_2
  #String_1
  #Frame3D_3
  #Hyperlink_0
  #ListIcon_3
  ;#ListIcon_4
  #Frame3D_4
  #String_2
  #Button_0
  #Image_0
  #Text_0
  #Panel_0
  #Image_1
  #Image_2
EndEnumeration

Structure Download
  id.l
  nom.s
  Path.s
  Size.s
  Speed.s
  progress.l
  status.l
EndStructure

Global NewList Downloads.download()
Procedure Open_Window_0()
  If OpenWindow(#Window_0, 251, 143, 601, 534, "test",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered);
    
      If CreateGadgetList(WindowID(#Window_0))
      PanelGadget(#Panel_0, 0, 0, 601, 534)
      AddGadgetItem(#Panel_0, -1, "                                                                                                                                                                  ")
        
        Frame3DGadget(#Frame3D_0, 5, 5, 270, 40, "Chercher")
        StringGadget(#String_0, 10, 20, 260, 20, "")
        Frame3DGadget(#Frame3D_1, 5, 50, 590, 220, "Résultats")
        
        ;-
        ListIconGadget(#ListIcon_0, 10, 65, 440, 200, "#", 45,#PB_ListIcon_FullRowSelect)
        AddGadgetColumn(#ListIcon_0, 1, "Nom du fichier",360)
        AddGadgetColumn(#ListIcon_0, 2, "Chemin", 0)
        AddGadgetColumn(#ListIcon_0, 3, "id", 0)
        Frame3DGadget(#Frame3D_2, 455, 60, 135, 40, "Chercher dans les résultats")
        StringGadget(#String_1, 460, 75, 105, 20, "")
        Frame3DGadget(#Frame3D_3, 5, 275, 590, 230, "Téléchargements")
        HyperLinkGadget(#Hyperlink_0, 110, 275, 200, 15, "Double clickez pour lire un fichier", RGB(0, 0, 0))
        
        ;-
        ListIconGadget(#ListIcon_3, 10, 290, 580, 160, "Nom de fichier", 275, #PB_ListIcon_FullRowSelect)
        AddGadgetColumn(#ListIcon_3, 1, "Destination", 0)
        AddGadgetColumn(#ListIcon_3, 2, "Taille", 100)
        AddGadgetColumn(#ListIcon_3, 3, "Vitesse", 100)
        AddGadgetColumn(#ListIcon_3, 4, "Progression", 75)

        Frame3DGadget(#Frame3D_4, 10, 455, 515, 40, "Dossier de destination (défaut: Mes Documents)")
        StringGadget(#String_2, 15, 470, 440, 20, "")
        ButtonGadget(#Button_0, 460, 470, 60, 20, "Selectionner")


        TextGadget(#Text_0, 280, 20, 300, 20, "")
        CloseGadgetList()


      EndIf
      
    EndIf
      
EndProcedure

Procedure refresh()

ResetList(Downloads())
    While NextElement(Downloads())
    i+1
        SetGadgetItemText (#ListIcon_3, Downloads()\Id,Downloads()\Size, 2)
        SetGadgetItemText (#ListIcon_3, Downloads()\Id,Downloads()\Speed, 3)
        SetGadgetItemText (#ListIcon_3, Downloads()\Id,Str(Downloads()\progress)+"%", 4)
        If i%2 = 0
                SetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor, RGB(205,221,233))
            Else
                SetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor, RGB(255, 255, 255))
            EndIf
            If Downloads()\Speed = "Mauvais fichier." 
                SetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor, RGB(208, 68, 68))
            EndIf
            If Downloads()\progress = 100
                SetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor, RGB(148, 190, 148),4)
            EndIf  
            ;Delay(Round(Random(7),1))
    Wend    
EndProcedure

Open_Window_0()
For k.l= 0 To 40
AddElement(Downloads())
            Downloads()\Id = 1
            Downloads()\Path = "blabla"
            Downloads()\Nom = "kikikikiki"
Downloads()\Size = "10Ko"
Downloads()\Speed = "10Ko/s"
Downloads()\progress = 50
            AddGadgetItem (#ListIcon_3, -1, Downloads()\Nom +Chr(10)+GetGadgetText(#String_2)+Downloads()\Nom+".mp3"+ Chr(10)+Downloads()\Size+ Chr(10)+Downloads()\Speed+ Chr(10)+Str(Downloads()\progress),Image3)
Next
SetTimer_( WindowID (#Window_0), 1, 300, @refresh())
Global contu.l
Repeat ; Start of the event loop
  
  Event = WaitWindowEvent() ; This line waits until an event is received from Windows
  
  WindowID = EventWindow() ; The Window where the event is generated, can be used in the gadget procedures
  
  GadgetID = EventGadget() ; Is it a gadget event?
  
  EventType = EventType() ; The event type
  AddKeyboardShortcut(#Window_0,#PB_Shortcut_Return,111)
  ;You can place code here, and use the result as parameters for the procedures
      If Event = #PB_Event_Menu 
       Select EventMenu() 
         Case 111 
           Select GetActiveGadget()
             Case #String_0
             DisableGadget(#ListIcon_0,1)
             sts.s=GetGadgetText(#String_0)
             HideGadget(#ListIcon_0,1)
             DisableGadget(#String_0,1)
             SetGadgetText(#Text_0,"Searching for '"+GetGadgetText(#String_0)+"'...")
             Case #String_1
             If GetGadgetText(#String_1)<> ""

             EndIf
           EndSelect
       EndSelect 
     EndIf
     
     
;      If Event = #WM_LBUTTONDOWN Or clicked=1
;         Gosub perso
; 
;      EndIf
      If Event = #WM_LBUTTONUP
        clicked = 0
     EndIf
  If Event = #PB_Event_Gadget
    
    If GadgetID = #String_0
      
    ElseIf GadgetID = #ListIcon_0
    fich.s= GetGadgetItemText(#ListIcon_0, GetGadgetState(#ListIcon_0),1)
   
      If EventType = #PB_EventType_LeftDoubleClick And GetGadgetState(#ListIcon_0)<>-1

       
      EndIf
    ElseIf GadgetID = #String_1
     If EventType = #PB_EventType_Change 
        If GetGadgetText(#String_1)<> ""

        Else
            SetGadgetText(#String_1,"")

        EndIf
    EndIf
    ElseIf GadgetID = #ListIcon_3
    If EventType = #PB_EventType_LeftDoubleClick
    fich.s= GetGadgetItemText(#ListIcon_3, GetGadgetState(#ListIcon_3),1)

   EndIf    

    ElseIf GadgetID = #String_2
      
    ElseIf GadgetID = #Button_0
dir.s=GetGadgetText(#String_2)
      DEST_DIR.s = PathRequester("Choose file destination",DEST_DIR) 
      If DEST_DIR = ""
        DEST_DIR =  dir
      EndIf
      SetGadgetText(#String_2,DEST_DIR)

        EndIf 
    EndIf


Until Event = #PB_Event_CloseWindow ; End of the event loop


End
ya d'autres gadgets sur la fentre mais le plus important c la listicon du bas!*

Si qq un a déja été confronté a ce probleme, ça serait vraiment genial...

merci d'avance a tous!
Asus bien? asus tres bien!
Avatar de l’utilisateur
Jacobus
Messages : 1559
Inscription : mar. 06/avr./2004 10:35
Contact :

Message par Jacobus »

J'ai aussi ce problème mais ne suis pas arrivé à le résoudre, bien qu'il ne soit pas énorme (pas beaucoup d'éléments dans ton cas) mais ça se conçoit du fait du rafraichissement de la liste.

Peut-être en cachant la liste à chaque remplissage, pas vraiment mieux.

Code : Tout sélectionner

Procedure refresh()

ResetList(Downloads())

 HideGadget(#ListIcon_3,1)
 
    While NextElement(Downloads())
    i+1
        SetGadgetItemText (#ListIcon_3, Downloads()\id,Downloads()\Size, 2)
        SetGadgetItemText (#ListIcon_3, Downloads()\id,Downloads()\Speed, 3)
        SetGadgetItemText (#ListIcon_3, Downloads()\id,Str(Downloads()\progress)+"%", 4)
        If i%2 = 0
                SetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor, RGB(205,221,233))
          Else
                SetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor, RGB(255, 255, 255))
        EndIf
        
        If Downloads()\Speed = "Mauvais fichier."
          SetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor, RGB(208, 68, 68))
        EndIf
            
        If Downloads()\progress = 100
           SetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor, RGB(148, 190, 148),4)
        EndIf 
            ;Delay(Round(Random(7),1))
    Wend 
    
  HideGadget(#ListIcon_3,0) 
  
EndProcedure
Un détail, n'oublie pas de tuer le timer à la fin

Code : Tout sélectionner

Until Event = #PB_Event_CloseWindow ; End of the event loop
KillTimer_(WindowID (#Window_0),1)
End
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

J'ai regardé aussi mais j'ai tout suite pensé qu'il ne serait pas possible d'éviter le scintillement car ce n'est pas un mauvais emploi dans une boucle mais c'est Windows qui rafraichi de cette manière la liste. j'avais aussi remarqué sur des exemples personnels que ce n'était pas toujours systématique.

Il y aura peut-être un codeur avec une bonne solution, qui sait ?

Pour limiter l'effet, il faudrait peut-être ne réécrire que lorsqu'il y a eu un changement (sous Vista c'est la couleur qui cause le problème)


Je te propose ce code qui arrangera peut-être (?) le problème ou le limitera. J'ai modifié la procedure de rafraichissement


Code : Tout sélectionner

Procedure refresh()

ResetList(Downloads())
    While NextElement(Downloads())
    i+1
        SetGadgetItemText (#ListIcon_3, Downloads()\Id,Downloads()\Size, 2)
        SetGadgetItemText (#ListIcon_3, Downloads()\Id,Downloads()\Speed, 3)
        SetGadgetItemText (#ListIcon_3, Downloads()\Id,Str(Downloads()\progress)+"%", 4)
        If i%2 = 0
               If GetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor) <> RGB(205,221,233)
                  SetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor, RGB(205,221,233))
               EndIf
        Else
              If GetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor) <> RGB(255, 255, 255)
                 SetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor, RGB(255, 255, 255))
               EndIf
        EndIf
        If Downloads()\Speed = "Mauvais fichier."
              If GetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor) <> RGB(208, 68, 68)
                  SetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor, RGB(208, 68, 68))
              EndIf
        EndIf
        If Downloads()\progress = 100
              If GetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor, 4) <> RGB(148, 190, 148)
                 SetGadgetItemColor(#ListIcon_3, i-1, #PB_Gadget_BackColor, RGB(148, 190, 148),4)
              EndIf
        EndIf 
    Wend   
EndProcedure
A+
Denis
popstatic
Messages : 83
Inscription : lun. 20/sept./2004 18:21
Localisation : derriere toi fais gaffe!

Message par popstatic »

@ Jacobus: Merci à toi c'est gentil, malheuresement ça n'a rien changé :s, et si toi aussi tu n'a pas reussi a regler le pb ca n'augure rien de bon.... y a un gros manque là....

@Denis: j'essaie et je vous tiens au courant... mais ça reste cuurieux, il y a tellement de programme de telechargements et autres qui rafraichissent sans scintillement....
Asus bien? asus tres bien!
popstatic
Messages : 83
Inscription : lun. 20/sept./2004 18:21
Localisation : derriere toi fais gaffe!

Message par popstatic »

@denis: Alors c'est mieux, moins pire: ça clignote encore quelquefois, mais beaucoup moins souvent. et en plus lorsque tout les fichiers sont terminés, ca clignote plus tout seul, c'est mieux.
Merci!
maintenant je ne lâche toujours pas le morceaux: il y a forcément une solution, je vais encore continuer de chercher, je posterai des progres eventuels dans ce thread.
Asus bien? asus tres bien!
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

lorsque la liste est mise à jour (écriture des fond en couleur) il y aura le clignotement.

Il y a une API windows, LockWindowUpdate_() que tu pourrais essayer.

Tu verrouille l'affichage comme ceci avant d'écrire :

Code : Tout sélectionner

LockWindowUpdate_(gadgetid(#ListIcon_3))
puis après écriture tu déverouilles comme ceci

Code : Tout sélectionner

LockWindowUpdate_(0)
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Après essais, LockWindowUpdate_() ne donne pas de bons résultats

Je me demande si le rafraichissement n'est pas fait pas la fonction de couleur PB, auquel cas on arrivera pas à grand chose. Je ne sais pas si la listIcon avec les couleurs PB est ownerdraw.

Tu devrais essayer la lib de Gnozal PureColor qui il me semble utilise ce mode qui donnera peut-être de meilleurs résultats
Avatar de l’utilisateur
Jacobus
Messages : 1559
Inscription : mar. 06/avr./2004 10:35
Contact :

Message par Jacobus »

J'avais aussi testé en retirant le coloriage mais ça ne change rien, cela ne vient donc pas des couleurs, tu as toujours ce petit flash de refresh. Je me demande s'il ne faut pas créer une sorte de décalage de quelques ms avant de redessiner la liste...
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

J'ai aussi essayé le message WM_SetRedraw qui donne de bons résultats en vitesse de chargement d'une liste importante mais il y a toujours le clignotement, c'est bien un problème interne de rafraichissement.
Avatar de l’utilisateur
Jacobus
Messages : 1559
Inscription : mar. 06/avr./2004 10:35
Contact :

Message par Jacobus »

oui, et je pense que c'est dû à la listicon de PB, car si tu lui ajoute l'option #PB_ListIcon_GridLines, celles-ci ont tendance à merder avec en utilisant les flêches de la scrollbar verticale. Blême que nous avions déjà évoqué il y a quelques, euh... mois, années, je sais plus.
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Le problème ne serait t'il pas moindre si au lieu de tous réinjecter dans la ListIcon, on ne changeait que les éléments qui changent (ajout et supression)
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Sinon j'ai trouvé ce style LVS_EX_DOUBLEBUFFER non documenté qui ne fonctionne qu'à partir de XP avec style activé qui pourrait améliorer les choses.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Ce code améliore le rafraichissement:

Code : Tout sélectionner

Procedure ListIcon_Callback(hWnd, Msg,  wParam, lParam)
  Protected OriginProc.l
  OriginProc.l= GetProp_(hWnd, "OriginProc")
   Select Msg
     Case #WM_ERASEBKGND
       Debug "#WM_ERASEBKGND"
       ProcedureReturn 1
   EndSelect
  ProcedureReturn CallWindowProc_(OriginProc,hWnd,Msg,wParam,lParam)
EndProcedure 


ListIconGadget(#ListIcon_3, 10, 290, 580, 160, "Nom de fichier", 275, #PB_ListIcon_FullRowSelect)
OriginProc = SetWindowLong_(GadgetID(#ListIcon_3), #GWL_WNDPROC, @ListIcon_Callback())
SetProp_(GadgetID(#ListIcon_3), "OriginProc", OriginProc) 
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

On peut aussi rajouter le double buffer:

Code : Tout sélectionner

styles=SendMessage_(GadgetID(#ListIcon_3),#LVM_GETEXTENDEDLISTVIEWSTYLE,0,0)
#LVS_EX_DOUBLEBUFFER=$10000
styles = styles | #LVS_EX_DOUBLEBUFFER 
SendMessage_(GadgetID(#ListIcon_3),#LVM_SETEXTENDEDLISTVIEWSTYLE,0,styles)
Avatar de l’utilisateur
Jacobus
Messages : 1559
Inscription : mar. 06/avr./2004 10:35
Contact :

Message par Jacobus »

Je viens de tester ta solution nico et l'effet de flash est "presque" parti. Si tu regardes la première ligne colorée de la listicon, tu aperçois une ligne en travers pendant un très cours moment. Mais c'est beaucoup mieux...

ta deuxième soluce semble avoir réglé le blème, nickel nico :D
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
Répondre