|
Mit der API-Funktion FloodFill
können Sie den Bereich innerhalb einer geschlossenen Linienfigur
mit einer Farbe oder einem Muster füllen. Sie geben zum einen den
Ausgangspunkt (Koordinaten in Pixels) an, der innerhalb dieser
Linienfigur liegen muss. Zum anderen legen Sie die Farbe fest, die
die Begrenzung darstellen soll - und nicht etwa die Füllfarbe, wie
man auf den ersten Blick auf die Deklaration der Funktion meinen
könnte.
Vielleicht haben Sie ja schon einmal mit dieser API-Funktion
experimentiert und sich gewundert, warum diese Funktion nicht
funktionieren will, obwohl die zu übergebenden Parameter auf den
ersten Blick so einleuchtend erscheinen. Neben der Angabe der
Füllfarbe scheint auch noch die Möglichkeit zu fehlen, das
Füllmuster festzulegen.
Private Declare Function FloodFill Lib "gdi32" _
(ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, _
ByVal crColor As Long) As Long
Doch wie erfährt nun die Funktion mit welcher Farbe und mit
welchem Füllmuster der Bereich gefüllt werden soll? Sie haben es
bei den grafischen Funktion des API mit einer Denkweise zu tun, die
sich ziemlich von der gewohnten Weise unterscheidet, wie Sie in
Visual Basic Aufgaben zu lösen gewohnt sind. Stellen Sie sich
einfach eine Aufgabenteilung vor, wenn Sie es mit grafischen
API-Funktionen zu tun haben, die meistens in der Bibliothek (Lib)
"gdi32" enthalten sind.
Hier gibt es eine Zeichenfläche, den so genannten
"Gerätekontext" ( Device
Context) - Sie begegnen ihm und verwenden ihn als
"Handle". Ein Handle (manchmal auch Bezug oder
Bezugsnummer genannt) ähnelt in gewisser Weise einer
Objekt-Referenz - es ist eine Zahl, die von Windows intern
festgelegt wird. Der Wert eines Handles spielt keine Rolle, und
rechnen können Sie damit auch nicht. Über irgendeinen
API-Funktionsaufruf bekommen Sie solch ein Handle zur weiteren
Verwendung von Windows mitgeteilt.
Weiterhin gibt es (fast) immer irgend ein Objekt, mit dem etwas
gemacht werden soll. Verwechseln Sie den Begriff in diesem
Zusammenhang nicht mit den Objekten und Objekt-Referenzen, wie Sie
sie von Visual Basic her kennen. Auch hier handelt es sich wieder
nur um Handles, die Sie mit Hilfe von API-Funktionen erhalten. Damit
die Funktion FloodFill funktionieren kann, brauchen wir als ein
solches Objekt einen Pinsel (Brush), mit dem die
Windows-Grafikmaschine (das "GDI" - Graphic Device
Interface) als der eigentliche Akteur im Rahmen der
Aufgabenverteilung auf der Zeichenfläche malen kann.
Windows gehört zu der Gattung der Malermeister, die für die in
ihrem Handwerk Ordnung das halbe Leben ist. Daher werden mit
Vorliebe neue Pinsel verwendet, die erst einmal "erzeugt"
werden. Windows-Pinsel haben die Eigenart, dass in sie zum einen
beim Erzeugen gleich der Eimer mit der gewünschten Farbe eingebaut
wird und dass sie zum anderen auch Muster malen können - ganz nach
Ihren Wünschen. Mit den API-Funktionen CreateSolidBrush
(glatte Füllung) und CreateHatchBrush
(Musterfüllung) erzeugen Sie solche Pinsel - die Aufrufe dieser
Funktionen liefern ein Pinsel-Handle (Brush).
Mit der API-Funktion SelectObject
weisen Sie Windows an, diesen Pinsel in die Hand zu nehmen. Da ein
Windows-Malermeister allerdings keine leeren Hände kennt, sondern
aller Wahrscheinlichkeit nach bereits zuvor ein anderes Werkzeug in
der Hand hält, nehmen Sie ihm dieses im Gegenzug ab (Sie bekommen
es im Rückgabewert der Funktion SelectObject) und verstauen es
(dessen Handle) erst einmal in einer Variablen.
Nun können Sie (endlich) die Aufforderung zum Malen mit FloodFill
erteilen. Beachten Sie, dass die Angabe der Koordinaten des
Ausgangspunktes unbedingt in der Maßeinheit Pixels erfolgen muss.
Wie bereits erwähnt, ist der Windows-Malermeister ein
Ordnungsfanatiker. Unmittelbar nach getaner Arbeit erwartet er, dass
Sie ihm den Pinsel wieder aus der Hand nehmen und ihm sein
vorheriges Werkzeug wieder zurückgeben (Sie rufen die Funktion
SelectObject erneut auf). Da Sie den Pinsel jedoch bereits vorher
selbst erzeugt haben (d.h. das Brush-Handle ist bereits in einer
Variablen gespeichert), können Sie die Rückgabe (den Rückgabewert
der Funktion) ignorieren.
Damit ist der Ordnungsliebe aber noch nicht genug - Windows
erwartet, dass man einen erzeugten und benutzten Pinsel nicht
einfach in der Gegend herumliegen lässt, sondern ihn vor dem
Verlassen des Arbeitszimmers (der Prozedur) saubermacht. Windows
kann zwar genauso gut am Ende eines Arbeitstages (beim Beenden eines
Programms) die gebrauchten Werkzeuge saubermachen und aufräumen -
aber räumen Sie denn gerne anderer Leute Krempel auf? Stecken Sie
daher zum Schluss den Pinsel einfach in die Objekt-Waschmaschine
namens DeleteObject.
Die Funktion Fill verpackt die ganze Aktion für einen einzigen
Aufruf. Sie geben in deren Parametern das Objekt bzw. Steuerelement
an, das als Zeichenfläche dient, die Koordinaten des
Ausgangspunktes, die Füllfarbe und die Begrenzungsfarbe und den
gewünschten Musterstil. Achten Sie darauf, dass sich die Konstanten
der Musterstile von den verwandten Werten für die Eigenschaft
FillStyle etwa eines VB-Forms unterscheiden - hier verwenden Sie die
mit HS_ beginnenden Konstanten. Die übergebenen Farben müssen Sie
zuvor mittels der API-Funktion OleTranslateColor
in echte RGB-Farbwerte umwandeln, falls Sie Systemfarben-Konstanten
vorliegen haben sollten.
Private Declare Function CreateSolidBrush Lib "gdi32" _
(ByVal crColor As Long) As Long
Private Declare Function CreateHatchBrush Lib "gdi32" _
(ByVal nIndex As Long, ByVal crColor As Long) As Long
Private Declare Function SelectObject Lib "gdi32" _
(ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function FloodFill Lib "gdi32" _
(ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, _
ByVal crColor As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" _
(ByVal hObject As Long) As Long
Private Const HS_HORIZONTAL = 0
Private Const HS_VERTICAL = 1
Private Const HS_FDIAGONAL = 2
Private Const HS_BDIAGONAL = 3
Private Const HS_CROSS = 4
Private Const HS_DIAGCROSS = 5
Private Const HS_SOLID = 8
Public Sub Fill(Obj As Object, ByVal X As Long, ByVal Y As Long, _
ByVal FillColor As Long, ByVal BorderColor As Long, _
ByVal Brush As Long)
Dim nBrush As Long
Dim nOldBrush As Long
If Brush = HS_SOLID Then
nBrush = CreateSolidBrush(FillColor)
Else
nBrush = CreateHatchBrush(Brush, FillColor)
End If
nOldBrush = SelectObject(Obj.hdc, nBrush)
FloodFill Obj.hdc, X, Y, BorderColor
SelectObject Obj.hdc, nOldBrush
DeleteObject nBrush
End Sub
 |
Die Funktion Fill macht die Verwendung der
API-Funktion FloodFill weniger umständlich

|

|