Accélération de la vitesse d'affichage en "gelant" le rafraîchissement d'un contrôle

Soyez le premier à donner votre avis sur cette source.

Vue 10 624 fois - Téléchargée 502 fois

Description

Généralement, lorsqu'on ajoute beaucoup d'éléments à une liste à l'aide d'une boucle et qu'on utilise DoEvents, il se produit un effet de clignotement
de la liste (à moins qu'on n'ait masqué celle-ci).

La source que je vous propose fait appel à 2 API qui permettent de "geler" et "dégeler" le rafraîchissement de cette liste ce qui accélère également le remplissage de la liste en question (voir le screenchot pour comparer l'ajout de 1000 éléments dans une ListView en utilisant les deux méthodes).

Les API en question sont InvalidateRect() et ValidateRect()

Source / Exemple :


'API pour mesurer le temps écoulé
Private Declare Function GetTickCount Lib "kernel32" () As Long

'API permettant de "geler" la mise à jour d'un objet
Private Declare Sub InvalidateRect Lib "user32" (ByVal hWnd As Long, ByVal t As Long, ByVal bErase As Long)
Private Declare Sub ValidateRect Lib "user32" (ByVal hWnd As Long, ByVal t As Long)
'   1000 éléments sont ajoutés à la ListView via une boucle rendant régulièrement la main à Windows
'   mais ici, on utilise 2 API permettant de "geler" et "dégeler" le rafraîchissement de la liste.
'   La liste "clignote" moins voire pas du tout si on annule la ligne (=>)

Private Sub Command2_Click()
    
    Dim nStart As Long
    Dim i As Integer
    
    nStart = GetTickCount()
    ListView1.View = 3
    
    ListView1.ListItems.Clear
        
    For i = 1 To 1000
        ListView1.ListItems.Add , , "Chaîne " & CStr(i)
            
        '-- En validant la région, il n'y aura pas de génération d'un message WM_PAINT
        ValidateRect ListView1.hWnd, 0&
            
        '-- "Rafraîchit" la liste
'(=>) Essayez également en désactivant cette ligne...
        If (i Mod 10) = 0 Then InvalidateRect ListView1.hWnd, 0&, 0&
            
        '-- Autorise le multi-tâche
        DoEvents
    Next i
    
    InvalidateRect ListView1.hWnd, 0&, 0&
    MsgBox Str(GetTickCount() - nStart) & " ms", vbOKOnly, "Avec optimisation :"

End Sub

Conclusion :


'============================
PS: Encore une source qui n'est pas de moi mais... vous connaissez la chanson...

Cette source est extraite d'un article de Xavier LECLERCQ consacré à l'optimisation du code en VB paru dans la revue "Programmez!" du mois de Novembe 2000 (n° 26)

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

cs_MyC
Messages postés
94
Date d'inscription
lundi 23 septembre 2002
Statut
Membre
Dernière intervention
22 avril 2003
-
Je ne sais pas si tu as vu ma question dans le forum ou si tu lis dans mes pensées, mais c'est exactement ce qu'il me fallait. Un grand merci à toi (10/10, même si cette source n'est pas de toi, car c'est une très bonne contribution) !
cs_MyC
Messages postés
94
Date d'inscription
lundi 23 septembre 2002
Statut
Membre
Dernière intervention
22 avril 2003
-
Peux-tu me dire à quoi sert cette ligne : "If (i Mod 10) = 0 Then InvalidateRect ListView1.hWnd, 0&, 0&", car comme j'ai mis cette ligne en commentaire comme il est suggéré dans le code, et au lieu de 15751 ms, en vue grandes icônes, avec 1000 items, et avec cette ligne, cela se fait en 99 ms avec les mêmes propriétés mais avec la ligne en commentaire et sans le moindre petit clignotement. Alors j'aimerai savoir, si est est obligatoire dans certains cas et sinon à quoi sert-elle ? Merci d'avance pour ta réponse, et encore bravo pour cette source très utile !
cs_PROGRAMMIX
Messages postés
1134
Date d'inscription
mercredi 2 octobre 2002
Statut
Membre
Dernière intervention
24 juillet 2011
-
Comme tu as pû le voir, cette API est également utilisée après la boucle et sert à rafraîchir la liste.

La ligne de code peut être traduit de la manière suivante :
If (i Mod 10) = 0 signifie que toutes les 10 boucles...
Then InvalidateRect... on redessine la ListView1
Ainsi et suivant les PC, le clignotement peut encore apparaître mais à une moindre fréquence...

Effectivement, en supprimant cette ligne de code, on accélère encore le temps de réalisation de la boucle puisque qu'on ne la redessine plus (ce qui se faisait 1000/10=100 fois)
cs_FPatrick
Messages postés
122
Date d'inscription
mercredi 27 novembre 2002
Statut
Membre
Dernière intervention
8 août 2014
-
Bonjour tout d'abord.
Si tu mets la liste ou les controles dans un picturebox et que tu rends invisible ce picturebox lors d'un chargement , la vitesse de chargement et d'affichage est considérablement augmenté (remarqué plusieurs fois dans mes applications) . Par contre on charge un controle donc de la mémoire , a voir ....
Merci d'avance pour tes commentaires....
peug
Messages postés
234
Date d'inscription
mercredi 25 octobre 2000
Statut
Membre
Dernière intervention
5 octobre 2012
-
La ligne "ValidateRect ListView1.hWnd, 0&" doit se trouver en dehors de la boucle For ! non ?

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.