Die Community zu .NET und Classic VB.
Menü

Credit-Scroller

 von 

Übersicht 

Dieser kurze Artikel zeigt die Grundlagen um einen sicherlich noch ausbaufähigen, flackerfreien Credit-Scroller zu erstellen, der jedem Programm vorgestellt werden kann.

Mit freundlichen Grüßen
Herfried K. Wagner,

Beschreibung  

Microsoft Visual Basic bietet keine guten Möglichkeiten, Text bzw. Grafik zu scrollen [Animation]. Es wäre denkbar, ein Label-Steuerelement mit transparentem Hintergrund, das den zu scrollenden Text enthält, mit einem Timer über eine Hintergrundgrafik zu bewegen, allerdings tritt bei dieser Methode ein unschönes Flackern des Label-Steuerelements auf. Derselbe Effekt ist auch bei der Verwendung des Image-Steuerelement zu bemerken, das eine transparente Grafik beinhaltet. Daher muss man eine Lösung über die Win32 API [Application Programming Interface]-Schnittstelle suchen. Eine gute Möglichkeit bieten die Funktionen aus der GDI-Schnittstelle des Systems. Diese API-Funktionen sind unter 32-Bit Windows in der gdi32.dll implementiert, seit Windows 98 bzw. Windows 2000 stellt das System auch die msimg32.dll zur Verfügung, die als Ergänzung zur gdi32.dll gedacht ist.


Abbildung 1

So war es beispielsweise mit GDI API-Funktionen nur schwer möglich, transparente Grafiken auf einen Device Context zu blitten. Dazu wird von der msimg32.dll die Funktion TransparentBlt zur Verfügung gestellt, weiters finden sich in dieser Dynamic Link Library z.B. auch eine Funktion zum Zeichnen von Farbverläufen [Gradients] und zum Überblenden zweier DCs [Fading].

TransparentBlt  

Wie oben beschrieben, wäre es möglich, die TransparentBlt API-Funktion aus der msimg32.dll zu verwenden, um den transparenten Text in einer Grafik über den Hintergrund zu blitten. Problem dabei ist, dass diese Funktion nur auf neueren Betriebssystemversionen vorhanden ist und daher separater Code für frühere Versionen geschrieben werden müsste (inklusive eines Versions-Checks), man könnte aber auch die msimg32.dll mit seiner Anwendung ausliefern, was aber aus lizenzrechtlichen Gründen problematisch ist (Copyright). Deshalb wird in diesem Beispiel eine erweiterte Implementierung der BitBlt API-Funktion verwendet, die TransBlt benannt wurde. Diese Prozedur maskiert die Vordergrundbitmap in einem Memory-DC (Ein DC, der nicht angezeigt wird, sondern nur im Arbeitsspeicher angelegt wird, um eine Bitmap zu speichern bzw. Grafikoperationen auf diesen DC anzuwenden. Wenn Grafikoperationen auf einen Memory DC angewendet werden, sind diese viel schneller als wenn sie auf einen sichtbaren DC angewendet werden würden.) und erstellt dann eine transparente Bitmap, die anschliessend über den Ziel-DC geblittet wird. Damit diese Funktion (wie auch die anderen BitBlt-Funktionen) funktionieren, muss die ScaleMode-Eigenschaft von Quell- und Zielobjekt auf vbPixels eingestellt werden und die Autoredraw-Eigenschaft auf True gesetzt werden.

Public Sub TransBlt(ByVal hDestDC As Long, _
                    ByVal x As Long, _
                    ByVal y As Long, _
                    ByVal nWidth As Long, _
                    ByVal nHeight As Long, _
                    ByVal hSrcDC As Long, _
                    ByVal xSrc As Long, _
                    ByVal ySrc As Long, _
                    ByVal lngTransColor As Long)

Listing 1

Wie aus den Parametern der TransBlt-Prozedur erkennbar ist, unterscheidet sich dieses Sub von der TransparentBlt API-Funktion nur dadurch, dass die Weite und Höhe auf dem Quell-DC nicht angegeben werden muss. Da es sich um ein Sub handelt, wird auch kein Wert zurückgegeben, der über den Erfolg des Funktionsaufrufs Aufschluss gibt. Es muss kein Timer-Steuerement als Zeitgeber verwendet werden, da die TransBlt-Prozedur das System kurzzeitig "blockiert" und dadurch die Anzeige verzögert. Ausserdem wird bei jedem Schleifendurchlauf DoEvents aufgerufen, damit auch andere Systemprozesse ablaufen können. Deklaration der TransparentBlt API-Funktion:

Private Declare Function TransparentBlt Lib "msimg32" ( _
    ByVal hdcDest As Long, _
    ByVal nXOriginDest As Long, _
    ByVal nYOriginDest As Long, _
    ByVal nWidthDest As Long, _
    ByVal nHeightDest As Long, _
    ByVal hdcSrc As Long, _
    ByVal nXOriginSrc As Long, _
    ByVal nYOriginSrc As Long, _
    ByVal nWidthSrc As Long, _
    ByVal nHeightSrc As Long, _
    ByVal crTransparent As Long) As Long

Listing 2

Algorithmus  

Im hier beschriebenen Beispiel wird ein Text mit Grafikelementen transparent über eine Hintergrundgrafik bewegt. Die Hintergrundgrafik stellt einen Sternenhimmel dar, beim "Text" handelt es sich um Informationen zu einer Anwendung [Credits]. Der Text ist als Bitmap abgelegt, damit auch Grafikelemente angezeigt werden können.

Bevor der transparente Vordergrund geblittet wird, wird der Inhalt der Ziel-PictureBox geleert und ein neuer Hintergrund geblittet. Dies ist einerseits notwendig, um die bereits vorhandene Anzeige zu löschen, andererseits wird in diesem Beispiel alle 40 Schleifendurchläufe [d.h., wenn die Vertikalposition auf der Quellbitmap um 40 Pixel nach unten verschoben wurde] das Hintergrundbild gewechselt, wodurch die Sterne am Himmel "flackern".


Abbildung 2


Abbildung 3

Folgende Grafiken zeigen das Anzeigeresultat zu den in der Skizze beschriebenen Zuständen, die Grafik am Seitenanfang zeigt den Zustand 1.

Folgende Grafik beschreibt den verwendeten Algorithmus. Im Zustand 1 wird der Teil der Grafik von der Vertikalposition 0 bis 0 + die Höhe des Zielbereichs transparent auf den Device Context der Ziel-PictureBox geblittet. Die Vertikalposition wird entlang des blauen Pfeils bei jedem Schleifendurchlauf inkrementiert, wodurch der aktuell geblittete Bereich auf der Quellbitmap nach unten wandert [Zustand 2]. Wird die Vertikalposition + der Höhe des Zielbereichs grösser als die Höhe des Quellbereichs, so muss zuerst der Bereich von der aktuellen Vertikalposition mit der Höhe, die sich aus der Gesamthöhe der Quellbitmap - die aktuelle Vertikalposition ergibt geblittet werden und anschliessend der Bereich von der Vertikalposition 0 bis mit der Höhe [aktuelle Position + Höhe des Zielbereichs - die Gesamthöhe der Quellbitmap] auf dem Zielobjekt an der Vertikalposition, die der Höhe des Bereichs, der zuerst geblittet wurde, entspricht [Zustand 3]. Durch diesen Algorithmus wird nach dem Abspielen der gesamten Quellbitmap erneut die Quellbitmap abgespielt, was einem schleifenartigen Durchlauf gleicht.


Abbildung 4: Anzeige im Stadium 2


Abbildung 5: Anzeige im Stadium 3

Beispiel als Download [29000 Bytes]

Ihre Meinung  

Falls Sie Fragen zu diesem Tutorial 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.