Gleisbild zeichnen
Bei kleinen, übersichtlichen
Anlagen kann man vielleicht auf ein Gleisbild (Gb.)
verzichten.
Gibt es aber auf der Anlage Schattenbahnhöfe, verdeckte
Streckenführungen o.ä. ist ein Gb. die optimale Lösung für
die Anzeige des
jeweiligen Streckenzustandes.
Die meisten der kommerziellen Programme für die Digitalsteuerung
bieten deshalb auch die Möglichkeit, ein Gb. zu erstellen.
Oftmals werden die Gleisstrecken dabei aus verschiedenen Modulen
wie in einem Baukasten zusammengestellt. Da jede Anlage
eine andere Streckenführung hat, ist dies der einzig gangbare
Weg.
Dieses System hat jedoch den Nachteil, daß man auf das starre
Raster der einzelnen Module festgelegt ist.
Spezielle Probleme, wie z.B. Streckenkreuzungen auf
unterschiedlichem Niveau lassen sich oftmals überhaupt nicht
darstellen.
Wesentlich flexibler ist man, wenn
man sich das Gleisbild selber zeichnet.
Dazu ist kein besonderes Zeichenprogramm erforderlich, das bei
jedem Windows mitgelieferte Paint® reicht völlig aus.
Damit können wir u.a. die Stellung von Weichen oder die Belegung
von Gleisstrecken optisch signalisieren.
Das folgende einfache Gb. soll uns als Übungsvorlage dienen:
Bild 1 Um ein Gleisbild in Visual
Basic anzeigen zu können, brauchen wir das Picture-Steuerelement
(PictureBox).
Im Gegensatz zum Image-Steuerelement
bildet die PictureBox einen Container.
Das heißt u.a., wenn wir die PictureBox an eine andere
Position bringen, verschieben sich auch alle darin
vorhandenen Tasten, Bilder usw. automatisch mit.
Um zur Laufzeit des Programms die
Weiche zu schalten, senden wir nicht nur den betreffenden Befehl
(33 oder 34) an das Interface,
sondern
machen zusätzlich das Image sichtbar oder unsichtbar (Weiche.Visible
= True / False) .
Wenn es sichtbar (Weiche.Visible = True) ist,
verdeckt es die Weiche auf der PictureBox.
Bei (Weiche.Visible = False) sehen wir die
Original-Zeichnung der PictureBox.
________________________________
Wenn nun ein Zug in ein Gleis
eingefahren ist, wie können wir dieses dann als belegt markieren ?
Die Information werden wir wohl meist über ein Rückmeldemodul
erhalten, aber auch eine manuelle Markierung des
Streckenbereichs wäre denkbar.
Die einfachste Methode ist das
Markieren der Gleistrecke in einer anderen Farbe.
In unserem Beispiel ist Gleis 1 frei und Gleis 2
belegt.
Gleis 1 soll als belegt gekennzeichnet werden.
Wir könnten, - wie bei der Weiche -, ein Image darüberlegen und
dieses sichtbar
oder unsichtbar schalten. Ein sehr umständlicher Weg, vor allem,
wenn wir viele Strecken ändern oder überwachen wollen.
Einfacher ist es, wenn wir die
Farbe gleich in der PictureBox von grün nach rot ändern.
Visual Basic selbst kann diese Arbeit nicht ausführen, aber es
gibt in Windows ein sogenanntes API (Application
Programming Interface).
In diesem API sind viele verschiedene Funktionen verfügbar,
welche von jedem Programm benutzt werden können.
Wir brauchen die Funktion: FloodFill.
FloodFill funktioniert wie das Werkzeug 'Fläche ausfüllen ' in Paint bzw. anderen Zeichenprogrammen.
In Paint heißt das Werkzeug 'Farbfüller'.
Um die Funktion in Visual Basic
benutzen zu können, müssen wir sie in einem Modul (Modul.bas)
deklarieren.
Die Deklaration lautet:
Public Declare Function FloodFill Lib "gdi32" Alias "FloodFill" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long |
Wie jede Funktion liefert auch FloodFill einen Wert zurück. Wir brauchen ihn nicht und weisen ihn einer
Dummy-Variablen zu.
btnTest |
Private
Sub btnTest_Click() Dim Dummy as Variant ... ... End Sub |
Damit die Funktion arbeiten kann, braucht sie 4 Werte:
hdc | Handle der PictureBox (handle ist ein vom Betriebssystem an die PictureBox vergebener einmaliger ganzzahliger Wert) |
X | waagerechte Position |
Y | senkrechte Position |
crColor | Farbe, welche den Rand der einzufärbenden Fläche bildet |
Ich muß zugeben, das sieht alles ziemlich kompliziert aus. Ist es aber wirklich nicht.
Am schlimmsten erscheint die Sache
mit dem handle (hdc).
Die Funktion braucht die genaue Bezeichnung des Steuerelementes,
in welchem die Änderung durchgeführt werden soll.
Das betreffende Steuerelement ' weiß' natürlich seinen Handle:
in der Eigenschaft .hdc könnten wir ihn
auslesen.
Einfacher ist jedoch die indirekte Adressierung.
Der erste Teil des Funktions-Aufrufs lautet damit:
btnTest |
Private
Sub btnTest_Click() Dim Dummy as Variant ... Dummy = FloodFill(Gleisbild.hdc, .... ) End Sub |
Als weiteres braucht FloodFill die
Position, an der die Änderung beginnen soll.
Um die Koordinaten X und Y zu
ermitteln, brauchen wir lediglich 1 Zeile Code:
Gleisbild |
Private
Sub Gleisbild_MouseDown(Button As Integer, Shift As
Integer, X As Single, Y As Single) MsgBox "X = " & Str(X) & ", Y =" & Str(Y) End Sub |
Wenn wir zur Laufzeit des
Programms mit der Maus auf die grüne Fläche von Gleis 1
zeigen, erscheint nach dem Mausklick eine MsgBox
mit den Werten von X und Y.
Beispiel: X = 196, Y = 12 .
Bei unserem Gleisbild liegt der Wert von X
zwischen 120 und 220 und Y zwischen 11 und 13.
Wir erweitern unseren Funktions-Aufruf um X und Y:
btnTest |
Private
Sub btnTest_Click() Dim Dummy as Variant ... Dummy = FloodFill(Gleisbild.hdc, 196,12 .... ) End Sub |
Zum Schluß muß FloodFill
noch wissen, wie weit die 'Farbe fließen' darf oder, anders
ausgedrückt, an welcher Farbe haltgemacht
werden soll.
Wir haben die Strecke schwarz umrandet.
Folglich lautet die komplette Zeile zum Aufruf von FloodFill:
btnTest |
Private
Sub btnTest_Click() Dim Dummy as Variant ... Dummy = FloodFill(Gleisbild.hdc, 196,12, vbBlack) End Sub |
Aber noch wird FloodFill
nicht zufriedenstellend arbeiten, denn bisher haben wir dem
Programm wir noch nicht gesagt,
welche Farbe wir einsetzen wollen. Die Auswahl treffen wir mit
der PictureBox-Eigenschaft FillColor.
btnTest |
Private
Sub btnTest_Click() Dim Dummy as Variant Gleisbild.FillColor = vbRed Dummy = FloodFill(Gleisbild.hdc, 196,12, vbBlack) End Sub |
Nun endlich sollte es klappen: Gleis 1 wechselt von grün nach rot.
Um wieder auf grün zurückzuschalten
installieren wir eine weitere Taste mit Name btnTest2.
Sie erhält folgende Code:
btnTest2 |
Private
Sub btnTest_Click() Dim Dummy as Variant Gleisbild.FillColor = vbGreen Dummy = FloodFill(Gleisbild.hdc, 196,12, vbBlack) End Sub |
Hinweis:
Der Rand, bis zu welchem die Farbe fließen soll, muß absolut dicht
sein, wenn nur ein einziges Pixel fehlt,
füllt die Farbe ggf. die gesamte PictureBox aus.
Tip:
Wer nicht sicher ist, ob die Koordinaten X und Y
korrekt sind, kann sich mit der folgenden Methode helfen:
Gleisbild.Pset(196,12), vbBlack |
Visual Basic zeichnet dann an die
angegebene Position einen winzigen schwarzen Punkt.
Man sollte dabei jedoch beachten, daß dieser Punkt auch mal im (schwarzen)
Rand der Gleisstrecke landen kann
(und unsichtbar bleibt), in solchen Fällen sollte man mit einer
anderen Farbe arbeiten.