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 687 fois - Téléchargée 503 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

NISANDSYSTEMS
Messages postés
146
Date d'inscription
vendredi 1 novembre 2002
Statut
Membre
Dernière intervention
13 décembre 2014

Bonjour,

pour eviter le clignotement du controle il suffit juste de supprimer doevents dans les deux procedures tout simplement.

A+
cs_Arcanis
Messages postés
18
Date d'inscription
mardi 31 décembre 2002
Statut
Membre
Dernière intervention
26 juin 2008

Programmix,

Merci de ta réponse. J'ai essayé de mon coté d'utiliser la méthode "cache-cache" sur ton projet. Je passe à 20ms......... En revanche, au lieu d'obtenir un effet de clignotement, j'ai plutôt un effet d'interrupteur (jour/nuit). C'est sans doute dûe à ma machine qui est assez performante (sur mon lieu de travail :-) ).

Je peux en revanche justifier mon choix sur mon projet d'éditeur de texte. Le projet doit permettre une gestion multi-fenêtre à l'interieur de l'appli (avec une fenêtre MDI et des fenêtres filles). Donc lors d'une modification de masse sur un fichier, il est intéressant de voir sur lequel on travaille, surtout quand tous les fichiers sont modifiés les uns après les autres par le même traitement (modif séquentielle de chaque fichier en fait...).
Donc je vais essayé ton api pour essayer de grapiller quelques centièmes...

Je vais également essayé ton projet à plus grande échelle (100 000, 300 000 lignes à remplir) pour voir... Peut être qu'à cette échelle, elle est plus rapide...

Encore merci et a+

Arcanis
cs_PROGRAMMIX
Messages postés
1134
Date d'inscription
mercredi 2 octobre 2002
Statut
Membre
Dernière intervention
24 juillet 2011

Arcanis,

Aucune idée...
Il me semble qu'avec la méthode "cache-cache", il y a un effet de clignotement qui peut être désagréable (c'est du moins ce que j'ai pu observer sur mes premiers essais du genre et de vieux pc).

Le mieux serait de faire une copie de ton projet, de remplacer le cache-cache par les API et de comparer.

C'est hélas, tout ce que je peux dire, vu que je ne suis pas un expert en API et que je n'ai plus touché à VB depuis un bon moment.

Bien à toi,

Programmix
cs_Arcanis
Messages postés
18
Date d'inscription
mardi 31 décembre 2002
Statut
Membre
Dernière intervention
26 juin 2008

Salut à tous,

D'abord bravo pour cette source. L'optimisation via les API est toujours bon à prendre !!!
J'aimerais toutefois vous demander conseil. J'ai développé un éditeur de texte en vb qui permet des modifs de masse sur fichier(s), et j'ai fait l'erreur de choisir un objet listview comme zone de reception du fichier.
Après de nombreuses fonctionnalités ajoutées, je me suis rendu compte d'un manque de performances. En effet, à la base le programme devait servir à ouvrir de petits fichiers.
Maintenant, il est utilisé pour des fichiers dépassant les 300 000 lignes...........
Autant dire que ma listview en prend un coup à chaque manipulation. Pour optimiser, j'ai opté pour la méthode "on cache la listview" ce qui permet un énorme gain de puissance.
Toutefois, d'après vous, vaut il mieux utilisé cette api ou ma méthode de "cache-cache" ???

Merci d'avance pour vos réponses...

PS : épargnez moi les conseils du style "utilise plutôt une textbox", c'est impossible. Autant jeter à la poubelle 2 ans de dev... Je DOIS maintenir la listview...

Arcanis
cavo789
Messages postés
168
Date d'inscription
vendredi 9 janvier 2004
Statut
Membre
Dernière intervention
28 juillet 2009
1
Merci pour tout vos conseils.

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.