Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0386: Flackern bei Aktualisierung im Listview unterbinden

 von 

Beschreibung 

Wird ein ListView mit vielen Einträgen erweitert, kommt es oft zu einenem hässlichen Flackern. Indem das Conrtol in eine PictureBox gesetzt und letzteres für die Zeit der ListView-Erweiterung vom grafischen Update freigesprochen wird, verschwindet auch das Flackern.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

SendMessageA (SendMessage)

Download:

Download des Beispielprojektes [2,86 KB]

'Dieser Quellcode stammt von http://www.activevb.de
'und kann frei verwendet werden. Für eventuelle Schäden
'wird nicht gehaftet.

'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
'Ansonsten viel Spaß und Erfolg mit diesem Source!

'------------- Anfang Projektdatei Project1.vbp -------------
' Die Komponente 'Microsoft Windows Common Controls 6.0 (SP6) (mscomctl.ocx)' wird benötigt.

'--------- Anfang Formular "Form1" alias Form1.frm  ---------
' Steuerelement: Bildfeld-Steuerelement "Picture1"
' Steuerelement: Listenanzeigesteuerungselement "ListView1" auf Picture1
' Steuerelement: Schaltfläche "Command2"
' Steuerelement: Kontrollkästchen-Steuerelement "Check1"
' Steuerelement: Schaltfläche "Command1"
' Steuerelement: Beschriftungsfeld "Label1"
' Steuerelement: Beschriftungsfeld "Label2"


'Autor: Michael Pluemper
'E-Mail: michael.pluemper@epost.de

Option Explicit

Private Declare Function SendMessage Lib "user32" Alias _
        "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As _
        Long, ByVal wParam As Long, lParam As Any) As Long

Private Const WM_SETREDRAW As Long = &HB&

Private Sub Command1_Click()
    Dim I As Long
    Dim vstrWert As String
    
    'Aktualisierung abschalten
    If Check1.Value = vbChecked Then
        Call SendMessage(Picture1.hwnd, WM_SETREDRAW, 0&, 0&)
    End If
        
    'Schleife für Berechnungen, ...
    For I = 1 To 500
        'Messages ausführen
        DoEvents
        
        'Hier steht der Code, der die Einträge erzeugt
        vstrWert = "Eintrag " & Str(I)
        
        'In ListView eintragen
        ListView1.ListItems.Add I, , vstrWert
        
        If I Mod 10 = 0 Then Label1.Caption = I
    Next I
    
    'Aktualisierung wieder einschalten
    If Check1.Value = vbChecked Then
        Call SendMessage(Picture1.hwnd, WM_SETREDRAW, 1&, 0&)
    End If
    
    'Für Neudarstellung
    ListView1.Refresh
End Sub

Private Sub Command2_Click()
    ListView1.ListItems.Clear
End Sub

Private Sub Form_Load()
    With ListView1
        .Width = Picture1.Width
        .Height = Picture1.Height
    End With
End Sub
'---------- Ende Formular "Form1" alias Form1.frm  ----------
'-------------- Ende Projektdatei Project1.vbp --------------

Tipp-Kompatibilität:

Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 4 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von Marius am 12.03.2007 um 11:15

Bei dem Befehl "Call SendMessage(Picture1.hwnd, WM_SETREDRAW, 0&, 0&)" , wird doch die piturebox ausgeblendet. wie kann ich das dann wieder unterbinden?

Kommentar von Romeo Rechtacek am 12.03.2004 um 09:25

Warum nicht gleich die Aktualisierung für das ListView ausschalten. Für Windows ist ein ListView doch auch nichts anderes als ein Fenster und das hat nun mal auch ein Fenster-Handle. Das spart eine Menge Arbeit und auch Zeit. Und um ein Abbrechen bei vielen Einträgen zu ermöglichen, kann mann eine DoEvents-Anweisung einbauen. Mit einer Form-globalen Variable kann man dann die Schleife von außen beenden.
Eine Datei mit über 52000 Einträgen, die zeilenweise eingelesen wird, braucht da bei nur ca. 3,5 Sekunden.

Hier ein kurzer Code-Ausschnitt.

SendMessage ListView1.hwnd, WM_SETREDRAW, 0, 0
Do While Not EOF(FHandle)
If bBeenden Then Exit Do
ListView1.ListItems.Add Index, Key, Text
DoEvents
Loop
SendMessage ListView1.hwnd, WM_SETREDRAW, 1, 0

Kommentar von Thierry Zoller am 21.10.2001 um 13:42

Such mal google nach "lockwindowupdate" ab

Kommentar von Michael am 15.06.2001 um 23:26

Und wenn ich 20000 Einträge in die Listview reinhauen will dann wartet der User vergeblich und fragt sich was da vor sich geht! (man kann in der Zeit ja in der ListView nichts anklicken bzw scrollen)
Ich suche eine Funktion (oder eine ListView-Alternative) die das so macht wie die Windows Suchfunktion! also EInträge werden ohne Flackern in die List eingetragen, man kann zwischendurch auch scrollen und normal arbeiten, das wäre genial...