|
|
|
|
|
Immer wieder beeindruckend sind die leuchtenden Farbverläufe im
Hintergrund von Setup-Programmen. Dabei ist das gar nicht so
schwierig nachzubilden, wenn Sie auch Ihre VB-Forms in
Farbverläufen glänzen lassen wollen.
Der Trick besteht darin, die innere Höhe des Forms in 256
Streifen zu teilen und von Streifen zu Streifen die gewünschte
Farbe dunkler bzw. heller werden zu lassen. Komplizierte Rechnereien
können sie sich sparen, wenn Sie die Eigenschaft ScaleHeight
einfach auf 256 setzen. Visual Basic berechnet die tatsächliche
Streifenhöhe von zwei vorgewählten Einheiten (dies, damit keine
Lücken entstehen) automatisch selbst:
For i = 0 To 255
Form.Line (0, i)-(Form.ScaleWidth, i - 1), _
RGB(0, 0, 255 - i), B
Next 'i
Zuvor werden die Eigenschaften DrawStyle auf vbInsideSolid und
DrawMode auf vbCopyPen gesetzt. Wenn Sie nichts außer dem
Farbverlauf auf das Form zeichnen möchten, können Sie diese
Einstellungen fix einstellen - das Füllen des Farbverlaufs
geschieht dann wesentlich schneller (ist aber auch so schnell
genug). Anderenfalls sollten Sie die betroffenen Eigenschaften des
Forms vor jedem Füllvorgang sichern und anschließend gleich wieder
restaurieren (siehe Listing). Dann brauchen Sie sich an keiner
anderen Stelle Ihres Programms darum zu kümmern, welche
Einstellungen wann und wo zuletzt verwendet wurden.
Damit die Farbverlauf-Prozedur universell verwendbar wird,
verlagern wir sie am besten in ein Standardmodul, das von jedem Form
aus aufgerufen werden kann. Damit Sie Verläufe auch in anderen
Farben als Blau erhalten können, übergeben Sie der Prozedur neben
der Referenz auf das Form eine Konstante, die die gewünschte Farbe
angibt. Der Einfachheit halber habe ich hierzu die
VB-Standard-Farbkonstanten zweckentfremdet - sie lassen sich einfach
gut merken: vbWhite, vbRed, vbBlue, vbGreen, vbCyan, vbMagenta und
vbYellow. Die Werte dieser Konstanten werden lediglich zum
Verzweigen in die jeweilige Schleife benötigt - dort wird der
gewünschte Farbwert mit Hilfe der RGB-Funktion für jeden
Schleifendurchlauf ermittelt.
Setzen Sie den zusätzlichen optionalen Parameter BottomUp gleich
True, wird der Farbverlauf in umgekehrter Richtung, also von Schwarz
oben bis zur vollen Farbe unten gefüllt. Lassen Sie den Parameter
einfach weg, ist das genauso gut, als ob Sie ihn gleich False
gesetzt hätten.
Einen kleinen weiteren Trick müssen wir noch anwenden, damit der
Farbverlauf immer neu gezeichnet wird, wenn sich die Größe des
Forms ändert. Das Paint-Ereignis wird von VB nämlich nur dann
ausgelöst, wenn die Breite und/oder die Höhe des Forms
vergrößert wird - beim Verkleinern geht VB bzw. Windows
standardmäßig davon aus, dass nichts zu tun wäre, da ja der zuvor
sichtbare Inhalt lediglich beschnitten wird. Damit unser Farbverlauf
jedoch immer den sichtbaren Bereich genau ausfüllen kann, muss im
Resize-Ereignis des Forms geprüft werden, ob es in der Richtung des
Farbverlaufs kleiner geworden ist.
Diese Prüfung und ein gegebenenfalls notwendiges Neuzeichnen des
Farbverlaufs macht nur dann Sinn, wenn das Form nicht als Icon
abgelegt ist. Ist die Eigenschaft WindowState ungleich vbMinimized,
wird der Inhalt der statischen Variablen sLastHeight (beim ersten
Mal sowieso noch Null) mit der aktuellen Höhe des Forms verglichen.
Ist sie größer, wird Prozedur FormGradient aufgerufen und die
aktuelle Höhe in sLastHeight für den Vergleich beim nächsten
Auftreten des Ereignisses festgehalten.
Vertauschen Sie die Orientierung der Füllung, können Sie
selbstverständlich auch horizontale Farbverläufe erhalten. Die
hierfür notwendige Erweiterung bzw. Umkehrung der Prozedur
FormGradient überlasse ich Ihnen jedoch selbst.
Public Sub FormGradient(iForm As Form, _
Optional ByVal iColor As Long, _
Optional ByVal iBottomUp As Boolean)
Dim i As Integer
Dim nScaleWidth As Single
Dim nOldDrawStyle As Integer
Dim nOldDrawMode As Integer
Dim nOldDrawWidth As Integer
Dim nOldScaleMode As Integer
Dim nOldScaleHeight As Single
Select Case iColor
Case vbBlue, vbRed, vbGreen, vbCyan, vbMagenta, _
vbYellow, vbWhite
With iForm
nOldDrawStyle = .DrawStyle
nOldDrawMode = .DrawMode
nOldDrawWidth = .DrawWidth
nOldScaleMode = .ScaleMode
nOldScaleHeight = .ScaleHeight
.DrawStyle = vbInsideSolid
.DrawMode = vbCopyPen
.DrawWidth = 2
.ScaleHeight = 256
nScaleWidth = .ScaleWidth
If iBottomUp Then
Select Case iColor
Case vbRed
For i = 0 To 255
iForm.Line (0, 255 - i)-(nScaleWidth, 256 - i), _
RGB(255 - i, 0, 0), B
Next 'i
Case vbGreen
For i = 0 To 255
iForm.Line (0, 255 - i)-(nScaleWidth, 256 - i), _
RGB(0, 255 - i, 0), B
Next 'i
Case vbBlue
For i = 0 To 255
iForm.Line (0, 255 - i)-(nScaleWidth, 256 - i), _
RGB(0, 0, 255 - i), B
Next 'i
Case vbYellow
For i = 0 To 255
iForm.Line (0, 255 - i)-(nScaleWidth, 256 - i), _
RGB(255 - i, 255 - i, 0), B
Next 'i
Case vbCyan
For i = 0 To 255
iForm.Line (0, 255 - i)-(nScaleWidth, 256 - i), _
RGB(0, 255 - i, 255 - i), B
Next 'i
Case vbMagenta
For i = 0 To 255
iForm.Line (0, 255 - i)-(nScaleWidth, 256 - i), _
RGB(255 - i, 0, 255 - i), B
Next 'i
Case vbWhite
For i = 0 To 255
iForm.Line (0, 255 - i)-(nScaleWidth, 256 - i), _
RGB(255 - i, 255 - i, 255 - i), B
Next 'i
End Select
Else
Select Case iColor
Case vbRed
For i = 0 To 255
iForm.Line (0, i)-(nScaleWidth, i - 1), _
RGB(255 - i, 0, 0), B
Next 'i
Case vbGreen
For i = 0 To 255
iForm.Line (0, i)-(nScaleWidth, i - 1), _
RGB(0, 255 - i, 0), B
Next 'i
Case vbBlue
For i = 0 To 255
iForm.Line (0, i)-(nScaleWidth, i - 1), _
RGB(0, 0, 255 - i), B
Next 'i
Case vbYellow
For i = 0 To 255
iForm.Line (0, i)-(nScaleWidth, i - 1), _
RGB(255 - i, 255 - i, 0), B
Next 'i
Case vbCyan
For i = 0 To 255
iForm.Line (0, i)-(nScaleWidth, i - 1), _
RGB(0, 255 - i, 255 - i), B
Next 'i
Case vbMagenta
For i = 0 To 255
iForm.Line (0, i)-(nScaleWidth, i - 1), _
RGB(255 - i, 0, 255 - i), B
Next 'i
Case vbWhite
For i = 0 To 255
iForm.Line (0, i)-(nScaleWidth, i - 1), _
RGB(255 - i, 255 - i, 255 - i), B
Next 'i
End Select
End If
If nOldScaleMode = vbUser Then
.ScaleMode = vbUser
.ScaleHeight = nOldScaleHeight
Else
.ScaleMode = nOldScaleMode
End If
.DrawWidth = nOldDrawWidth
.DrawMode = nOldDrawMode
.DrawStyle = nOldDrawStyle
End With
End Select
End Sub
 |
Das Modul modGradient mit der universell
verwendbaren Prozedur FormGradient

|
Der Code für das oben abgebildete Beispiel sieht so aus:
Private mGradientColor As Long
Private Sub chkBottomUp_Click()
FormGradient Me, mGradientColor, _
CBool(chkBottomUp.Value)
End Sub
Private Sub Form_Load()
With lstColors
.AddItem "Weiß"
.ItemData(.NewIndex) = vbWhite
.AddItem "Gelb"
.ItemData(.NewIndex) = vbYellow
.AddItem "Cyan"
.ItemData(.NewIndex) = vbCyan
.AddItem "Magenta"
.ItemData(.NewIndex) = vbMagenta
.AddItem "Blau"
.ItemData(.NewIndex) = vbBlue
.AddItem "Rot"
.ItemData(.NewIndex) = vbRed
.AddItem "Grün"
.ItemData(.NewIndex) = vbGreen
.ListIndex = 4
End With
End Sub
Private Sub Form_Paint()
FormGradient Me, mGradientColor, _
CBool(chkBottomUp.Value)
End Sub
Private Sub Form_Resize()
Static sLastHeight As Single
With Me
If .WindowState <> vbMinimized Then
If sLastHeight > .Height Then
FormGradient Me, mGradientColor, _
CBool(chkBottomUp.Value)
sLastHeight = .Height
End If
End If
End With
End Sub
Private Sub lstColors_Click()
With lstColors
mGradientColor = .ItemData(.ListIndex)
FormGradient Me, mGradientColor, _
CBool(chkBottomUp.Value)
End With
End Sub
 |
Code des Test-Beispiels mit der Anpassung im
Resize-Ereignis

|

|
|
|