VB -24: AutoRedraw

Geheimnisvolles Geschehen im Hintergrund

Jetzt wird es höchste Zeit, daß wir uns mal näher mit der wichtigen Eigenschaft "AutoRedraw" befassen. Sie hat Einfluß auf das Geschehen im Speicher, wenn eine Grafikmethode wie Print, PaintPicture oder Line angewandt wird. Ist AutoRedraw eingeschaltet (True), dann wird jede Ausgabemethode auch im Speicher durchgeührt. Ihr könnt Euch das so vorstellen, daß die Form, wie sie gerade aussieht, nochmal im Speicher als Kopie vorhanden ist. Man spricht in diesem Zusammenhang auch von "persistenter" Grafik/Bitmap. Ist AutoRedraw auf False, dann werden Grafikoperationen nur im Vordergrund ausgeführt, die persistente Bitmap bleibt unverändert.

Um das etwas zu veranschaulichen, wollen wir unser Übungsprogramm mal etwas abwandeln. Wir entfernen picTafel und lblBegruessung und malen/schreiben stattdessen eine Tafel (nicht ganz so schön) direkt auf die Form:

     Private Sub Form_Activate()
        AutoRedraw = True
        Rand = 500           'Abstand vom linken bzw. oberen Rand
        Line (Rand, Rand)-(Me.ScaleWidth - Rand, Me.ScaleHeight - Rand), RGB(150, 100, 0), BF
        'malt ein hellbraunes Rechteck auf die Form
        Rand = Rand + 400    'Abstand vom Rand vergrößern für schwarzes Rechteck
        Line (Rand, Rand)-(Me.ScaleWidth - Rand, Me.ScaleHeight - Rand), RGB(0, 0, 0), BF
        'malt ein schwarzes Rechteck auf die Form

        AutoRedraw = False   'AutoRedraw zurücksetzen
        CurrentX = 1500      'positioniert den nachfolgenden Printbefehl X-Achse
        CurrentY = 2000      'positioniert den nachfolgenden Printbefehl Y-Achse
        Print "Viel Spaß mit Mathe-Max!"  'druckt Text direkt auf die Form
        Verzoegerung 2

        MsgBox "Bitte suche eine Übung aus!", vbExclamation
        Cls                  'Begrüßungstext löschen
     End Sub
     

Beispielprojekt laden

Was passiert?

Zunächst ist AutoRedraw auf True. Alle folgenden Grafikmethoden (das Zeichnen der konzentrischen Rechtecke) werden auch im Hintergrund im Speicher ausgeführt. Dann wird AutoRedraw auf False geschaltet, das Schreiben des Begrüßungstextes wird im Speicher nicht nachvollzogen. Gleichzeitig wird der bisherige Zustand der Form unabänderbar im Speicher festgehalten. Ein anschließendes Cls löscht nur den Text, nicht die Rechtecke.

Ihr könnt den Effekt auch studieren, wenn Ihr, während Text und Tafel angezeigt werden, eine andere Form (z.B. ein Explorerfenster) ganz oder teilweise davor schiebt und wieder wegnehmt. Der Text wird nicht aufgefrischt, da er im Speicher nicht mitgeschrieben wurde.

Ihr könnt Euch sicher denken, daß das Mitschreiben im Speicher mehr Resourcen benötigt als ohne. Man sollte AutoRedraw daher nicht bedenkenlos auf True setzen, weil es bequemer ist, sondern nur dann, wenn es auch notwendig ist oder evtl. nach einer Ausweichmöglichkeit suchen. Wir probieren eine solche Alternative mal für unser Beispiel aus:

Wir nehmen das Malen der Tafel aus dem Activate-Ereignis raus und versuchen es stattdessen mit dem Form_Paint-Ereignis. Das Paint-Ereignis wird immer dann ausgelöst, wenn eine Form neu gemalt werden muß, z.B. wenn sie durch ein anderes Fenster verdeckt wurde.

     Private Sub Form_Activate()
        AutoRedraw = False
        CurrentX = 1500      'positioniert den nachfolgenden Printbefehl X-Achse
        CurrentY = 2000      'positioniert den nachfolgenden Printbefehl Y-Achse
        Print "Viel Spaß mit Mathe-Max!"  'druckt Text direkt auf die Form
        Verzoegerung 2

        MsgBox "Bitte suche eine Übung aus!", vbExclamation
        Cls
     End Sub

     Private Sub Form_Paint()
        Rand = 500                      'Tafel malen
        Line (Rand, Rand)-(Me.ScaleWidth - Rand, Me.ScaleHeight - Rand), RGB(150, 100, 0), BF
        Rand = Rand + 400
        Line (Rand, Rand)-(Me.ScaleWidth - Rand, Me.ScaleHeight - Rand), RGB(0, 0, 0), BF
     End Sub
     

Beispielprojekt laden

Wenn Ihr das Beispiel jetzt ausprobiert, könnt Ihr noch einen anderen Effekt feststellen: Wenn Ihr die Form mit der Maus vergrößert, wird auch die Tafel neu an die Größe angepaßt, d.h. auch dann tritt das Paint-Ereignis ein, weil der neu hinzukommende Teil der Form gemalt werden muß!

Anders ist es beim Verkleinern der Form, hier wird kein Paint-Ereignis ausgelöst, die Tafel nicht neu gemalt. Außerdem wird beim Cls-Befehl auch die Tafel gelöscht, denn sie wurde nicht im Speicher mitgezeichnet, da von Anfang an AutoRedraw auf False war. Und was auch nicht gerade zur Verbesserung beiträgt: Die Tafel wird jedes Mal neu gezeichnet, wenn die Kugeln angezeigt werden, denn auch da tritt ein Paint-Ereignis eingeleitet. Die Folfe ist ein Flackern.

Wenn es uns wichtig ist, daß die Form auch vergrößert werden kann, dann ist es besser anstelle des Paint- das Resize-Ereignis zu nutzen. Es tritt immer dann ein, wenn die Form in ihrer Größe verändert wird, übrigens auch beim Vergößern aus Icon-Größe.

Wir probieren auch diese Methode einmal aus:

     Private Sub Form_Resize()
        AutoRedraw = True
        Rand = 0                        'Hintergrund übermalen
        Line (Rand, Rand)-(Me.ScaleWidth - Rand, Me.ScaleHeight - Rand), Me.BackColor, BF
        Rand = 500                      'Tafel malen
        Line (Rand, Rand)-(Me.ScaleWidth - Rand, Me.ScaleHeight - Rand), RGB(150, 100, 0), BF
        Rand = Rand + 400
        Line (Rand, Rand)-(Me.ScaleWidth - Rand, Me.ScaleHeight - Rand), RGB(0, 0, 0), BF
        AutoRedraw = False
     End Sub
     

Damit die Tafel in ihrer vorherigen Größe gelöscht wird und keine Reste übrig bleiben, habe ich hier zu Beginn noch ein randloses Rechteck in Farbe und Größe der Form gemalt. Jetzt sieht das Ganze schon besser aus: Die Tafel hat immer die richtige Größe, es tritt kein Flackern beim Neuzeichnen der Kugeln auf (außer beim Ändern der Größe) und wir haben dennoch nur wenige Resourcen verbraucht, weil wir AutoRedraw nur im Bedarfsfall auf True gesetzt haben.

Beispielprojekt laden

Hinweis: Die AutoRedraw-Eigenschaft ist sowohl bei Formen als auch bei PictureBoxen verfügbar. Wir können uns dies zunutze machen, wenn wir in einem Programm Teilbereiche ständig im Speicher mitzeichnen möchten, ohne gleich die ganze Form auf AutoRedraw setzen zu müssen und können dann solche Grafikmethoden nur in einer PictureBox ausführen lassen.

Jetzt bleibt aus unserem Projekt 20 nur noch eine Frage zu klären: Was hat es mit der "Image"-Eigenschaft auf sich?

Es handelt sich hierbei um nichts anderes als das Abbild, das im Speicher mitgeführt wird und wir können bei einer Form oder einer PictureBox zur Laufzeit darauf zugreifen. In unserem Fall hat das den Effekt, daß die transparenten Ecken unseres (unsichtbaren) Picture-Controls auch im Speicher-Abbild richtig nachvollzogen werden und sie werden dann mit der PaintPicture-Methode korrekt übertragen. Eigentlich ganz einfach, wenn man's weiß.

Da die Originalgrafik mit den abgerundeten Ecken doch etwas besser aussieht, kehren wir jetzt zu unserem Projekt 20 zurück und wenden dort unser frisch erworbenes Wissen an, um auch dort noch ein paar Resourcen zu sparen. Wir verzichten auf das Begrüßungslabel und schreiben den Text direkt auf die Tafel, die wir durch Toggeln der AutoRedraw-Eigenschaft "wischfest" machen. Wir bleiben beim Active-Ereignis, da wir auf eine Größenanapssung in unserem Projekt verzichten wollen.

     Private Sub Form_Activate()
        AutoRedraw = True
        Me.PaintPicture picTafel.Image, (Me.ScaleWidth - picTafel.Width) \ 2, (Me.ScaleHeight - picTafel.Height) \ 2
        AutoRedraw = False

        CurrentX = 1500      'positioniert den nachfolgenden Printbefehl X-Achse
        CurrentY = 2000      'positioniert den nachfolgenden Printbefehl Y-Achse
        Print "Viel Spaß mit Mathe-Max!"  'druckt Text direkt auf die Form

        Verzoegerung 2
        MsgBox "Bitte suche eine Übung aus!", vbExclamation
        Cls
     End Sub
     

Beispielprojekt laden

zurück Index weiter


© Copyright 1998-2000 J.Behling EMail schreiben ABC-Ware's Homepage
Weitergabe und Druck (auch in Teilen, mit Ausnahme von Privatgebrauch) ohne ausdrückliche Genehmigung der Autorin untersagt.