Sandini Bib
Visual Basic 6 lernen
Sandini Bib
Sandini Bib
Dirk Abels
Visual Basic 6 lernen Anfangen, anwenden, ve...
110 downloads
1544 Views
4MB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
Sandini Bib
Visual Basic 6 lernen
Sandini Bib
Sandini Bib
Dirk Abels
Visual Basic 6 lernen Anfangen, anwenden, verstehen
An imprint of Addison Wesley Longman, Inc. Bonn • Reading, Massachusetts • Menlo Park, California New York • Harlow, England • Don Mills, Ontario Sydney • Mexico City • Madrid • Amsterdam
Sandini Bib
Die Deutsche Bibliothek – CIP-Einheitsaufnahme Dirk Abels Visual Basic 6 lernen / Dirk Abels. - 1 Aufl. Bonn ; Reading, Mass. [u.a.] : Addison-Wesley-Longman, 1999 ISBN 3-8273-1371-6
© 1999 Addison Wesley Longman GmbH 1. Auflage 1999 Satz: mediaService, Siegen. Gesetzt aus der Stone Serif 9,5 pt. Belichtung, Druck und Bindung: Bercker Grafische Betriebe, Kavelaer Lektorat: Tomas Wehren, Judith Stevens Korrektorat: Boris Karnikowski, Münster Produktion: Petra Strauch, Bonn Umschlaggestaltung: Barbara Thoben, Köln Illustrationen: Elisabeth Herzel, Hamburg Das verwendete Papier ist aus chlorfrei gebleichten Rohstoffen hergestellt und alterungsbeständig. Die Produktion erfolgt mit Hilfe umweltschonender Technologien und unter strengsten Auflagen in einem geschlossenen Wasserkreislauf unter Wiederverwertung unbedruckter, zurückgeführter Papiere. Text, Abbildungen und Programme wurden mit größter Sorgfalt erarbeitet. Verlag, Übersetzer und Autoren können jedoch für eventuell verbliebene fehlerhafte Angaben und deren Folgen weder eine juristische Verantwortung noch irgendeine Haftung übernehmen. Die vorliegende Publikation ist urheberrechtlich geschützt. Alle Rechte vorbehalten. Kein Teil dieses Buches darf ohne schriftliche Genehmigung des Verlages in irgendeiner Form durch Fotokopie, Mikrofilm oder andere Verfahren reproduziert oder in eine für Maschinen, insbesondere Datenverarbeitungsanlagen, verwendbare Sprache übertragen werden. Auch die Rechte der Wiedergabe durch Vortrag, Funk und Fernsehen sind vorbehalten. Die in diesem Buch erwähnten Software- und Hardwarebezeichnungen sind in den meisten Fällen auch eingetragene Warenzeichen und unterliegen als solche den gesetzlichen Bestimmungen.
Sandini Bib
I
Inhaltsverzeichnis
I
Inhaltsverzeichnis ............................................................................ 5
V V.1
Vorwort ........................................................................................... 13 Icons und typographische Vereinbarungen des Handbuches ............ 15
1 1.1
Installation von Visual Basic 6.0 ................................................... 17 Systemvoraussetzungen....................................................................... 21 Hardware ............................................................................................. 21 Betriebssystem ..................................................................................... 22
2 2.1 2.2 2.3
Einführung in die Entwicklungsumgebung.................................. 23 Starten von Visual Basic 6.0 ................................................................ 23 Die Programmoberfläche von Visual Basic 6.0 ................................... 23 Wichtige Grundlagen .......................................................................... 24 Zeichen, die nicht verwendet werden sollten..................................... 24 Programmdokumentation................................................................... 24 Befehlszeilen über mehrere Zeilen ...................................................... 25 Steuerelemente .................................................................................... 26 Direkte Sprünge mit Goto ................................................................... 26 Lange Funktionen „Spaghetti-Code“ .................................................. 27 Variablenbenennung........................................................................... 28 Die verschiedenen Programmfenster .................................................. 28 Das Hauptfenster ................................................................................. 28 Das Projekt-Fenster .............................................................................. 29 Das Werkzeugfenster Toolbox............................................................. 30 Das Eigenschaftsfenster Properties ...................................................... 30 Das Fenster für den Programmcode .................................................... 31 Der Debugger....................................................................................... 31 Das Formularfenster ............................................................................ 33 Aufbringen der Steuerelemente auf eine Form ................................... 34 Die Visual Basic-Menüleiste ................................................................ 34 Das Datei-Menü................................................................................... 34 Das Bearbeiten-Menü .......................................................................... 36
2.4
5
Sandini Bib
Das Ansicht-Menü .............................................................................. 38 Das Projekt-Menü ............................................................................... 40 Das Format-Menü ............................................................................... 42 Das Debuggen-Menü .......................................................................... 43 Das Ausführen-Menü .......................................................................... 45 Das Extras-Menü ................................................................................. 46 Das Add-In-Menü................................................................................ 46 3 3.1 3.2
3.3
4 4.1
4.2
4.3
4.4
4.5 4.6 4.7 4.8
6
Die Programmentwicklung ............................................................ 47 Das einfachste Visual Basic-Programm............................................... 47 Grundlegende Programmstrukturen .................................................. 48 Kurzüberblick ...................................................................................... 48 Variablen............................................................................................. 48 Konstanten.......................................................................................... 53 Mehrdimensionale Felder ................................................................... 55 Selbstdefinierte Datentypen ............................................................... 62 Schleifen.............................................................................................. 63 Verzweigungen ................................................................................... 65 Funktionen und Prozeduren............................................................... 67 Das erste Programm ............................................................................ 71 Eingabe................................................................................................ 72 Ausgabe ............................................................................................... 73 Buttons (Programmsteuerungen) ....................................................... 74 Der Programmcode zum Algorithmus................................................ 75 Größere Benutzerfreundlichkeit ......................................................... 81 Standardsteuerelemente ................................................................. 85 Das Formular Form ............................................................................. 85 Aufgabe ............................................................................................... 87 Lösung................................................................................................. 87 Das Textelement Label........................................................................ 88 Aufgabe ............................................................................................... 88 Lösung................................................................................................. 88 Die Schaltfläche Button ...................................................................... 89 Aufgabe ............................................................................................... 89 Lösung................................................................................................. 90 Das Texteingabeelement TextBox ...................................................... 92 Aufgabe ............................................................................................... 92 Lösung................................................................................................. 93 Das Bildfeldsteuerelement PictureBox................................................ 93 Das Anzeigesteuerelement Image ....................................................... 95 Das Rahmensteuerelement Frame ...................................................... 95 Das Kontrollkästchen CheckBox ........................................................ 96 Aufgabe ............................................................................................... 97 Lösung................................................................................................. 97
Sandini Bib
4.9
4.10
4.11
4.12
4.13
4.14
4.15 4.16 4.17 4.18
4.19
4.20
5 5.1 5.2 5.3 5.4 5.5 5.6
Das Optionsfeld OptionButton ........................................................... 98 Aufgabe................................................................................................ 99 Lösung ................................................................................................. 99 Das Listenfeld ListBox ....................................................................... 100 Einen neuen Datensatz eintragen ..................................................... 101 Einen Datensatz löschen ................................................................... 101 Den gesamten Inhalt des Listenfeld-Steuerelements löschen .......... 101 Aufgabe.............................................................................................. 101 Lösung ............................................................................................... 101 Das Kombinationsfeld Combobox.................................................... 102 Aufgabe.............................................................................................. 103 Lösung ............................................................................................... 103 Die Bildlaufleisten ScrollBar .............................................................. 104 Aufgabe.............................................................................................. 105 Lösung ............................................................................................... 105 Das Datei-, Verzeichnis- und Laufwerklistenfeld .............................. 105 Aufgabe.............................................................................................. 106 Lösung ............................................................................................... 106 Der Zeitgeber Timer........................................................................... 108 Aufgabe.............................................................................................. 109 Lösung ............................................................................................... 109 Das Liniensteuerelement Linie.......................................................... 111 Das Figurensteuerelement Shape ...................................................... 111 Beispiel zum Figurensteuerelement Shape ........................................ 111 Hinzufügen weiterer Steuerelemente ................................................ 115 Der Standarddialog mit dem CommonDialog.................................. 116 Die Eigenschaften des Dialogs Datei öffnen/speichern .................... 117 Die Eigenschaften des Dialogs Farbpalette........................................ 119 Die Eigenschaften des Dialogs Schriftart .......................................... 120 Die Eigenschaften des Dialogs Drucken............................................ 121 Die Eigenschaften des Dialogs Hilfe.................................................. 122 Zusammenfassung ............................................................................. 123 Das Registerblättersteuerelement SSTab............................................ 124 Aufgabe.............................................................................................. 125 Lösung ............................................................................................... 125 Das MDI-Formular............................................................................. 125 Aufgabe.............................................................................................. 126 Lösung ............................................................................................... 126 Wichtige Eigenschaften der Steuerelemente............................... 129 Die Eigenschaft (Name)..................................................................... 130 Die Eigenschaft Appearance .............................................................. 130 Die Eigenschaft Caption.................................................................... 130 Die Eigenschaft Cancel...................................................................... 131 Die Eigenschaft Default..................................................................... 131 Die Eigenschaft Enabled.................................................................... 132 Hintergrund- und Vordergrundfarbe ................................................ 132
7
Sandini Bib
5.7 5.8 5.9 5.10 5.11 5.12 5.13 5.14
Die Eigenschaft MousePointer.......................................................... 133 Die Eigenschaft TabIndex ................................................................. 134 Die Eigenschaft TabStop ................................................................... 134 Die Eigenschaft Tag .......................................................................... 134 Die Eigenschaft Text ......................................................................... 134 Die Eigenschaft ToolTipText ............................................................ 135 Die Eigenschaft Visible ..................................................................... 135 Die Eigenschaft WindowState .......................................................... 135
6 6.1 6.2 6.3 6.4 6.5
Wichtige Ereignisse der Steuerelemente ...................................... 137 Click – der einfache Mausklick ......................................................... 138 Der doppelte Mausklick: DblClick.................................................... 138 Das Laden eines Formulars durch Load............................................ 138 GotFocus ........................................................................................... 139 KeyDown und KeyUp – Drücken und Loslassen einer Tastaturtaste...................................................................................... 140 Drücken und Loslassen einer Maustaste mit MouseDown und MouseUp ................................................................................... 140 Mit MouseMove die Maus über ein Steuerelement bewegen........... 141 Beispiel zum Ereignis MouseMove ................................................... 142 Den Fokus verlieren: LostFocus ........................................................ 145
6.6 6.7 6.8 7 7.1
7.2 7.3
Fehlerbehandlung in Visual Basic ............................................... 147 Vorgehensweise beim Auftreten eines Laufzeitfehlers ..................... 147 Der Befehl On Error .......................................................................... 148 Der Befehl Error ................................................................................ 151 Ein Programm zum Erstellen der Fehlercodetabelle......................... 151 Die Fehlercodetabelle........................................................................ 153
8
Meldungen anzeigen .................................................................... 157
9 9.1
Grafikprogrammierung ................................................................ 161 Grundlagen zur Grafikausgabe ......................................................... 161 Farben ............................................................................................... 161 Die Line-Methode ............................................................................. 162 Die Methode Circle........................................................................... 164 Grafische Beispiele ............................................................................ 165 RGB-Farbenbeispiel ........................................................................... 165 Chaos auf dem Bildschirm – das „fraktale Apfelmännchen“........... 169
9.2
10 Der Menüdesigner......................................................................... 173 10.1 Aufgabe ............................................................................................. 175 10.2 Lösung............................................................................................... 175
8
Sandini Bib
11 Aufbau eines Visual Basic-Projekts .............................................. 177 11.1 Ablaufgesteuerte Programmierung.................................................... 177 11.2 Ereignisgesteuerte Programmierung ................................................. 178 12 12.1 12.2 12.3 12.4 12.5
Entwicklung einer komplexen Applikation ............................... 181 Beschreibung des Programms „Stack-Taschenrechner“.................... 181 Planung des Projekts ......................................................................... 182 Die verwendeten Steuerelemente und ihre Eigenschaften ............... 183 Programmglobale Definitionen ........................................................ 184 Funktionen im Formular ................................................................... 185 Formularglobale Definitionen........................................................... 185 Initialisieren der Variablen................................................................ 185 Speichern des letzten Zustandes ....................................................... 185 Vorbereitung der Berechnung ........................................................... 186 Eingabe von der Tastatur................................................................... 187 Den Stack aktualisieren ..................................................................... 188 Programm beenden ........................................................................... 190 Gesamten Stack löschen.................................................................... 190 Den letzten Wert auf dem Stack löschen .......................................... 190 Bestätigung einer Eingabe ................................................................. 191 Farben definieren .............................................................................. 191 Berechnungsfunktionen.................................................................... 192 Die letzte Aktion widerrufen ............................................................. 193 Die Eingabe der Ziffern...................................................................... 194 12.6 Das Modul für die Berechnungen ..................................................... 194 Funktion zum Überprüfen eines Operanden .................................... 194 Berechnungen mit einem Operanden .............................................. 195 Arithmetische Funktionen ................................................................ 196 Berechnungen mit zwei Operanden ................................................. 197 12.7 Das Modul zur Fehlerbehandlung..................................................... 197 13 Weitere Programmiergrundlagen ................................................ 199 13.1 Arbeiten mit Dateien......................................................................... 199 Dateien öffnen................................................................................... 199 Lesen und Schreiben in Dateien ....................................................... 201 Dateien schließen .............................................................................. 202 Umbenennen von Dateien................................................................ 202 Löschen von Dateien......................................................................... 203 Formatieren von Dateien .................................................................. 203 Beispiel zu „Arbeiten mit Dateien“ ................................................... 205 Testen des Programms....................................................................... 208 Weitere Funktionen für das Arbeiten mit Dateien ........................... 209 Funktionen für das Arbeiten mit Verzeichnissen ............................. 211 13.2 Ziehen und Fallenlassen – „Drag and Drop“ .................................... 212 Verschieben von Objekten ................................................................ 212 Verschieben von Objekten mit anschließender Reaktion ................ 217
9
Sandini Bib
13.3 Einführung in die Objektorientierung ............................................. 222 Was ist ein Objekt? ........................................................................... 223 Was sind Eigenschaften? .................................................................. 224 Was sind Ereignisse? ......................................................................... 224 Was sind Methoden? ........................................................................ 225 Was ist eine Klasse?........................................................................... 225 Erzeugen einer Klasse........................................................................ 226 Datenelemente.................................................................................. 227 13.4 Das Arbeiten mit zwei Formularen ................................................... 231 Laden und Anzeigen eines Formulars .............................................. 232 Beispiel zum Arbeiten mit zwei Formularen .................................... 235 Die Programmentwicklung............................................................... 240 13.5 Rekursive Programmierung .............................................................. 246 Einfache Rekursion ........................................................................... 246 Mehrfache Rekursion........................................................................ 248 13.6 Die Registrierdatenbank.................................................................... 250 Die Schlüssel der Registrierdatenbank.............................................. 251 Der Zugriff auf die Registrierdatenbank ........................................... 252 Das Arbeiten mit der Registrierdatenbank ....................................... 254 14 Tools .............................................................................................. 257 14.1 Verzeichnisgröße .............................................................................. 257 Die Programmoberfläche .................................................................. 257 Der Programmcode zum Verzeichnis-Informationsprogramm........ 259 14.2 Berechnungen mit dem Zufallsgenerator ......................................... 267 Die Programmoberfläche .................................................................. 268 Der Zufallsgenerator ......................................................................... 269 Der Algorithmus zum Gleichungssystem ......................................... 270 Auflösung des Gleichungssystems.................................................... 275 Zusammenfassung ............................................................................ 276 14.3 Das Spiel MasterMind ....................................................................... 277 Die Spielregeln von MasterMind ...................................................... 277 Die Programmoberfläche .................................................................. 277 Der Programmcode zu MasterMind.................................................. 279 15 Der Installationsassistent ............................................................. 287 15.1 Starten des Installationsassistenten .................................................. 288 15.2 Das Erstellen von Installationsdisketten .......................................... 288 Festlegen des Programmes (Projekts)................................................ 288 Die Optionen des Installationsassistenten ....................................... 288 Generieren der Installationsdatei ..................................................... 289 Das Zielverzeichnis bestimmen ........................................................ 290 Das Festlegen von zusätzlichen Treibern.......................................... 290 CAB-Optionen .................................................................................. 291 Festlegen des Installationstitels ........................................................ 292 Festlegen der Menüeinträge.............................................................. 292
10
Sandini Bib
Installationsorte der Dateien............................................................. 293 Skriptdatei.......................................................................................... 294 Verpackungsbericht........................................................................... 294 16 16.1 16.2 16.3 16.4 16.5 16.6
16.7
16.8
Das Erstellen eines Hilfesystems .................................................. 295 Was ist kontextsensitive Hilfe? ......................................................... 296 Grundlegende Begriffe für das Erstellen einer Hilfedatei.................. 296 Der Hilfecompiler HCW .................................................................... 297 Die Installation des HelpCompilers .................................................. 298 Die Formatierungen des Hilfetexts.................................................... 300 Erstellen einer Hilfedatei ................................................................... 301 Schreiben der Hilfedatei .................................................................... 302 Einführen eines Titels in die Hilfedatei............................................. 302 Erzeugen von Querverweisen ............................................................ 302 Erzeugen von Begriffserklärungen .................................................... 303 Erzeugen von Hilfesequenzen ........................................................... 304 Einbinden von Grafiken.................................................................... 304 Erzeugen einer ersten Hilfe mit dem Help Workshop ...................... 306 Einbinden der RTF-Textdatei ............................................................ 307 Einbinden der Grafikdateien............................................................. 308 Eigenschaften des Hilfefensters......................................................... 308 Hinzufügen der HelpContext-ID in dem Hilfeprojekt...................... 310 Das Einbinden der Hilfedatei in ein Visual Basic-Projekt ................. 312 Erstellen des Hilfeindexes.................................................................. 312 Hinzufügen von Indexeinträgen....................................................... 313 Das Bearbeiten von Indexeinträgen .................................................. 314
17 Datenbankanbindung .................................................................. 317 17.1 Standardabfragesprache .................................................................... 318 17.2 Erlernen von SQL .............................................................................. 318 Die Abfragesprache............................................................................ 321 17.3 Arbeiten mit den SQL-Kommandos .................................................. 324 Abfrage aus einer Tabelle................................................................... 324 Abfragen über mehrere Tabellen....................................................... 326 Berechnungen mit SQL-Abfragen ..................................................... 328 Abfragen zum Manipulieren des Datenbestandes ............................ 330 17.4 Datenbankprogrammierung.............................................................. 332 DAO-Bibliothek ................................................................................. 333 Datengebundene Steuerelemente ..................................................... 333 Der Datenzugriff im Programmcode ................................................. 339 Beispiele zum Datenbankzugriff ....................................................... 343 A A.1 A.2
Anhang.......................................................................................... 351 Inhalt der Diskette............................................................................. 351 Standardbefehle................................................................................. 353
11
Sandini Bib
12
A.3 A.4 A.5
Glossar............................................................................................... 355 Von Visual Basic 5.0 verwendete Dateitypen................................... 357 Zeichentabellen................................................................................. 358
S
Stichwortverzeichnis .................................................................... 363
Sandini Bib
V
Vorwort
Es gibt eine Vielzahl von Programmiersprachen, doch finden sie nur selten eine so starke Verbreitung wie Visual Basic. Warum gerade Visual Basic? Weil dies eine Programmiersprache ist, mit der man sehr schnell ein Programm entwickeln kann. Visual Basic existiert nun schon in der sechsten Generation und erfreut sich einer immer größeren Beliebtheit. Der wesentliche Vorteil dieser Programmiersprache liegt in der Möglichkeit, mit geringem Aufwand eine einfache Applikation zu erstellen. In diesem Buch sollen einfache Programmbeispiele den Umgang mit Visual Basic 6.0 erklären und das Grundverständnis für das Programmieren unter Windows vermitteln. Visual Basic 6.0 hat sein Aussehen gegenüber der Version 5.0 nur geringfügig verändert. In den Versionen bis 4.0 waren alle Module in eigenen Fenstern untergebracht. Seit der Version 5.0 sind aber alle Module in ein Visual Basic-Fenster integriert. Für Visual Basic-Umsteiger, die von der Version 4.0 oder früher auf 6.0 umsteigen, ist dieses Design zwar eine Umstellung, doch ist die Entwicklungsumgebung dank der neuen Oberfläche nun auch deutlich übersichtlicher. Um diese Übersichtlichkeit auch voll ausnutzen zu können, empfiehlt es sich, mit einer Grafikauflösung von mindestens 1024x768 auf einem 17"-Bildschirm zu arbeiten. Seit der Version 5.0 gibt es auch einen Compiler, der in der Version 6.0 noch weiter optimiert wurde, damit er schnelleren, vom Prozessor ausführbaren Programmcode erzeugt. Bis zur Version 4.0 wurde der Programmcode immer nur von einem Interpreter verarbeitet; seit der Version 5.0 können richtige, ausführbare Programme (.EXE) erzeugt werden. Der Anwender merkt bei der Bedienung keinen direkten Unterschied. Die Programme, die jedoch mit einem Compiler übersetzt wurden, sind in der Ausführung merklich schneller. Dieser Umstand erlaubt es auch, größere Programme unter Visual Basic 6.0
13
Sandini Bib
zu realisieren, was bis zur Version 4.0 aus Performancegründen nicht möglich war. Eine weitere Novität ist, daß unter Visual Basic auch teilweise objektorientiert entwickelt werden kann. In diesem Buch werde ich darauf jedoch nur oberflächlich eingehen, weil dies den Rahmen eindeutig sprengen und den Einstieg deutlich erschweren würde. Über die objektorientierte Programmierung in Visual Basic ließe sich leicht ein eigenes Buch schreiben. (Für den fortgeschrittenen Visual Basic-Programmierer empfehle ich hierzu das Buch „Visual Basic 6.0. Effektive Programmentwicklung unter Windows 98“ von Michael Kofler, in dem die objektorientierte Programmierung fundiert erklärt und anhand vieler Beispiele erläutert wird.) Mit diesem Buch möchte ich dem Leser anhand einiger Beispiele die Möglichkeit bieten, sich von Grund auf in die Programmierung mit Visual Basic 6.0 einzuarbeiten. Es werden Grundbegriffe der Programmierung sowie grundlegende Programmstrukturen ausführlich erläutert. Ebenso wird der Umgang mit der grafischen Oberfläche von Visual Basic demonstriert, um die bestmögliche Grundlage zum Erstellen von Anwendungen zu bieten. Das Buch wendet sich an interessierte Einsteiger sowie an Anwender, die bereits Kenntnisse im Programmieren erworben haben und sich nun mit der Programmiersprache Visual Basic vertraut machen wollen. Die Bedeutung von Fachbegriffen wird dem Leser anhand von ausführlichen Erläuterungen und, wo angebracht, mit praktischen Beispielen nahegebracht. Ganz nach dem Prinzip „learning by doing“ möchte dieses Buch Orientierung zu einem Thema bieten, das in der Fachpresse leider oft nur eine unzugängliche Darstellung findet. Das Schreiben dieses Buches hat mir viel Freude bereitet, da ich meine eigenen Ideen und Vorstellungen darin einbringen konnte.
Dirk Abels
14
Sandini Bib
V.1
Icons und typographische Vereinbarungen des Handbuches
In diesem Buch wird eine Reihe von Icons verwendet, deren Bedeutung Sie hier finden: Beispiele helfen Ihnen, sich schneller und sicher im Feld der Visual Basic-Programmierung zu orientieren. Sie werden darum mit diesem Icon gekennzeichnet. Übung – so werden praktische Übungen gekennzeichnet, mit deren Hilfe Sie Ihre neuerworbenen Kenntnisse trainieren können. Sie werden dieses Icon in diesem Buch sehr oft finden! Hinweis – damit möchten wir Sie auf Textpassagen hinweisen, die Ihre besondere Aufmerksamkeit verdienen. Warnung – hier zeigen wir Ihnen, wie Sie häufig gemachte Fehler vermeiden und nicht in verborgene Fallen tappen. Tips und Tricks – hier geben wir Ihnen einige Tips, wie Sie sich die Arbeit erleichtern können. Um Ihnen die Übersicht im Text zu erleichtern, werden bestimmte Textformatierungen verwendet, die in der folgenden Tabelle aufgelistet sind: Schriftart mit Beispiel
Bedeutung
Kursiv (Button1)
Bestandteile der Programmiersprache, wichtige Passagen, Verzeichnisse
Kapitälchen (UNIT.PAS)
Menübefehle, Schaltflächen, Dateinamen
Nichtproportional (GetMessage)
Programmtexte (Listings)
Nichtproportional, fett (string)
Reservierte Wörter in Listings
Fett (Button)
Icon-Bezeichnungen
Tastenkappen (F9)
Tasten, Tastenkombinationen
15
Sandini Bib
Sandini Bib
1
Installation von Visual Basic 6.0
Für die Installation von Visual Basic 6.0 legen Sie die CD-ROM mit der Software von Microsoft in das CD-Laufwerk ein. Im Normalfall wird das Installationsprogramm daraufhin automatisch gestartet. Beginnt das System nicht automatisch mit der Installation, kann die Installation manuell gestartet werden. Hierfür wählen sie aus der Startleiste das Menü START und darin die Option AUSFÜHREN.
Abbildung 1.1: Das Start-Menü von Windows 95
Geben Sie in die Befehlszeile zunächst den Buchstaben des Laufwerks, in dem sich die Installations-CD befindet (z.B. d:), und danach \Setup ein (Abbildung 1.1). Nach Bestätigung der Eingabe durch Drücken des Buttons OK wird die Installation gestartet, und es erscheint der Bildschirm aus Abbildung 1.2.
17
Sandini Bib
Abbildung 1.2: Der Installationsbildschirm
Hier können Sie sich über die Schaltfläche INFO-DATEI ANZEIGEN weitere Information, über die neue Entwicklungsumgebung im InternetBrowser anzeigen lassen. Während der gesamten Installation werden drei Schaltflächen im unteren Bereich des Fensters angezeigt: 1. ZURÜCK: Wird verwendet, um zu dem vorhergehenden Bildschirm
zu gelangen. Da es beim Startbildschirm keinen vorhergehenden Bildschirm gibt, ist die Schaltfläche nicht verfügbar. 2. WEITER: Hiermit werden die gemachten Einstellungen übernom-
men und der nächste Bildschirm aktiviert. 3. BEENDEN: Hiermit kann jederzeit die Installation von Visual Basic
6.0 abgebrochen werden. Wenn schon einige Dateien auf die Festplatte kopiert wurden, werden diese auch wieder gelöscht und die erzeugten Verzeichnisse entfernt. Durch Betätigen der Schaltfläche WEITER wird nun der Lizenzvertrag eingeblendet, und die Schaltfläche WEITER ist deaktiviert. Um den nächsten Installationsschritt durchführen zu können, muß einer der beiden Optionsschalter: 1. ICH STIMME DEM LIZENZVERTRAG ZU 2. ICH LEHNE DEN LIZENZVERTRAG AB
selektiert werden. Beim Ablehnen des Lizenzvertrages wird die Installation beendet, ohne Visual Basic 6.0 installiert zu haben. Wenn Sie dem Lizenzvertrag zustimmen, erscheint der nächste Installationsschritt.
18
Sandini Bib
Hier werden Sie aufgefordert, die ID-Nummer des Produktes, Ihren Namen und evtl. den Ihrer Firma einzutragen. Die ID-Nummer finden Sie auf der Rückseite der CD-Hülle, der Sie die Installationsdiskette entnommen haben. Mit Betätigen der Schaltfläche WEITER wird wieder ein neues Fenster angezeigt. Wenn auf Ihrem Rechner Komponenten von Visual Studio 97 installiert sind, kann hier selektiert werden, welche dieser Applikationen deinstalliert werden sollen. Es ist jedoch nicht nötig, Visual Studio 97 zu deinstallieren, da sich die alten und die neuen Versionen nicht behindern. Mit WEITER wird nun der Installationsschritt für die Art der Installation von Visual Basic aktiviert. Im allgemeinen kann die voreingestellte Option VISUAL BASIC 6.0 ... INSTALLIEREN übernommen werden. Jetzt wird das eigentliche Installationsprogramm von Visual Basic gestartet. Bis zu diesem Zeitpunkt hatten Sie es lediglich mit der Installationssoftware für das Komplettpaket Visual Studio 6.0 zu tun. Jetzt werden zunächst noch einmal die Lizenzvereinbarung (doppelt hält besser) und im nächsten Fenster die ProduktID angezeigt. Nach Betätigung der WEITER-Taste wird wieder Ihre Interaktion verlangt. Es muß festgelegt werden, auf welche Art die Installation durchgeführt und wohin die Entwicklungsumgebung installiert werden soll. Im folgenden werden die einzelnen Installationsoptionen beschrieben. Standard Visual Basic 6.0 wird mit den Einstellungen installiert, die für die meisten Fälle ausreichend sind. Ich empfehle diese Installationsart, da zum Erlernen einer Programmiersprache die Standardeinstellungen völlig ausreichend sind. Wenn bei der Programmierung weitere Optionen oder Programmteile benötigt werden, läßt sich die Installation jederzeit anpassen und erweitern. Benutzerdefiniert Bei der benutzerdefinierten Installation müssen Sie selbst die zu installierenden Optionen festlegen, d. h. Sie geben an, welche Optionen Sie brauchen und welche nicht. Da beim Erlernen einer Programmiersprache meist nur selten Kenntnisse über die Bedeutung der einzelnen Module vorhanden sind, sollten Sie diese Installationsart nur wählen, wenn Sie Visual Basic schon aus früheren Versionen kennen.
19
Sandini Bib
Ordner wechseln... Über diesen Button können Sie ein anderes Verzeichnis auswählen, in das Visual Basic 6.0 installiert werden soll. Vom System wird im allgemeinen ein Verzeichnis auf dem Laufwerk vorgeschlagen, auf dem sich auch das Betriebssystem befindet. Ich empfehle für den Anfang die Option STANDARDINSTALLATION auszuwählen, da mit ihrer Hilfe alle wichtigen Elemente installiert werden. Der Vollständigkeit halber werde ich aber noch auf die BENUTZERDEFINIERTE INSTALLATION eingehen. Wenn sie die Option BENUTZERDEFINIERTE INSTALLATION gewählt haben, erscheint als nächstes Fenster ein Auswahldialog, in dem die verschiedenen Module, die installiert werden sollen, selektiert werden können.
Abbildung 1.3: Die Optionen zur benutzerdefinierten Installation
Die meisten der angezeigten Optionen teilen sich ebenfalls in kleinere Komponenten auf. Sind alle Komponenten aus einer Gruppe ausgewählt, so erscheint ein Haken vor der entsprechenden Option. Sind nur einige Komponenten einer Gruppe gewählt, so ist das Kästchen mit dem Haken grau eingefärbt. Wenn aus einer Gruppe kein Modul installiert werden soll, so ist das Kästchen vor der entsprechenden Option leer.
20
Sandini Bib
Um festzustellen, welche Komponenten einer Gruppe selektiert sind, muß mit dem Markierungsbalken die gewünschte Option markiert werden. Danach wird durch Betätigen der Schaltfläche OPTION ÄNDERN... das Fenster angezeigt, das die selektierten Module auflistet. Mit der Schaltfläche ALLE AUSWÄHLEN werden alle Optionen mit den jeweiligen Modulen markiert und dann auch installiert. Voreingestellt sind die Module, die bei der Standardinstallation auf die Festplatte kopiert werden. Jetzt beginnt der eigentliche Installationsvorgang. Die Zeit, die für das Kopieren und Konfigurieren der Entwicklungsumgebung gebraucht wird, hängt jetzt nur noch von der Computerhardware und von den ausgewählten Modulen ab.
1.1
Systemvoraussetzungen
1.1.1
Hardware
Folgende Hardwarekonfiguration ist für die Installation von Visual Basic 6.0 als minimales Basissystem erforderlich:
Prozessor
Ein PC mit einem 486DX/66 MHz oder einem schnelleren Prozessor.
Hauptspeicher
Mindestens 16 MB unter Windows 95.
Mindestens 24 MB unter Windows NT.
Festplatte
76 MB für die typische Installation.
94 MB für die komplette Installation.
CD-ROM-Laufwerk
Monitor
Ein VGA-Monitor oder ein Monitor mit einer höheren Auflösung.
Maus
Eine serielle oder entsprechend kompatible Maus.
Um Visual Basic 6.0 aber möglichst effizient einsetzen zu können, empfehle ich Ihnen folgende Hardwarekonfiguration:
Prozessor
PC mit Pentium-Prozessor.
21
Sandini Bib
Hauptspeicher
32 MB unter Windows 95.
64 MB unter Windows NT.
Festplatte
CD-ROM-Laufwerk
Monitor
17"-Monitor mit einer Auflösung von 1024x768 Bildpunkten.
Maus
1.1.2
22
Auf der Festplatte sollten Sie über mindestens 650 MB freien Speicher verfügen, um die Komplettinstallation einschließlich der mitgelieferten Zusatzprodukte durchführen zu können.
serielle oder entsprechend kompatible Maus.
Betriebssystem
Microsoft Windows 95 oder höher.
Microsoft Windows NT Workstation Version 4.0 (mit Service Pack 3).
Sandini Bib
2
2.1
Einführung in die Entwicklungsumgebung
Starten von Visual Basic 6.0
Nach der Installation von Visual Basic 6.0 befindet sich ein neuer Menüeintrag unter START x PROGRAMME. Wenn der Eintrag, der vom Installationsprogramm vorgeschlagen wurde, übernommen worden ist, dann heißt das Menü VISUAL BASIC 6.0. In diesem Menü können sich die in Abbildung 2.1 ersichtlichen Einträge befinden, die von der Installationsart abhängig sind:
Abbildung 2.1: Programme im Menü „Visual Basic 6.0“
Um die Entwicklungsumgebung von Visual Basic 6.0 zu starten, muß der Menüeintrag VISUAL BASIC 6.0 angeklickt werden. Danach wird die Entwicklungsumgebung geladen, und es erscheint das Auswahlfenster, in dem festgelegt werden muß, welche Art von Applikation entwickelt werden soll. In diesem Buch werden jedoch nur StandardEXE-Projekte dargestellt.
2.2
Die Programmoberfläche von Visual Basic 6.0
Um unter Visual Basic 6.0 effiziente Programme zu entwickeln, wird eine gute, übersichtliche Entwicklungsumgebung zur Verfügung gestellt (Abbildung 2.2). Beim ersten Starten des Programms werden automatisch die Menüleiste, das Projektfenster, die Toolbox und eine leere Form angezeigt, nachdem im Abfragefenster die Option Standard-EXE ausgewählt wurde.
23
Sandini Bib
Abbildung 2.2: Die Visual Basic-Entwicklungsumgebung nach dem Start
2.3
Wichtige Grundlagen
Im folgenden werden die einzelnen Fenstertypen, die auf der Visual Basic-Oberfläche angezeigt werden, sowie die Menübefehle und wichtigsten Grundbegriffe beschrieben.
2.3.1
Zeichen, die nicht verwendet werden sollten
Im Programmcode sollten Zeichen wie z.B. Umlaute, Sonderzeichen sowie das „ß“ vermieden werden. Die deutsche Version von Visual Basic unterstützt zwar derartige Zeichen in Funktionen und Variablen, doch kann es zu Kommunikationsproblemen kommen, wenn Visual Basic an andere Applikationen angebunden wird. Unter Umständen kommt es vor, daß solche Applikationen mit den genannten Sonderzeichen Probleme haben.
2.3.2
Programmdokumentation
Wie in allen Programmiersprachen ist es auch in Visual Basic wichtig, daß der zu entwickelnde Programmcode vernünftig dokumentiert wird. Oft werden Programme gar nicht, falsch oder sinnlos dokumentiert (Abbildung 2.3). Es ist offenkundig, daß die Variable Anzahl den
24
Sandini Bib
Wert 1 zugewiesen bekommt und um 1 erhöht wird. Es wäre allerdings interessant zu wissen, welche Aufgabe die Variablen Anzahl und Wert haben.
Abbildung 2.3: Fehlerhafte Dokumentation eines Programmteils
Für eine solide Dokumentation des Programmcodes empfehle ich, zuerst die Funktion in Pseudocode (fast umgangssprachlich) zu schreiben. Wenn die Funktion dann in Visual Basic programmiert wird, liegt eine sehr gute Beschreibung vor. Je besser eine Programmbeschreibung ist, desto schneller versteht man den Programmcode, und ein Programmierer kann sich dann der eigentlichen Aufgabe – dem Programmieren – widmen. Bemerkungen können unter Visual Basic immer mit dem Zeichen „'“ oder dem Befehl REM eingeleitet werden. Alle nachfolgenden Zeichen haben keinen Einfluß mehr auf das Programm und werden somit auch nicht mehr berücksichtigt. Nach diesen Kommentarzeichen kann in dieser Zeile kein Programmcode mehr folgen.
2.3.3
Befehlszeilen über mehrere Zeilen
Damit übersichtlich programmiert werden kann, bietet Visual Basic die Möglichkeit, sehr lange Befehlszeilen auf mehrere Zeilen zu verteilen. Um Visual Basic mitzuteilen, daß eine Befehlszeile umgebrochen wird, muß ein Unterstrich „_“, dem ein Leerzeichen vorangeht, an die Befehlszeile angehängt werden. Das Beispiel in Tabelle 2.1 verdeutlicht dies: Die beiden Programmzeilen sind zwar identisch, die Programmzeile im linken Fenster ist jedoch auf drei Zeilen verteilt worden. Mit Zeilenumbruch
Ohne Zeilenumbruch
Datensatz = _
Datensatz = "System ausgelastet"
"System " & _ "ausgelastet" Tabelle 2.1: Zeilenumbruch in einer Programmzeile
!"
25
Sandini Bib
2.3.4
Steuerelemente
Steuerelemente sind für die Darstellung der Information oder die Eingabe durch Benutzer zuständig. Sie werden auf Formulare aufgebracht und gestalten somit das Aussehen der Programmfenster. Wichtige Steuerelemente sind z.B. Schaltflächen und Listenelemente.
2.3.5
Direkte Sprünge mit Goto
Wie andere Programmiersprachen auch, ist Visual Basic mit der Zeit gewachsen und moderner geworden. Um aber kompatibel zu bleiben, wurden sogenannte Altlasten mit in die neueren Versionen übernommen. Visual Basic beruht auf der älteren Sprache Basic, die schon beim C641 Verwendung gefunden hat. Auf dem PC unter DOS wurde GW-Basic mitgeliefert. Diese Sprachen kannten keine Funktionen oder Prozeduren, sondern bestanden aus einer Liste aneinandergereihter Befehle (Abbildung 2.4), bei denen jede Zeile eine Nummer hatte. Um nun eine bestimmte Befehlsfolge auszuführen, gab es den direkten Sprungbefehl Goto. 5 10 20 30 40 41 42 43 45
Clr For I=3 To 10 If I 0
Kann nie wahr werden, da X nicht kleiner als 0 und gleichzeitig größer als 0 sein kann
Tabelle 3.8: Beispiel Boolscher Ausdrücke in If-Then-Else-Abfragen
SELECT CASE Die Verzweigung Select Case ist eine Fallunterscheidung, da sie für mehrere verschiedene Fälle auch unterschiedliche Entscheidungsspielräume zur Verfügung stellt. Select Case Ausdruck Case Fall1: ... Case Fall2: ... Case Falln: ... [Case ELSE] ... End Select
Diese Art von Verzweigung wird u.a. verwendet, wenn das Programm abhängig vom Wochentag unterschiedliche Programmteile ausführen muß. Das folgende Beispiel schreibt in eine Variable vom Typ String den Namen des Wochentages, wobei die Woche bei Sonntag beginnt, und Sonntag dem Wert 1 entspricht. Dim Tag As Integer Dim Wochentag As String 'Der Variablen Tag eine Zahl zwischen '1 und 7 zuweisen
66
Sandini Bib
Tag = 1 Select Case Tag Case 1: Wochentag Case 2: Wochentag Case 3: Wochentag Case 4: Wochentag Case 5: Wochentag Case 6: Wochentag Case 7: Wochentag Case ELSE Wochentag End Select
3.2.8
= "Sonntag" = "Montag" = "Dienstag" = "Mittwoch" = "Donnerstag" = "Freitag" = "Samstag" = "Falsche Eingabe"
Funktionen und Prozeduren
Prozeduren (Sub – End Sub) Prozeduren haben stets den folgenden Aufbau: Sub Prozedurname (Param1 As Vartyp, _ ..., Paramn As Vartyp) ... End Sub
Als Beispiel wählen wir eine Prozedur, die die Summe zweier Zahlen ermittelt: Sub Summe(Variable1 As Integer, _ Variable2 As Integer) Dim Ergebnis As Integer ... Ergebnis = Variable1 + Variable2 ... End Sub
67
Sandini Bib
Funktionen (Function – End Function) Funktionen sind Prozeduren, die einen Wert an die Funktion zurückgeben, von der sie aufgerufen wurden. Der Aufbau von Funktionen sieht wie folgt aus: Function Name (Param1 As Vartyp, _ ..., Paramn As Vartyp) AS Vartyp ... Name = Wert ... End Function
Auch hier wieder ein kurzes Beispiel, nämlich eine Funktion, die die Summe zweier Zahlen ermittelt: Function Summe(Variable1 As Integer, _ Variable2 As Integer) AS Integer Summe= Variable1 + Variable2 End Function
Call-by-Value Call-by-Value bedeutet, daß der Inhalt der Variablen an die aufzurufende Funktion oder Prozedur übergeben wird. Ändert man also den Inhalt der Variablen in der aufgerufenen Funktion oder Prozedur, hat dies keinen Einfluß auf den Inhalt der Variablen der aufrufenden Funktion. Soll bei einer Funktion oder Prozedur eine Variable durch die Methode Call-by-Value übergeben werden, muß dies explizit bei der Deklaration der Funktion angegeben werden. Sub Procedure(ByVal Variablenname As Variablentyp) Function Function(ByVal Variablenname As Variablentyp)
Das folgende Beispiel berechnet die Fakultät einer Zahl. Damit der Variableninhalt in der aufrufenden Funktion nicht verändert wird, wird das Verfahren Call-by-Value gewählt. Function Fakultaet(ByVal x As Long) As Long Dim i As Integer If x > 0 Then For i = x – 1 To 2 Step –1 x = x * i Next i
68
Sandini Bib
Fakultaet = x Else Fakultaet = 0 End If End Function
Call-by-Reference Bei der Methode Call-by-Reference wird – im Gegensatz zur Methode Call-by-Value – nicht der Inhalt der Variablen übergeben, sondern deren Speicheradresse. Wird der Inhalt der Variablen in der aufgerufenen Funktion oder Prozedur geändert, so ändert sich auch der Inhalt der Variablen in der aufrufenden Funktion. Durch diese Art der Parameterübergabe ist es nun möglich, daß eine Funktion mehrere verschiedene Variablen an die aufrufende Funktion zurückliefert (sog. indirekte Parameterrückgabe). Call-by-Reference muß nicht explizit definiert werden, da diese Art der Variablenübergabe in Visual Basic voreingestellt ist. Das folgende Beispiel berechnet die Fakultät einer Zahl (vgl. mit Callby-Value). Diesmal wird die Parameterübergabe jedoch nach dem Prinzip Call-by-Reference programmiert. Function Fakultaet(x As Long) As Long Dim i As Integer If x > 0 Then For i = x – 1 To 2 Step –1 x = x * i Next i Fakultaet = x Else Fakultaet = 0 End If End Function
In dem Beispiel Call-By-Reference ist der Inhalt der Variablen der aufrufenden Funktion verändert worden. Er entspricht nicht mehr dem Wert, der der Berechnung zugrundeliegt, sondern dem Ergebnis. In Tabelle 3.9 werden die Variableninhalte der beiden Verfahren nochmals anhand der einzelnen Programmschritte verdeutlicht.
69
Sandini Bib
Call-by-Value
Call-by-Reference
Schritt 1: Initialisierung
Zahl = 4
Zahl = 4
Schritt 2: Aufruf der Fakultätsfunktion
Erg = Fakultaet(Zahl)
Erg = Fakultaet(Zahl)
Variableninhalte nach dem Zurückkehren aus der Fakultätsfunktion
Erg = 24 Zahl = 4
Erg = 24 Zahl = 24
Tabelle 3.9: Schrittweiser Vergleich von Call-by-Value und Call-by-Reference
Wird der Inhalt der Variablen in der aufgerufenen Funktion nicht geändert, so ist es nicht relevant, ob die Parameterübergabe mit der Methode Call-by-Value oder Call-by-Reference erfolgt. Wird der Inhalt der Variablen jedoch in der aufgerufenen Funktion geändert, so muß bereits bei der Deklaration bekannt sein, ob die aufgerufene Funktion den neuen Wert verwerfen (Call-by-Value) oder an die aufrufende Funktion zurückliefern soll (Call-by-Reference). Aufgabe Das erste Programmbeispiel, das im folgenden entwickelt werden soll, ist eine mathematische Spielerei. Alle natürlichen Zahlen2 lassen sich in die Zahl 123 umrechnen, indem man sowohl die geraden und ungeraden Ziffern als auch die Anzahl der Stellen ermittelt. Wird dieser Algorithmus oft genug ausgeführt, so lautet das Endergebnis immer 123. Theoretisches Beispiel mit den Zahlen 3 und 12345
Beispiel 1
Beispiel 2
Zahl
gerade Ziffern
ungerade Ziffern
Anzahl Stellen
3
0
1
1
11
0
2
2
22
2
0
2
202
3
0
3
303
1
2
3
123
1
2
3
123
1
2
3
12345
2
3
5
235
1
2
3
123
1
2
3
123
1
2
3
Tabelle 3.10: Beispiele zum Algorithmus des Zahlenbeispiels „123“ 2. Zahlen, die größer als 0 sind und keine Nachkommastellen haben, also nicht gebrochen sind.
70
Sandini Bib
3.3
Das erste Programm
Auf dem leeren Formularfenster werden die Steuerelemente, über die Programm und Benutzer kommunizieren, untergebracht. Hier werden die Buttons, Labelfelder usw. positioniert und der Code für das Formular implementiert. Jedes Formularfenster kann wiederum ein anderes Formularfenster aufrufen. Im Eigenschaftsfenster kann nun der Name des Fensters geänder werden. Hiefür ändern Sie die Eigenschaft Name in Zahlenloch.
Abbildung 3.10: Ein leeres Formularfenster
Wenn man mit der linken Maustaste auf dem Formular einen Doppelklick ausführt, gelangt man in den Programmeditor von Visual Basic. Jede Funktion oder Prozedur kann nun wiederum eine andere Funktion oder Prozedur aufrufen.
Entwickeln einer ersten Applikation mit Visual Basic 6.0
Um den Programmcode dem aktuellen Fenster zuzuordnen, ist es am einfachsten, wenn mit der linken Maustaste ein Doppelklick auf die Form ausgeführt wird. Nach dem Doppelklick wird das Programmeditorfenster geöffnet und der Cursor in der Funktion Sub Form_Load() positioniert (Abbildung 3.11). Hier kann nun z.B. dem Fenster ein neuer Titelleistentext zugewiesen werden. Private Sub Form_Load() Zahlenloch.Caption = "Zahlenloch 123 End Sub
Version 1.0"
71
Sandini Bib
Abbildung 3.11: Programmeditor nach dem Doppelklick auf das Formularfenster
Wird das Programm nun nochmals gestartet, erscheint der eingegebene Satz in der Titelleiste des Fensters. Des weiteren hat das Fenster Eigenschaften wie z.B. einen Namen, Aussehen usw. Diese Eigenschaften lassen sich im Eigenschaftenfenster einstellen. In dem Beispiel „Zahlenloch 123“ erhält das Fenster den Namen „Zahlenloch“, d.h. in dem Property-Fenster wird bei der Eigenschaft Name der Name „Zahlenloch“ eingetragen. Die Eigenschaft Caption wird beim Programmstart in der Funktion Form_Load initialisiert, sie braucht also nicht geändert zu werden. Um zu zeigen, daß diese Eigenschaft keinen Einfluß auf das Programmfenster hat, kann der voreingestellte Eintrag FORM1 gelöscht werden.
3.3.1 Die Dateneingabe in das Programm Zahlenloch
Eingabe
Für das Beispiel wird eine Eingabemöglichkeit benötigt, um die zu berechnende Zahl frei wählen zu können. Zur Eingabe von Daten über die Tastatur steht unter Visual Basic das Texteingabeelement TextBox zur Verfügung.
Abbildung 3.12: Das Texteingabeelement „TextBox“
Um eine TextBox oder einen Schaltknopf auf die Oberfläche eines Formulars zu bringen, muß in dem Werkzeugfenster das jeweilige Steuerelement aktiviert werden. Nun muß der Mauszeiger an die Stelle bewegt werden, an der das Element positioniert werden soll. Durch Klicken mit der rechten Maustaste wird die Position des Texteingabeelements auf dem Formular festgelegt. Die Größe des Steuerelements kann durch Ziehen mit gedrückter linker Maustaste definiert werden. Um die Eigenschaften nun für das Beispielprogramm Zahlenloch einzustellen, muß das Steuerelement durch einmaliges Anklicken aktiviert werden. Die Eigenschaft Name erhält den Wert
72
Sandini Bib
Zahl, bei der Eigenschaft Tag wird die Zeichenkette „Die zu prüfende Zahl eingeben“ eingegeben. Der Inhalt in der Eigenschaft Text wird gelöscht. Bei einem Programmstart kann nun in der TextBox eine Eingabe vorgenommen werden.
3.3.2
Ausgabe
Natürlich wird auch ein Steuerelement benötigt, mit dessen Hilfe die ermittelten Daten dem Benutzer dargestellt werden. Es gibt dazu mehrere Möglichkeiten, von denen man die jeweils beste wählen kann. Anhand des Beispiels zur Berechnung der Zahl 123 sollen drei Ausgabemöglichkeiten verglichen werden, um das Vorgehen zur Entscheidung zwischen verschiedenen Steuerelementen zu verdeutlichen. Label
TextBox
ListBox
Ausgabe von Text möglich
Ja
Ja
Ja
Eingabe von Text während des Programmablaufs möglich
Nein
Ja
Nein
Ausgabe von mehreren Zeilen Text möglich (Möglichkeit zum Verschieben des sichtbaren Textes mittels Bildlaufleiste)
Nein
Nein
Ja
Ausgabe des Programmergebnisses
Tabelle 3.11: Vergleich von drei Ausgabe-Steuerelementen
Wie Tabelle 3.11 zeigt, ist es nicht eindeutig, wie viele Schritte notwendig sind, um das Ziel zu erreichen. Es ist aber dennoch sinnvoll, alle Zwischenergebnisse dem Benutzer auszugeben, damit er die Berechnung nachvollziehen kann. Aus der Vergleichstabelle (Tabelle 3.11) ist ersichtlich, daß nur die ListBox mehrere Datenzeilen ausgeben kann. Daher wird in diesem Beispiel die ListBox eingesetzt. Um eine ListBox auf die Oberfläche eines Formulars zu bringen, muß in der Toolbox das Steuerelement ListBox aktiviert werden. Nun muß der Mauszeiger an die Stelle bewegt werden, an der das Element positioniert werden soll. Durch Klicken der rechten Maustaste wird die Position der ListBox auf dem Formularfenster festgelegt. Die Größe der ListBox kann durch Ziehen mit gedrückter rechter Maustaste definiert werden. Die Eigenschaft Name erhält die Definition Wertigkeit.
73
Sandini Bib
3.3.3 Ausführen von Programmodulen
Buttons (Programmsteuerungen)
Um in einem Programm einen bestimmten Programmteil zu starten, werden CommandButtons, kurz Buttons oder Schaltflächen genannt, eingesetzt. Im Beispiel zur Berechnung der Zahl 123 werden zwei Schaltflächen benötigt – eine zum Starten der Berechnung, eine zum Beenden des Programms.
Abbildung 3.13: Die Schaltfläche „Button“
Um einen Button oder Schaltknopf auf die Oberfläche einer Form zu bringen, muß im Werkzeugfenster das Steuerelement Button aktiviert werden. Nun muß der Mauszeiger an die Stelle bewegt werden, an der das Element positioniert werden soll. Durch Klicken der rechten Maustaste wird die Position des Buttons auf dem Formular festgelegt. Die Größe des Buttons kann durch Ziehen mit gedrückter rechter Maustaste definiert werden. Die Eigenschaft Name des Buttons erhält den Wert OK, die Eigenschaft Caption den Wert Berechnen. Auf die gleiche Weise muß der Button zum Beenden des Programms auf das Formular aufgebracht werden. Die Eigenschaft Name erhält nun den Wert Abbruch, und die Eigenschaft Caption erhält den Wert Beenden. Im Zusammenhang mit der Schaltflächenprogrammierung kann man gleich auch noch eine nützlichen Funktion einrichten – den sog. ShortKey3. Damit ein Button mit einem solchen ShortKey aktiviert werden kann, muß in Visual Basic das Zeichen „&“ vor denjenigen Buchstaben gesetzt werden, der als ShortKey aktiviert werden soll. Wird zum Beispiel das „&“ vor den Buchstaben „d“ bei Beenden gesetzt, erscheint ein unterstrichenes „d“ auf dem Button; das Programm kann nun mit der Tastenkombination (Alt)-(D) beendet werden. Es muß jedoch darauf geachtet werden, daß jeder ShortKey nur einmal benutzt wird, da sonst nicht eindeutig definiert werden kann, welche Funktion als erste ausgeführt wird. Um auch dieses Beispielprogramm an den Windows-Standard anzupassen, erhält der Button OK bei der Eigenschaft Caption die Zeichenkette Be&rechnen und der
3. Eine Tastenkombination, die das Ausführen einer Menüoption oder einer Funktion ermöglicht, ohne zuvor das Steuerelement aktiviert zu haben.
74
Sandini Bib
Button ABBRECHEN – ebenfalls bei der Eigenschaft Caption – die Zeichenkette &Beenden. Wenn das Programm neu gestartet wird, können beide Buttons betätigt werden. Dennoch geschieht nichts. Weder wird eine Fehlermeldung ausgegeben, noch wird durch Betätigen des Buttons Beenden das Programm abgebrochen. Um das Programm zu beenden, muß immer noch das Tastenkürzel (Alt)+(F4) oder das Visual Basic-Menü AUSFÜHREN | BEENDEN benutzt werden. Als erstes wird der Button ABBRECHEN programmiert. Durch Doppelklick auf den Button ABBRECHEN wird der Programmeditor mit der Funktion Abbrechen_Click() geöffnet. Zwischen dem Funktionsaufruf von Abbrechen_Click() und dem Funktionsende END SUB kann nun der abzuarbeitende Programmcode eingefügt werden. In diesem konkreten Fall ist das die Funktion END. Die Funktion sieht also wie folgt aus: private Sub Abbrechen_Click() End End Sub
3.3.4
Der Programmcode zum Algorithmus
Der zweite Button soll die eigentliche Berechnungsroutine auslösen. Im folgenden Abschnitt soll diese Funktion programmiert werden. Zum besseren Verständnis wird der Programmablauf zuerst in einem Pseudocode entwickelt und danach mit der jeweiligen Erklärung in einen richtigen Visual Basic-Programmcode umgewandelt.
Entwickeln des Programmcodes auf der Basis des Vorgabealgorithmus
Initialisiere alle Variablen Solange die Zahl 123 nicht gefunden wurde, durchlaufe diese Schleife Zähle alle geraden Zahlen Zähle alle ungeraden Zahlen Zähle die Anzahl der Ziffern Rechne die Ergebnisse in eine neue Zahl um Gebe die ermittelte Zahl in der ListBox aus Ende der Solange-Schleife
Die Initialisierung der Variablen Nachdem der Startbutton aktiviert wurde, muß zuerst geprüft werden, ob es sich bei den eingegebenen Daten um eine erlaubte Zahl handelt. Wenn das zutrifft, wird diese Zahl einer Variablen zugewiesen und der Algorithmus zum Umwandeln der Zahl gestartet.
Vorbelegen der Variablen mit den Startwerten
75
Sandini Bib
Der folgende Programmcode führt die Zeile Initialisiere alle Variablen aus dem Pseudocode-Listing aus. Dim Ergebnis As String Dim Gerade As Integer Dim Ungerade As Integer Dim i As Integer If IsNumeric(Zahl.Text) then 'Wenn die Zahl vom Typ 'Long ist Ergebnis = Zahl.Text Else Exit Sub End If Wertigkeit.Clear
Die While-Schleife Ausführen einer Schleife bis zur Erfüllung des Abbruchkriteriums
Nachdem alle Variablen initialisiert wurden, muß die While-Schleife realisiert werden. Als Kriterium für die einzusetzende Schleife gilt folgendes: 1. Es muß zu Beginn der Schleife geprüft werden, ob die Zahl 123
schon gefunden wurde, denn wenn 123 als zu modifizierende Zahl eingegeben wird, ist es nicht nötig, den Algorithmus abzuarbeiten. 2. Es ist nicht bekannt, wie oft die Schleife durchlaufen wird. In Ta-
belle 3.12 ist gut zu erkennen, daß die Größe der Zahl nicht in Zusammenhang mit der Anzahl der Schleifendurchläufe steht, die für das Erreichen der Zahl 123 nötig sind. Mit einer While-Schleife können genau diese Anforderungen erfüllt werden. Der Programmcode in der While-Schleife wird solange abgearbeitet, bis das Abbruchkriterium der Schleife wahr ist. Der Bereich der While-Schleife des Pseudocodes stellt sich in Visual Basic wie folgt dar: While Val(Ergebnis) 123 'Zähle alle geraden Zahlen 'Zähle alle ungeraden Zahlen 'Zähle die Anzahl der Ziffern 'Berechne die neue Zahl anhand der Ergebnisse Wend
76
Sandini Bib
Zählen der geraden und ungeraden Zahlen Um Ziffern in einer Zahl zu analysieren, ist es sinnvoll, die Zahl in eine Zeichenkette umzuwandeln und jedes Zeichen (bzw. jede Ziffer) auf das Kriterium „gerade“ bzw. „ungerade“ zu überprüfen. Für die Umwandlung eines Variablentypen in einen anderen existieren folgende Funktionen:
Analysieren aller Ziffern der eingegebenen Zahl
Funktion
Beschreibung
Asc(s)
Liefert den ASCII-Code des ersten Zeichens von s.
CBool(x)
Wandelt einen beliebigen Datentyp x in den Datentyp Boolean um.
CByte(x)
Wandelt einen beliebigen Datentyp x in den Datentyp Byte um.
CCur(x)
Wandelt einen beliebigen Datentyp x in den Datentyp Currency um.
CDate(x)
Wandelt einen beliebigen Datentyp x in den Datentyp Date um.
CDbl(x)
Wandelt einen beliebigen Datentyp x in den Datentyp Double um.
Chr(n)
Liefert das n-te Zeichen des ASCII-Zeichensatzes.
CInt(x)
Wandelt einen beliebigen Datentyp x in den Datentyp Integer um.
CLng(x)
Wandelt einen beliebigen Datentyp x in den Datentyp Long um.
CSng(x)
Wandelt einen beliebigen Datentyp x in den Datentyp Single um.
CStr(x)
Wandelt einen beliebigen Datentyp x in den Datentyp String um.
CVar(x)
Wandelt einen beliebigen Datentyp x in den Datentyp Variant um.
Format(n, "xxx")
Wandelt n in eine Zeichenkette unter Berücksichtigung des Formats xxx um.
Str(n)
Wandelt n in eine Zeichenkette um.
Val(s)
Liefert den Wert der numerischen Zeichenkette s.
Tabelle 3.12: Funktionen zur Umwandlung von Datentypen
Im konkreten Fall des Zahlenlochbeispiels wird eine Umwandlungsfunktion von String nach Integer benötigt, also die Funktion CInt. Es ist in diesem Fall nicht relevant, welche der drei Umwandlungsfunktionen eingesetzt wird, da der Eingabewert immer ein Zeichen, also vom Typ String ist. Könnte der Eingabewert auch vom Typ Date sein, müßte die Funktion CStr gewählt werden, da allein die Funktionen Str und Format numerische Variablen in Zeichenketten umwandeln können. Um nun die gesamte Zahl Ziffer für Ziffer zu analysieren, muß jede Stelle mit einer Schleife geprüft werden. Hier bietet sich nun eine ForSchleife an, da die Anzahl der Schleifendurchläufe bekannt ist. Die Menge der Durchläufe muß mit der Menge der Ziffern, die die Zahl hat, identisch sein. Im Programm ist die Zahl aber als Zeichenkette bekannt, wobei die Anzahl der Zeichen mit der Anzahl der Ziffern der Ausgangszahl identisch ist.
77
Sandini Bib
Um nun die Anzahl der Zeichen einer Zeichenkette zu ermitteln, kann die Funktion Len(s) eingesetzt werden, die die Anzahl der Zeichen der Zeichenkette s zurückliefert. Der folgende Programmcode ermittelt die Anzahl der geraden und ungeraden Zahlen: Ungerade = 0 Gerade = 0
'Setze die Variablen zum Zählen der 'geraden 'und ungeraden Zahlen auf 0
for i = 1 to Len(Ergebnis) 'Solange das Ende der 'Zeichenkette nicht erreicht 'ist, if CInt(Mid(Ergebnis, i, 1)) Mod 2 = 0 Then 'prüfe, ob es sich bei der 'Ziffer um eine Gerade = Gerade + 1 'gerade Zahl Else 'oder Ungerade = Ungerade + 1 'um eine ungerade Zahl 'handelt End If next i 'Prüfe die nächste Ziffer
Die in diesem Programmcode enthaltene Funktion Mid$(s, i, l) dient dazu, einen Teil der Zeichenkette s zurückzuliefern. Dabei handelt es sich um den Teil, der sich in der Zeichenkette s ab Position i befindet und die Länge l hat. Befehl
Ergebnis
Mid$("Dies ist eine Zeichenkette", 2, 9)
ies ist e
Mid$("Dies ist eine Zeichenkette", 23, 8)
ette
Mid$("Dies ist eine Zeichenkette", 3, 0) Tabelle 3.13: Beispiel für die Funktion „Mid$“
Die Funktion Mod der folgenden Befehlszeile if CInt(Mid$(Ergebnis, i, 1)) Mod 2 = 0 Then
entspricht der Funktion Modulo. Die Funktion Modulo liefert immer den Restwert einer Division zurück. Hierzu ein Beispiel: 7 --- = 3 Rest 1 7 Modulo 2 = 1 2 8 --- = 4 Rest 0 2
78
8 Modulo 2 = 0
Sandini Bib
Ermitteln des Ergebnisses und Berechnen der neuen Zahl An dieser Stelle des Programms sind alle drei Werte, die zur Berechnung der neuen Zahl benötigt werden, bekannt: die Anzahl der ungeraden und geraden Zahlen sowie – mit Hilfe der Funktion Len – die Anzahl der Ziffern der Ausgangszahl. Diese Daten bilden nun die neue Zahl. Die einzelnen Zahlen müssen jedoch nicht nach einem bestimmten Algorithmus addiert, sondern wie einzelne Zeichenketten aneinandergereiht werden.
Berechnen der neuen Zahl anhand der analysierten Ziffern der Ausgangszahl
Die folgende Programmzeile führt diese Aneinanderreihung aus: Ergebnis = CLng(CStr(Gerade) & CStr(Ungerade) & CStr(Len(Ergebnis)))
Abbildung 3.14: Verknüpfung der ermittelten Ergebnisse
Ausgabe des Ergebnisses Zu guter Letzt muß das Ergebnis auch noch auf dem Bildschirm des Benutzers ausgegeben werden. Wenn bei jedem Schleifendurchlauf die ermittelte Zahl in die ListBox geschrieben wird, sind alle Berechnungen über die Zwischenschritte nachvollziehbar. Die folgende Programmzeile schreibt das neu berechnete Ergebnis immer in die erste Zeile der ListBox Ergebnis: Wertigkeit.Additem CStr(Ergebnis), 0
Die gesamte Funktion zur Berechnung des Zahlenloches 123 Nun sind alle Befehlszeilen des Pseudocodes in Visual Basic-Programmcode umgewandelt worden. Im folgenden ist nun die gesamte Funktion, die zum Button OK gehört, abgebildet.
79
Sandini Bib
Private Sub Ok_Click() Dim Ergebnis As String Dim Gerade As Integer Dim Ungerade As Integer Dim i As Integer If IsNumeric(Zahl.Text) then 'Wenn die Zahl ' vom Typ Long ist Ergebnis = Zahl.Text Else Exit Sub End If While Val(Ergebnis) 123 Ungerade = 0 'Setze die Variablen zum ' Zählen der geraden Gerade = 0 'und ungeraden Zahlen auf 0 for i = 1 to Len(Ergebnis) 'Solange das Ende 'der Zeichenkette nicht 'erreicht ist, if CInt(Mid(Ergebnis, i, 1)) Mod 2 = 0 Then 'prüfe, ob es sich bei der 'Ziffer um eine Gerade = Gerade + 1 'gerade Zahl Else 'oder Ungerade = Ungerade + 1 'um eine 'ungerade Zahl handelt End If next i 'Prüfe die nächste Ziffer
Ergebnis = CLng(CStr(Gerade) & _ CStr(Ungerade) & _ CStr(Len(Ergebnis))) Wertigkeit.Additem CStr(Ergebnis), 0 Wend End Sub
Wenn das Programm gestartet wird, kann die Oberfläche wie in Abbildung 3.15 dargestellt aussehen.
80
Sandini Bib
Abbildung 3.15: Mögliche Oberfläche des Programms „Zahlenloch 123“
Um das Programm zu testen, ist es sinnvoll, Werte zu wählen, bei denen das Ergebnis und die Zwischenschritte bekannt sind. In diesem Fall bieten sich die Zahlen aus der Abbildung 3.15 an, da für diese Zahlen schon alle Zwischenschritte berechnet wurden. In der ListBox müssen alle Zahlen in der gleichen Reihenfolge wie in der Beispieltabelle auftreten.
3.3.5
Größere Benutzerfreundlichkeit
Bei vielen Programmen erhält man in Form einer sog. Statusleiste für die meisten Steuerelemente auf der Programmoberfläche eine schnelle Hilfe. In Visual Basic ist diese schnelle Hilfe recht einfach zu realisieren.
Erhöhen der Benutzerfreundlichkeit durch Einsatz einer Statuszeile
Als Statusleiste wird ein Steuerelement benötigt, das der Ausgabe dient, in dem aber keine Eingabe gemacht werden darf. Darüber hinaus ist es nicht möglich, mehrere Datensätze darzustellen. In der Tabelle 4.11 wurden verschiedene Ausgabesteuerelemente verglichen. Aus diesem Grund wird für die Statusleiste das Steuerelement Label verwendet. Wie alle anderen Steuerelemente wird die Statusleiste durch Aktivieren des Symbols im Werkzeugfenster und durch Festlegen der Position und Größe infolge von Anklicken und Ziehen des Steuerelements mit Hilfe der Maus erzeugt. Die Statusleiste läßt sich optisch hervorheben, indem bei der Eigenschaft BorderStyle die Option 1FestEinfach (Abbildung 3.15) eingestellt wird. Mit der Statusleiste wird erreicht, daß zu jedem Steuerelement eine Hilfetext ausgegeben werden kann, wenn der Mauszeiger über das jeweilige Steuerelement bewegt wird.
81
Sandini Bib
Fast jedes Steuerelement besitzt die Eigenschaft Tag, die keinen Einfluß auf das Steuerelement selbst hat. In dieser Eigenschaft kann zu jedem Steuerelement ein kurzer Beschreibungstext eingegeben werden. Steuerelement
Beschreibungstext
Button OK
Hiermit wird das Programm gestartet.
Button ABBRECHEN
Hiermit wird die Berechnung beendet.
ListBox
Hier sind alle Zwischenschritte der Berechnung enthalten.
TextBox
Bitte geben Sie hier die zu berechnende Zahl ein.
Form Tabelle 3.14: Beschreibungstexte der Steuerelemente4
Der Eigenschaft Tag des Formularfensters Form ist eine sog. leere Zeichenkette zugewiesen worden, da in der Statuszeile auch kein Hilfetext ausgegeben werden soll, wenn der Mauszeiger auf keines der Steuerelemente zeigt. Um den Inhalt der Eigenschaft Tag eines jeden Steuerelements der Eigenschaft Caption der Statusleiste zuzuweisen, wird die Funktion MouseMove benötigt. MouseMove wird dann ausgeführt, wenn das jeweilige Steuerelement mit der Maus angesteuert wird. Für jedes Steuerelement, das in der Statusleiste einen Hilfetext enthalten soll, muß die Funktion MouseMove wie folgt angepaßt werden: Form Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) Status.Caption = Form.Tag End Sub
Der Button OK Private Sub Ok_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) Status.Caption = Ok.Tag End Sub
4. In der Eigenschaft Tag der Form ist eine Zeichenkette mit der Länge 0 eingetragen
82
Sandini Bib
Der Button ABBRECHEN Private Sub Abbruch_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) Status.Caption = Abbruch.Tag End Sub
Die ListBox zur Ausgabe der Zwischenschritte Private Sub Wertigkeit_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) Status.Caption = Wertigkeit.Tag End Sub
Die TextBox zur Eingabe der Ausgangszahl Private Sub Zahl_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) Status.Caption = Zahl.Tag End Sub
83
Sandini Bib
Sandini Bib
4
Standardsteuerelemente
In diesem Kapitel wird ein kurzer Überblick über einen Teil der Steuerelemente gegeben, die von Visual Basic standardmäßig mitgeliefert werden. Mit kleinen Beispielprogrammen zu jedem Steuerelement werden dessen jeweiligen Aufgaben erklärt. Dabei wird auch auf die wichtigsten Funktionen und Eigenschaften der Steuerelemente eingegangen.
Elemente für die Programmsteuerung, Dateieingabe und -ausgabe sowie die Gestaltung der Formulare
Das entstandene Programm aus den Beispielen der Objekte Form, Button und Label soll in einem eigenen Verzeichnis unter dem Namen VORGABE gespeichert werden. Es wird als Grundlage für alle anderen Beispiele gelten, um den Programmieraufwand so gering wie möglich zu halten.
4.1
Das Formular Form Das Fenster eines Programmes
Abbildung 4.1: Das Formular im Designmodus
Auf Formularen (siehe Abbildung 4.1) werden die Steuerelemente, die zur Programmsteuerung und Darstellung der Informationen gebraucht werden, aufgebracht. Sie sind die Fenster des Programms. Jedes Visual Basic-Programm benötigt mindestens ein Formular: das
85
Sandini Bib
Startformular. Ein Programm kann aber auch aus mehreren Formularen bestehen. Um für ein Formular den Programmcode zu entwikkeln, muß der Editor (siehe Abbildung 4.1) geöffnet werden. Mit einem Doppelklick der linken Maustaste auf das Formular oder auf ein Steuerelement, das sich auf dem Formular befindet, wird das Fenster zur Eingabe des Programmcodes geöffnet. In der ListBox Object läßt sich das Objekt, zu dem der Programmcode gehören soll, auswählen. Nach dem Programmstart ist das einzige Objekt jedoch nur das Formular Form. Unter General werden alle Funktionen, Prozeduren, Konstanten und Variablen abgelegt, auf die alle Steuerelemente des Formulars zugreifen sollen. Hier wird auch definiert, ob alle Variablen, die in dem Formular verwendet werden, vor der ersten Anwendung auch deklariert sein müssen. Um diese Einstellung zu aktivieren, muß die folgende Zeile Option Explicit
in den Abschnitt Object = General und Proc = declarations eingegeben werden. Nun müssen alle Variablen, die in diesem Formular verwendet werden, auch deklariert werden. Eigenschaft
mögliche Wert
Beschreibung
(Name)
String
Der Name identifiziert das Fenster im Programmcode.
Appearance
0 - Flat 1 - 3D
Mit dieser Eigenschaft wird angegeben, ob das Fenster im neuen 3D-Design von Windows 95 oder in der alten Darstellung gezeigt wird.
AutoRedraw
True/False
Diese Eigenschaft gibt an, ob das Fenster nach jedem Aktivieren neu gezeichnet werden soll.
BackColor
0 - 16777,215 (&HFFFFFF)
Mit dieser Eigenschaft wird die Hintergrundfarbe des Fensters eingestellt (Abschnitt ).
Caption
String (Max 255. Zeichen)
In Caption wird die Beschriftung des Fensters eingetragen, die während des Programmlaufs sichtbar ist.
MDIChild
True/False
Diese Eigenschaft gibt an, ob es sich bei dem aktuellen Fenster um ein Fenster im Fenster handelt.
Tag
String
Steht zur freien Verfügung, d. h. es hat keinen direkten Einfluß auf das Steuerelement, sondern kann z.B. als Zwischenspeicher für das Steuerelement dienen.
ToolTipText
String
Der Inhalt dieser Eigenschaft wird in einer Sprechblase als Erklärung zu einem Steuerelement ausgegeben, wenn sich die Maus über dem Steuerelement befindet.
Tabelle 4.1: Die wichtigsten Eigenschaften des Fensters
Eine der wichtigsten Ereignisprozeduren des Formulars ist die Funktion Load. Deren wichtigste Eigenschaften sind Caption und Name.
86
Sandini Bib
In der Eigenschaft Name wird der Name des Formulars angegeben, unter dem es den anderen Objekten in diesem Programm bekannt sein soll. Bei der Namensvergabe sollte darauf geachtet werden, daß die Objektart in den Namen aufgenommen wird, beispielsweise indem die ersten drei Buchstaben das Objekt beschreiben. Bei einem Formular bietet sich die Abkürzung frm an. Der festgelegte Name findet sich auch rechts im Projektfenster wieder. Der Name, der vom System beim Erstellen eines neuen Programms vorgegeben wird, ist Form1. Die Eigenschaft Caption enthält den Titel oder die Beschreibung des Fensters. Der hier angegebene Text wird in der blauen Titelleiste des Fensters angezeigt. Der standardmäßige Parameter für die Eigenschaft Caption ist Form1.
4.1.1
Aufgabe
Das folgende Programmbeispiel soll beim Starten des Programms den Titel „Beispiel” in die Kopfzeile des Fensters schreiben.
4.1.2
Eine Aufgabe zum Formular
Lösung
Als erstes wird der Name des Formulars festgelegt; wir wählen hierzu frm_Beispiel. Der Eigenschaft Caption braucht kein Parameter zugewiesen zu werden, da in diesem Fall mit einer Konstanten gearbeitet werden soll. Weitere formularglobale Konstanten und Variablen werden nicht gebraucht. Also ergeben sich für den Abschnitt
Die Lösung zur Formularaufgabe
Object = General und Proc = declarations folgende Programmzeilen: Option Explicit Const Titel = "Beispiel"
Um das Programm beim Starten etwas ausführen zu lassen, besitzt das Formular die Funktion Form_Load(). Diese Funktion wird bei jedem Programmstart ausgeführt, daher muß hier der Programmcode geschrieben werden, um den Titel des Fensters zu beschriften. Private Sub Form_Load() frm_Beispiel.Caption = Titel End Sub
Wenn das Programm jetzt gestartet wird, erscheint in der Titelzeile des Fensters der Titel „Beispiel”. Das Programm kann mit der Tastenkombination (Alt)+(F4) oder über das Menü RUN | END beendet werden.
87
Sandini Bib
4.2
Das Textelement Label
Abbildung 4.2: Das Textelement „Label”
Das Textelement Label dient für die Beschriftung anderer Steuerelemente oder zur Ausgabe von Texten. Es kann nicht zur Texteingabe genutzt werden. Ein weiterer wichtiger Anwendungsbereich für Label ist die Verwendung der Statusleiste. In vielen Programmen ist es Standard, daß zu jedem Steuerelement ein Hilfetext in der Statuszeile ausgegeben wird. Um ein Steuerelement als Label zu markieren, bieten sich hier die drei Anfangsbuchstaben lab als Kennzeichnung des Namens an.
4.2.1 Eine Aufgabe zum Textelement
Zur Ausgabe eines Hilfetextes soll eine Statuszeile auf das aktuelle Formular aufgebracht werden. Der Text, der in der Statuszeile dargestellt wird, soll zentriert sein, und das Label soll optisch den Eindruck erwecken, als sei es in das Formular eingelassen.
4.2.2 Die Lösung zur Textelementaufgabe
Aufgabe
Lösung
Zunächst muß ein Label auf das geöffnete Formular als Fußzeile auf das Fenster aufgebracht werden. Um die gestellte Aufgabe zu lösen, ist kein Programmieraufwand nötig, sondern es müssen die richtigen Eigenschaften eingestellt werden. Vergessen Sie nicht die Kennzeichnung als Label im Objektnamen. Deshalb erhält das Steuerelement den Namen lab_Status. Damit nach dem Programmstart kein Text in der Statuszeile steht, muß die Eigenschaft Caption des Labels leer sein. Für die Ausrichtung des Textes in einem Label ist die Eigenschaft Alignment zuständig. Um den Text zentriert auszugeben, muß hier der Wert 2 – Center eingestellt werden. Dieser kann entweder über die Eingabe einer 2 oder das Auswählen dieser Option über die angebotene ListBox erfolgen. Als letzte Eigenschaft wird nun der 3D-Effekt eingeschaltet, damit die Statuszeile optisch versenkt auf dem Bildschirm erscheint. Dazu muß die Eigenschaft Border Style den Wert 1 – Fixed Single bekommen.
88
Sandini Bib
Um nach dem Programmstart mit Sicherheit auszuschließen, daß Text in der Eigenschaft Caption enthalten ist, kann die Funktion Load des Formulars wie folgt angepaßt werden. Private Sub Form_Load() frm_Beispiel.Caption = Titel lab_Status.Caption = "" End Sub
Nun ist sichergestellt, daß es keinen Eintrag in der Statuszeile gibt, wenn das Programm gestartet wird. Selbst in der Eigenschaft Caption könnte ein Wert eingetragen sein.
4.3
Die Schaltfläche Button
Abbildung 4.3: Die Schaltfläche „Button“
Ein Button wird z.B. für das Bestätigen von Eingaben oder für das Starten von Prozessen eingesetzt. Die bekanntesten Schaltflächen sind die Buttons OK und ABBRECHEN. Auch im vorliegenden Beispiel wird dieses Steuerelement für beide Buttons verwendet. Die wichtigste Funktion der Schaltfläche ist die Ereignisprozedur Click. Diese Ereignis reagiert auf das Aktivieren der Schaltfläche. Bei den Eigenschaften ist außer Name und Caption die Eigenschaft Tag von großer Bedeutung. Sie hat zwar keinen Einfluß auf das Aussehen oder die Darstellung des Steuerelements, man kann dort aber die Beschreibung des Steuerelements ablegen. Für die Kennzeichnung des Buttons als Steuerelement im Namen wird im weiteren Verlauf btn verwendet.
4.3.1
Aufgabe
Es sollen zwei Schaltflächen auf das Formular aufgebracht werden. Die eine Schaltfläche ABBRUCH dient zum Beenden des Programms, die andere Schaltfläche OK dient zum Starten einer Aufgabe. In diesem Fall soll die Aufgabe darin bestehen, zu zählen, wie oft die Schaltfläche OK betätigt wurde, und den ermittelten Wert in der Titelleiste des Fensters auszugeben. Außerdem soll in der Statuszeile eine Beschreibung zu der Aufgabe der jeweiligen Schaltfläche ausgegeben werden.
Eine Aufgabe zur Schaltfläche
89
Sandini Bib
4.3.2 Die Lösung zur Aufgabe Schaltfläche
Lösung
Zuerst werden die beiden Schaltflächen auf die Form gebracht. Die erste Schaltfläche erhält bei der Eigenschaft Namen den Wert btn_Ok und bei der Eigenschaft Caption den Wert Ok. Die andere Schaltfläche erhält den Namen btn_Abbrechen und die Beschriftung ABBRECHEN. Die wichtigste Funktion aller Programme, die leider viel zu oft vergessen wird, ist das Beenden eines Programms. Aus diesem Grund wird hier mit diesem Teil begonnen. Um ein Programm zu beenden, gibt es den Befehl End. Er beendet das Programm von jeder Prozedur aus, von der er aufgerufen wird. Da die Schaltfläche durch Betätigen der Maustaste das Programm beenden soll, erhält die Funktion Click der Schaltfläche btn_Abbrechen den Befehl End. Private Sub btn_Abbrechen_Click() End End Sub
Die Aufgabe des Buttons btn_Ok besteht darin, zu zählen, wie oft der Button gedrückt wurde, und anschließend die ermittelte Anzahl in der Titelleiste des Fensters auszugeben. Diese Aufgabe wird ebenfalls über die Funktion Click gelöst, jedoch dieses Mal über das Click-Ereignis des Schaltelements mit Namen btn_Ok. Private Sub btn_Ok_Click() Anzahl = Anzahl + 1 'Registriert einen neuen 'Tastendruck 'Aktualisiert den Inhalt der Fenstertitelleiste Fenster.Caption = Titel & " Anzahl = " & Anzahl End Sub
Die Variable Anzahl, die zum Zählen der OK-Tastenanschläge gebraucht wird, ist eine globale Variable. Ihr Wert muß auch nach Verlassen der Funktion Click dem Programm bekannt sein, um beim nächsten Betätigen den alten Wert um eins erhöhen zu können. Die folgende Programmzeile muß im globalen Funktionsteil des Formulars eingetragen werden. Dim Anzahl As Integer
'Zählt die Anzahl der 'Tastendrücke OK
Initialisiert wird die Variable beim Programmstart mit dem Standardwert 0. Visual Basic initialisiert zwar selbständig alle numerischen Variablen mit 0; jedoch ist es für die Übersichtlichkeit des Programmcodes besser, diese Zuweisung nochmals in der Ereignisprozedur Load des Formulars auszuführen.
90
Sandini Bib
Private Sub Form_Load() frm_Beispiel.Caption = Titel lab_Status.Caption = "" Anzahl = 0 End Sub
Wenn das Programm nun gestartet und mit der Maus auf die Schaltfläche Ok gedrückt wird, so erscheint die geforderte Ausgabe in der Titelleiste des Fensters. Mit Betätigung der Schaltfläche Abbrechen wird das Programm sinngemäß beendet. Jetzt fehlt noch die Ausgabe des Hilfetextes zu der jeweiligen Schaltfläche in der Statuszeile. Die meisten Steuerelemente bieten hierfür die Funktion MouseMove an. Die Funktion MouseMove wird aktiviert, wenn die Maus über das jeweilige Steuerelement bewegt wird. Für den Hilfetext, der in der Statuszeile ausgegeben werden soll, kann man die Eigenschaft Tag, die ebenfalls von den meisten Steuerelementen unterstützt wird, nutzen. Die Schaltfläche btn_Ok erhält in der Eigenschaft Tag den Wert „Hiermit werden die Eingaben bestätigt.”, und die Schaltfläche btn_Abbrechen erhält den Wert „Hiermit wird das Programm beendet.”. Private Sub btn_Ok_MouseMove(Button As Integer, _ Shift As Integer, X As Single, Y As Single) lab_Status.Caption = btn_Ok.Tag End Sub
Private Sub btn_Abbrechen_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) lab_Status.Caption = btn_Abbrechen.Tag End Sub
Mit diesen Funktionen werden nun die Hilfetexte der Schaltelemente in der Statuszeile ausgegeben, wenn die Maus über das jeweilige Steuerelement bewegt wird. Wenn aber einmal ein Text in der Statuszeile ausgegeben wurde, wird dieser nur noch geändert, wenn die Maus über ein anderes Steuerelement bewegt wird, welches ebenfalls die Funktion MouseMove verwendet. In diesem konkreten Fall heißt das: wird die Maus über den Button OK bewegt, ändert sich der Text in der Statuszeile erst, wenn die Maus über den Button ABBRECHEN bewegt wird. Um nun den Inhalt der Statuszeile jedesmal zu löschen, wenn das Steuerelement wieder verlassen wird, muß die Statuszeile mit einer Funktion gelöscht werden. Dazu eignet sich die Funktion MouseMove des Formulars, da sich die Maus entweder auf einem Steuerelement befindet, d. h. Statustext anzeigt, oder auf dem Formular, d. h. keinen Statustext anzeigt.
91
Sandini Bib
Private Sub Form_MouseMove(Button As Integer, _ Shift As Integer, X As Single, Y As Single) lab_Status.Caption = frm_Beispiel.Tag End Sub
Bewegt man die Maus über ein Steuerelement, wird in der Statuszeile der Text ausgegeben, der in der Eigenschaft Tag enthalten ist. Da hier der Inhalt fehlt, fehlt auch der Text in der Statuszeile. Um eine vergleichbare Oberfläche zu haben, sollte sie wie in Abbildung 4.4 aussehen.
Abbildung 4.4: Das Standardformular für die weiteren Beispiele
4.4
Das Texteingabeelement TextBox
Abbildung 4.5: Das Texteingabeelement „TextBox”
Das Texteingabeelement TextBox dient dem Benutzer zur Eingabe von Daten, also zur Kommunikation mit dem Programm über die Tastatur. Für die Identifizierung des Steuerelements im Programmcode wird im folgenden die Kennung txt verwendet.
4.4.1 Eine Aufgabe zum Textelement
92
Aufgabe
Es soll ein Programm entwickelt werden, mit dem Längenmaße umgerechnet werden können. Dafür werden zwei Texteingabeelemente benötigt. Das erste Element txt_Wert dient zum Erfassen des Ursprungsmaßes, beispielsweise Kilometer. In das zweite Element txt_Faktor wird der Umrechnungsfaktor eingegeben. Bei der Umrech-
Sandini Bib
nung z.B. von Kilometer in Seemeilen beträgt dieser Faktor 1,852. Das Ergebnis wird beim Drücken des Buttons OK berechnet und in ein Label lab_Ergebnis geschrieben. Wird ein Eingabewert verändert, soll der Inhalt des Labels lab_Ergebnis gelöscht werden.
4.4.2
Lösung
Option Explicit
Die Lösung zur Aufgabe Textelement
Private Sub btn_Ok_Click() If txt_Wert.Text"" And txt_Faktor.Text"" Then lab_Ergebnis.Caption = CDbl(txt_Wert.Text) * _ CDbl(txt_Faktor.Text) End If End Sub Private Sub txt_Faktor_Change() lab_Ergebnis.Caption = "" End Sub Private Sub txt_Wert_Change() lab_Ergebnis.Caption = "" End Sub
4.5
Das Bildfeldsteuerelement PictureBox
Abbildung 4.6: Das Bildfeldsteuerelement „PictureBox”
Um auf einem Formular Grafiken anzuzeigen, stellt Ihnen Visual Basic das Steuerelement PictureBox zur Verfügung. In diesem Grafikfenster können Grafiken folgender Typen dargestellt werden:
Bitmap (*.bmp; *.dib)
Windows-Metafile (*.wmf)
Icon (*.ico; *.cur)
Es können aber nicht nur Bilder eingebunden, sondern auch eigene Zeichnungen erstellt werden. Das folgende Programm zeichnet ein paar Linien in verschiedenen Farben in die PictureBox. Für die Identifizierung des Steuerelements wird die Kennung pic für Picture ver-
93
Sandini Bib
wendet. Daraus ergibt sich der Name pic_Bild für das folgende Beispiel. Sub Linien_Zeichen() Const Anzahl_Linien = 15 'Anzahl der zu zeichnenden 'Linien Dim i As Integer Dim Breite As Integer 'Breite der PictureBox Dim Hoehe As Integer 'Höhe der PictureBox Dim delta_x As Double 'Größe der horizontalen 'Schrittweite Dim delta_y As Double 'Größe der vertikalen 'Schrittweite If Anzahl Mod 2 = 0 Then 'Wenn die PictureBox 'gelöscht werden soll pic_Bild.Cls 'Lösche den Inhalt der 'PictureBox Exit Sub 'Beende die Prozedur End If Breite = pic_Bild.ScaleWidth 'Ermittle die Breite 'der PictureBox Hoehe = pic_Bild.ScaleHeight 'Ermittle die Höhe 'der PictureBox delta_y = Hoehe / Anzahl_Linien 'Berechne die 'vertikale Schrittweite For i = 0 To Anzahl_Linien 'Zeichne Anzahl_Linien pic_Bild.ForeColor = QBColor(i Mod 15) 'Setze ' die Zeichenfarbe 'Zeichne eine Linie pic_Bild.Line (0, i * delta_y)- _ (Breite, Hoehe - (i * (delta_y / 3))) Next i 'Zeichne die nächste Linie End Sub
Um die Funktion aus der Funktion btn_Ok_Click() aufzurufen, gibt es die beiden folgenden Möglichkeiten: 1. Linien_Zeichen 2. Call Linien_Zeichen
Für die Übersichtlichkeit des Programmcodes empfiehlt es sich, den zweiten Funktionsaufruf zu verwenden, da er den Programmcode übersichtlicher gestaltet. Damit die Grafik nicht verlorengeht, wenn ein anderes Fenster über das Grafikprogramm gelegt wird, muß die Eigenschaft AutoRedraw den Wahrheitswert TRUE erhalten.
94
Sandini Bib
Ist die Grafik größer als das Steuerelement, werden die Seiten abgeschnitten. Um die Größe eines Bildfeldsteuerelements an die Grafik anzupassen, muß der Eigenschaft AutoSize der Wert True zugewiesen werden.
4.6
Das Anzeigesteuerelement Image
Abbildung 4.7: Das Anzeigesteuerelement „Image”
Das Anzeigesteuerelement Image dient – wie zuvor bereits das Bildfeldsteuerelement – der Anzeige von Grafiken folgender Formate:
Bitmap (*.bmp; *.dib)
Windows-Metafile (*.wmf)
Icon (*.ico; *.cur)
In Abbildung 4.7 ist dem Anzeigesteuerelement schon eine Grafikdatei zugeordnet. Es handelt sich um die Datei BANNER.GIF. Diese Datei befindet sich unter dem Visual Basic-Stammverzeichnis im Ordner SAMPLES\PGUIDE\PALMODE. Das Anzeigesteuerelement hat den Vorteil, daß es weniger Systemressourcen benötigt und schneller dargestellt werden kann als das Bildfeldsteuerelement. Es unterstützt jedoch nicht den gleichen Umfang an Ereignissen, Eigenschaften und Methoden wie das Bildfeldsteuerelement. Um die Größe einer Grafik an das Steuerelement anzupassen, gibt es die Eigenschaft Stretch. Mit dieser Eigenschaft wird definiert, ob das Steuerelement an die Größe der Grafik angepaßt oder die Grafik an die Größe des Steuerelements angepaßt wird.
4.7
Das Rahmensteuerelement Frame
Abbildung 4.8: Das Rahmensteuerelement „Frame”
95
Sandini Bib
In das Rahmensteuerelement werden keine Daten eingegeben. Es dient dazu, andere Steuerelemente zusammenzufassen und diese als eine Einheit auf dem aktuellen Fenster zu behandeln. Es wird verwendet, um z.B. Steuerelemente mit der Eigenschaft Enabled = False zu sperren oder um die Zusammengehörigkeit einzelner Steuerelemente zu verdeutlichen.
4.8
Das Kontrollkästchen CheckBox
Abbildung 4.9: Das Kontrollkästchen-Steuerelement „CheckBox”
Mit dem Kontrollkästchen-Steuerelement lassen sich zum Beispiel Berechtigungen erteilen oder Optionen ein- und ausschalten. Um die Übersichtlichkeit von Programmen zu erhöhen, können mehrere Steuerelemente zu einzelnen Gruppen zusammengefaßt werden. Wenn ein Kontrollkästchen vom Anwender angeklickt wird, ändert sich der Zustand. Eine CheckBox kann entweder im Zustand „Wahr” oder „Falsch ” sein. Ist die Eigenschaft Value „Wahr”, befindet sich in dem Kästchen des Steuerelements ein Kreuz. Ist die Eigenschaft Value „Falsch”, so ist das Kästchen leer. Diesen Schalter kann man sich wie einen Schalter bei einem Kassettenrecorder vorstellen: Der Kassettenrecorder ist entweder eingeschaltet oder nicht eingeschaltet. Die Kontrollkästchen einer Gruppe haben keinen direkten Einfluß aufeinander. Für die Identifizierung des Steuerelements CheckBox im Programmcode wird die Kennung cbx im weiteren Verlauf verwendet. Eigenschaft
mögliche Werte
Beschreibung
(Name)
String
Über den Namen wird das Steuerelement im Programmcode angesprochen.
Caption
String
Diese Eigenschaft beinhaltet den Beschreibungstext rechts neben der CheckBox.
Tag
String
Diese Eigenschaft steht zur freien Verfügung, d. h. sie hat keinen direkten Einfluß auf das Steuerelement, sondern kann z.B. als Zwischenspeicher für das Steuerelement dienen.
ToolTipText
String
Der Inhalt dieser Eigenschaft wird in einer Sprechblase als Erklärung zu einem Steuerelement ausgegeben, wenn die Maus eine bestimmte Zeit über dem Steuerelement stehenbleibt.
Value
0 nicht aktiviert 1 aktiviert
Mit dieser Eigenschaft wird festgelegt oder geprüft, ob das Kontrollkästchen aktiviert oder deaktiviert ist.
Tabelle 4.2: Die wichtigsten Eigenschaften des Kontrollkästchens
96
Sandini Bib
4.8.1
Aufgabe
Es soll ein Programm erstellt werden, in dem per Schalter die Sichtbarkeit eines Textfensters eingestellt wird. Der zweite Button gibt seinen aktuellen Zustand in diesem Textfenster aus, d.h. das Kontrollkästchen-Steuerelement schreibt den Wert „Wahr” in das Textfeld, wenn es aktiviert ist; ist es nicht aktiviert, erscheint der Wert „Falsch”.
4.8.2
Eine Aufgabe zum Kontrollkästchensteuerelement
Lösung
Um ein Steuerelement unsichtbar zu machen, muß man auf die Eigenschaft Visible (sichtbar) zurückgreifen. Enthält die Eigenschaft Visible den Wert „Falsch”, ist das Steuerelement während der Programmausführung nicht sichtbar.
Lösung zur Aufgabe Kontrollkästchensteuerelement
Private Sub Form_Load() cbx_Sichtbar.Value = 1 'Textelement ist sichtbar cbx_wahr.Value = 1 'In das Textelement "Wahr" 'schreiben End Sub Private Sub cbx_Sichtbar_Click() If cbx_Sichtbar.Value = 1 Then 'Wenn das Kontroll'kästchen aktiv ist lab_Ausgabe.Visible = True 'zeige die TextBox, Else 'sonst lab_Ausgabe.Visible = False 'verstecke sie End If End Sub Private Sub cbx_wahr_Click() If cbx_wahr.Value = 1 Then
'Wenn das Kontroll'kästchen aktiv ist, lab_Ausgabe.Caption = "Wahr" 'schreibe "Wahr" in 'das Textelement, Else lab_Ausgabe.Caption = "Falsch" 'sonst schreibe '"Falsch" End If End Sub
97
Sandini Bib
4.9
Das Optionsfeld OptionButton
Abbildung 4.10: Das Optionsfeld „OptionButton”
Das Optionsfeld ist wie die CheckBox ein Schalter, der nur die Eigenschaften Wahr oder Falsch annehmen kann. Jedoch sind alle Optionsfeldsteuerelemente einer Gruppe, z.B. gruppiert durch ein Frame, voneinander abhängig. Immer nur ein Optionsschalter kann den Wert Wahr haben. Selektiert der Anwender einen Schalter, der den Zustand Falsch hat, wird der Schalter mit dem Zustand Wahr auf Falsch gesetzt, und dem selektierten Schalter wird der Zustand Wahr zugewiesen. Ein Schalter, der den Zustand Wahr hat, kann nicht durch nochmaliges Anklicken wieder auf Falsch gesetzt werden. Man kann sich diese Art von Schaltung wie bei einem Radio vorstellen: Es kann immer nur ein Programmschalter auf einmal ausgewählt sein, wobei auch immer einer der möglichen Programmschalter ausgewählt ist. In Visual Basic können damit auch verschiedene Berechtigungsstufen erteilt werden, so z.B.: 1. Der Anwender darf ein bestimmtes Textfeld nicht sehen. 2. Der Anwender darf ein bestimmtes Textfeld sehen, aber nicht ver-
ändern. 3. Der Anwender darf ein Textfeld sehen und ändern.
Um mehrere Optionsschalter zusammenzufassen, sollte immer ein Frame verwendet werden, um dem Benutzer zu signalisieren: „Diese Optionsschalter sind voneinander abhängig.” Ebenfalls lassen sich somit auch mehrere unabhängige Schalterleisten auf einem Fenster realisieren. Für die Identifizierung des Steuerelements Optionsschalter im Programmcode wird die Kennung obt empfohlen.
98
Eigenschaft
mögliche Werte
Beschreibung
(Name)
String
Über den Namen wird das Steuerelement im Programmcode angesprochen.
Caption
String
Diese Eigenschaft beinhaltet die Beschreibung rechts neben dem Schalter (Ausgabe für den Anwender).
Tag
String
Diese Eigenschaft steht zur freien Verfügung, d. h sie hat keinen direkten Einfluß auf das Steuerelement, sondern kann z.B. als Zwischenspeicher für das Steuerelement dienen.
Sandini Bib
Eigenschaft
mögliche Werte
Beschreibung
ToolTipText
String
Der Inhalt dieser Eigenschaft wird in einer Sprechblase als Erklärung zu einem Steuerelement ausgegeben, wenn die Maus eine bestimmte Zeit über dem Steuerelement stehenbleibt.
Tabelle 4.3: Die wichtigsten Eigenschaften des Optionenschalters
4.9.1
Aufgabe
Es soll ein Programm erstellt werden, in dem über drei Optionenschalter festgelegt wird, ob der Schalter OK unsichtbar, sichtbar oder verfügbar sein soll. Dazu werden drei Steuerelemente benötigt. Wegen der besseren Übersichtlichkeit sollen sie in einem Frame zusammengefaßt werden.
4.9.2
Eine Aufgabe zum Optionenschalter
Lösung
Um ein Steuerelement für die Eingabe des Benutzers zu sperren, gibt es die Eigenschaft Enabled (verfügbar). Ist der Wert der Eigenschaft Enabled „Wahr”, kann das Steuerelement für eine Eingabe genutzt werden, ist der Wert „Falsch”, so ist das Steuerelement zwar sichtbar, jedoch kann keine Eingabe gemacht werden.
Die Lösung zur Aufgabe Optionenschalter
Private Sub Form_Load() obt_Unsichtbar.Value = True call obt_Unsichtbar_Click 'Der Ok-Button wird 'unsichtbar End Sub Private Sub obt_Sichtbar_Click() btn_Ok.Enabled = False 'Ok-Button nicht verfügbar btn_Ok.Visible = True 'Ok-Button sichtbar End Sub Private Sub obt_Unsichtbar_Click() btn_Ok.Enabled = False 'Ok-Button nicht verfügbar btn_Ok.Visible = False 'Ok-Button nicht sichtbar End Sub Private Sub obt_Verfügbar_Click() btn_Ok.Enabled = True 'Ok-Button verfügbar btn_Ok.Visible = True 'Ok-Button sichtbar End Sub
! !
99
Sandini Bib
4.10
Das Listenfeld ListBox
Abbildung 4.11: Das Listenfeldsteuerelement „ListBox”
In einer ListBox können, wie der Name schon sagt, Listen angezeigt werden. Die einzelnen Zeilen der Liste können auch mehrspaltige Datensätze enthalten, die durch ein bestimmtes Zeichen getrennt werden. Die Listen können über Bildlaufleisten gescrollt, einzelne Listenelemente dabei ausgewählt werden; direkte Eingabe von Daten in das Listenfeld-Steuerelement ist jedoch nicht möglich. Diese Steuerelemente werden z.B. verwendet, um Dateien in einem Verzeichnis anzuzeigen. Die Liste mit den Dateien kann gescrollt werden, und es lassen sich auch Dateien auswählen. Um aber z.B. den Dateinamen zu ändern, muß ein anderes Steuerelement verwendet werden. Für die Verwaltung der Datensätze eines Listenfeld-Steuerelements stehen einige Befehle zur Verfügung. Im folgenden werden die wichtigsten Befehle aufgeführt. Eigenschaft
mögliche Werte
Beschreibung
(Name)
String
Über den Namen wird das Steuerelement im Programmcode angesprochen.
ColCharacter
Byte
Diese Eigenschaft gibt an, welches Zeichen aus der ASCII-Tabelle als Spaltentrennzeichen genommen werden soll.
ListCount
Integer
Diese Eigenschaft enthält die Anzahl der in die Liste eingetragenen Zeilen; sie kann nur gelesen werden.
Listindex
Integer
Diese Eigenschaft enthält die Nummer der momentan selektierten Zeile des Listenelements; sie kann gelesen und geändert werden.
Tag
String
Diese Eigenschaft steht zur freien Verfügung, d. h. sie hat keinen direkten Einfluß auf das Steuerelement, sondern kann z.B. als Zwischenspeicher für das Steuerelement dienen.
Text
String
Diese Eigenschaft enthält die Zeichenkette des markierten Datensatzes in dem Listenelement.
ToolTipText
String
Der Inhalt dieser Eigenschaft wird in einer Sprechblase als Erklärung zu einem Steuerelement ausgegeben, wenn die Maus eine bestimmte Zeit über dem Steuerelement stehenbleibt.
Tabelle 4.4: Die wichtigsten Eigenschaften des Listenfeldsteuerelements
100
Sandini Bib
4.10.1
Einen neuen Datensatz eintragen
Mit dem Befehl AddItem können neue Datensätze dem ListenfeldSteuerelement hinzugefügt werden.
Eintragen eines neuen Datensatzes in ein Listenfeldsteuerelement
[ListBoxname].AddItem Datensatz[, Position]
Bei dem Datensatz kann es sich um einen einfachen String oder um eine Zahl handeln, die zu einem String konvertiert wird. Es kann sich aber auch um einen komplexeren Datensatz handeln, dessen Spalten mit einem Sonderzeichen getrennt sind.
4.10.2
Einen Datensatz löschen
Mit dem Befehl RemoveItem wird ein Datensatz aus dem ListenfeldSteuerelement entfernt. Durch Angabe einer Datensatznummer kann gezielt ein Datensatz aus der gesamten Liste zum Löschen ausgewählt werden.
4.10.3
Löschen eines Datensatzes im Listenfeldsteuerelement
Den gesamten Inhalt des ListenfeldSteuerelements löschen
Mit dem Befehl Clear werden alle Datensätze, die im ListenfeldSteuerelement eingetragen sind, gelöscht.
Alle Datensätze eines Listenfeldsteuerelements löschen
4.10.4
Aufgabe
Eine ListBox soll beim Programmstart mit Namen gefüllt werden. Bei einem Doppelklick auf einen bestimmten Namen wird dieser in eine zweite ListBox verschoben. Mit dem Button OK werden alle Namen aus der zweiten ListBox entfernt und wieder zurück in die erste verschoben. Bei jedem Namen, der mit Ok zurückverschoben wird, erscheint für kurze Zeit ein Meldungsfenster mit folgender Meldung: „Der Brief für Name wird soeben gedruckt.” Die Reihenfolge, in der die Briefe „gedruckt” werden, entspricht der, in der die Namen in die zweite ListBox eingetragen wurden. Um einen Namen, der versehentlich in die zweite ListBox kopiert wurde, wieder zu entfernen, muß ebenfalls ein Doppelklick auf den zu löschenden Namen erfolgen.
4.10.5
Eine Aufgabe zum Steuerelement Listenfeld
Lösung
Private Sub Form_Load() lst_Namen.AddItem ("Flink Fritze") lst_Namen.AddItem ("Hastig Hugo") lst_Namen.AddItem ("Simson Simone")
Die Lösung für die Aufgabe Listenfeldsteuerelement
" "
101
Sandini Bib
lst_Namen.AddItem ("Pundy Ale") lst_Namen.AddItem ("Super Man") End Sub Private Sub lst_Namen_DblClick() lst_Druck.AddItem (lst_Namen.Text) lst_Namen.RemoveItem (lst_Namen.ListIndex) End Sub Private Sub lst_Druck_DblClick() lst_Namen.AddItem (lst_Druck.Text) lst_Druck.RemoveItem (lst_Druck.ListIndex) End Sub Private Sub btn_Ok_Click() Dim i As Integer While lst_Druck.ListCount > 0 lst_Druck.ListIndex = 0 For i = 0 To 2000 'Die ersten 2000 'Fehlermeldungen ermitteln lab_Meldung.Caption = "Der Brief für " & _ lst_Druck.Text & " wird soeben gedruckt" DoEvents Next i Call lst_Druck_DblClick Wend lab_Meldung.Caption = "" End Sub
4.11
Das Kombinationsfeld Combobox
Abbildung 4.12: Das Kombinationsfeld „Combobox”
Die Combobox entspricht einer ListBox mit Eingabefeld. Zum einen kann durch Aufklappen der Combobox (Drücken des Pfeiles links neben der ComboBox) eine Liste dargestellt werden, aus der man eine Zeile auswählen kann, oder es kann ein Text in das Eingabefenster der Combobox eingegeben werden. Die Befehle der Combobox sind mit denen der ListBox (siehe Abschnitt „Einen neuen Datensatz eintragen“, „Einen Datensatz löschen“ und „Den gesamten Inhalt des Listenfeld-Steuerelements löschen“) identisch.
102
Sandini Bib
4.11.1
Aufgabe
Es soll nochmals ein Programm zum Umrechnen eines Wertes in einen anderen erstellt werden. Im Gegensatz zu dem ersten Beispiel soll das Steuerelement für den Umrechnungsfaktor jedoch eine Combobox sein, die schon folgende Umrechnungsfaktoren enthält:
Kilometer in Seemeilen,
Seemeilen in Kilometer,
Stunden in Minuten.
Eine Aufgabe für die ComboBox
Des weiteren können aber auch eigene Faktoren eingegeben werden, die nicht in die existierende Liste aufgenommen werden. Wenn ein eigener Faktor eingegeben oder ein Wert verändert wird, muß der Schalter OK gedrückt werden, um die Rechnung zu aktualisieren. Wird dagegen ein neuer Faktor aus der Liste ausgewählt, aktualisiert sich das Ergebnis automatisch.
4.11.2
Lösung
Private 'Die Call Call Call End Sub
Sub Form_Load() Combobox mit Vorgabewerten füllen cmb_Faktor.AddItem("1,852", 0) cmb_Faktor.AddItem("0,53996") cmb_Faktor.AddItem("60", 2)
Die Lösung zur Aufgabe ComboBox
Private Sub txt_Wert_Change() 'Löschen des alten Wertes im Ergebnislabel lab_Ergebnis.Caption = "" End Sub Private Sub cmb_Faktor_Change() 'Löschen des alten Wertes im Ergebnislabel lab_Ergebnis.Caption = "" End Sub Private Sub btn_Ok_Click() 'Sind Zahlen in der TextBox und der Combobox 'eingetragen, If txt_Wert.Text"" And cmb_Faktor.Text"" And _ IsNumeric(cmb_Faktor.Text) Then 'berechne das Ergebnis und gebe es im 'Ergebnislabel aus lab_Ergebnis.Caption=CStr(CDbl(txt_Wert.Text)* _ CDbl(cmb_Faktor.Text))
# ##
103
Sandini Bib
End If End Sub Private Sub cmb_Faktor_Click() 'Inhalt im Ergebnislabel entfernen lab_Ergebnis.Caption = "" 'Auslösen der Berechnung mit dem neu gewählten 'Faktor Call btn_Ok_Click End Sub
4.12
Die Bildlaufleisten ScrollBar
Abbildung 4.13: Die vertikale und horizontale Bildlaufleiste „ScrollBar”
Für das einfache Bewegen in großen Datenmengen oder auf einer großen Grafik wird von Visual Basic die Bildlaufleiste ScrollBar unterstützt. Diese Bildlaufleiste gibt es für das Bewegen in horizontaler und vertikaler Richtung. Des weiteren können Bildlaufleisten als Regler für bestimmte Programmeinstellungen wie
Helligkeit,
Lautstärke und
Geschwindigkeit
eingesetzt werden. Der bewegliche Balken auf der Bildlaufleiste – im folgenden Markierungsbalken genannt – zeigt dabei an, wie nah der eingestellte Wert sich am Minimum oder Maximum befindet. Die aktuelle Position des Markierungsbalkens wird programmintern über die Variable Value abgefragt. Der Wert der Eigenschaft Value kann eine beliebige ganze Zahl im Bereich von 0 bis einschließlich 32767 sein. Wird die Bildlaufleiste als Eingabe oder Ausgabe von bestimmten Regelbereichen eingesetzt, soll also etwa eine Lautstärkeregelung im Bereich von 1 bis 10 möglich sein, läßt sich über die Eigenschaften Min und Max der Intervallbereich der Bildlaufleiste anpassen.
104
Sandini Bib
4.12.1
Aufgabe
Es soll ein Programm entwickelt werden, das in einer TextBox immer den aktuellen Positionswert ausgibt, an dem sich der Markierungsbalken der Bildlaufleiste befindet.
4.12.2
ScrollBars
Lösung
Private Sub vsc_Zahl_Change() lab_Zahl.Caption = vsc_Zahl.Value End Sub
4.13
Eine Aufgabe für die
Die Lösung für die Aufgabe Scrollbars
Das Datei-, Verzeichnis- und Laufwerklistenfeld
Abbildung 4.14: Das Datei-, Verzeichnis- und Laufwerklistenfeld
Das Dateilistenfeld FileListBox, das Verzeichnislistenfeld DirListBox und das Laufwerklistenfeld DriveListBox sind ListBoxen, die von Visual Basic zur Verfügung gestellt werden, um Laufwerkstrukturen darzustellen. Im Dateilistenfeld werden alle Dateien, im Verzeichnislistenfeld die Verzeichnisse und im Laufwerklistenfeld schließlich alle bekannten Laufwerke angezeigt. Eigenschaft
mögliche Werte
Beschreibung
(Name)
String
Über den Namen wird das Steuerelement im Programmcode angesprochen.
Caption
String (Max. 255 Zeichen)
In Caption wird die Beschriftung des Fensters eingetragen, die während des Programmlaufs sichtbar ist.
Tag
String
Diese Eigenschaft steht zur freien Verfügung, d. h. sie hat keinen direkten Einfluß auf das Steuerelement, sondern kann z.B. als Zwischenspeicher für das Steuerelement dienen.
ToolTipText
String
Der Inhalt dieser Eigenschaft wird in einer Sprechblase als Erklärung zu einem Steuerelement ausgegeben, wenn die Maus eine bestimmte Zeit über dem Steuerelement stehenbleibt.
Tabelle 4.5: Die wichtigsten Eigenschaften der Datei-, Verzeichnis- und Laufwerklistenfelder
$%& $ " '
105
Sandini Bib
4.13.1 Eine Aufgabe zu den Listenfeldern
Es soll ein Programm geschrieben werden, mit dem zwei Verzeichnisse verglichen werden und das anschließend diejenigen Dateien auf dem Bildschirm ausgibt, die nur in einem Verzeichnis vorkommen.
4.13.2 Die Lösung zur Aufgabe Listenfelder
Aufgabe
Lösung
Zuerst muß gewährleistet werden, daß die ListBoxen der linken und der rechten Seite sich gegenseitig aktualisieren. Dafür wird das Ereignis Change der Laufwerks- und Verzeichnislistenfelder benötigt. Wird in einem Laufwerklistenelement das aktuelle Laufwerk geändert, muß dieses an das zugehörige Verzeichnislistenelement weitergegeben werden. Ebenso muß eine Änderung im Verzeichnislistenfeld sofort an das Dateilistenelement weitergegeben werden. Private Sub drv_links_Change() 'Dem Dateilistenfeld das neue Laufwerk melden pfd_links.Path = drv_Links.Drive End Sub Private Sub pfd_links_Change() 'Dem Dateilistenfeld den neuen Pfad melden dir_links.Path = pfd_links.Path 'Die Anzahl der gefundenen Dateien ausgeben If dir_links.ListCount = 1 Then lab_links.Caption = "Es gibt eine Datei" Else lab_links.Caption = _ "Es sind " & dir_links.ListCount & " Dateien" End If End Sub
Private Sub btn_Vergleich_Click() Static Button As String If btn_vergleich.Caption"&Vergleich beenden" Then 'Schaltflächensymbol merken Button = btn_vergleich.Caption 'Schaltfläche umbenennen btn_vergleich.Caption = "&Vergleich beenden" 'Verzeichnisbäume verstecken frm_links.Visible = False frm_rechts.Visible = False
106
Sandini Bib
'Vergleichsliste anzeigen lst_Vergleich.Visible = True lab_Vergleich.Visible = True 'Vergleich starten lab_Vergleich.Caption = "Prüfe das Verzeichnis" Call Vergleichen(dir_links, dir_rechts, _ lst_Vergleich) Call Anzahl_Dateien(lst_Vergleich.ListCount) Else 'Schaltflächenbeschriftung umbenennen btn_vergleich.Caption = Button 'Vergleichsliste verbergen lst_Vergleich.Visible = False lab_Vergleich.Visible = False 'Verzeichnisbäume anzeigen frm_links.Visible = True frm_rechts.Visible = True End If End Sub
Initialisierung des Programms Für die Initialisierung des Programms – d. h. die Aktualisierung der Listenfelder – müssen die folgenden Programmzeilen in das Ereignis Form_Load eingetragen werden.
Initialisieren der Laufwerke und Pfade
Private Sub Form_Load() Call drv_links_Change Call drv_rechts_Change End Sub
Vergleichen der Dateilistenfelder Um festzustellen, welche Dateien in welchem Listenfeld nicht vorkommen, müssen zuerst alle Dateien des ersten Listenfelds mit dem Inhalt des zweiten verglichen werden. Alle im zweiten Listenfeld nicht gefundenen Dateien werden nun in das Ergebnislistenfeld eingetragen. Danach muß geprüft werden, welche Dateien des zweiten Listenfeldes im ersten Dateilistenfeld enthalten sind. Diese werden dann ebenfalls in das Ergebnislistenfeld eingetragen.
Vergleichen des Inhaltes der ersten und zweiten DateiListBox
Private Sub Vergleichen(links As Control, _ rechts As Control, _ Ergebnis As Control) Dim l As Integer 'Zähler der Dateilistenfelder Dim r As Integer
$%& $ " '
107
Sandini Bib
Dim Gefunden As Boolean Ergebnis.Clear 'Prüfe, welche Dateien nicht im rechten Fenster _ 'enthalten sind For l = 0 To links.ListCount - 1 Gefunden = False For r = 0 To rechts.ListCount - 1 DoEvents If Trim(links.List(l)) = _ Trim(rechts.List(r)) Then Gefunden = True End If Next r If Gefunden = False Then Ergebnis.AddItem links.List(l) End If Next l ... Hier muß nun nochmals der Vergleich durchgeführt werden, mit dem Unterschied, daß das rechte Dateilistenelement in der äußeren Schleife ist. ... End Sub
In der vorhergehenden Prozedur wurde die neue Anweisung DoEvents eingeführt. Sie dient dazu, daß die Prozessorzeit an andere Prozesse abgegeben wird. Dies wird z.B. dann benötigt, wenn Ausgaben auf der Bildschirmoberfläche gemacht wurden, die aktualisiert werden müssen.
4.14
Der Zeitgeber Timer
Abbildung 4.15: Der Zeitgeber „Timer”
Der Zeitgeber Timer erzeugt nach einer bestimmten Zeit ein Ereignis. Mit ihm lassen sich somit Prozesse in bestimmten Zeitintervallen starten oder für eine bestimmte Zeit sperren. Dieses Zeitintervall kann zwischen 1 und 65.535 Millisekunden liegen. Der Zeitgeber ist während der Ausführung des Programms unsichtbar und kann somit vom Anwender nicht beeinflußt werden. Zur Identifizierung eines Steuerelements als Zeitgeber werden im folgenden die drei Buchstaben tim verwendet.
108
Sandini Bib
Eigenschaft
mögliche Werte
Beschreibung
(Name)
String
Über den Namen wird das Steuerelement im Programmcode angesprochen.
Enabled
True/False
True startet den Zeitgeber, er erzeugt Impulse. False stoppt den Timer, er erzeugt keine Impulse mehr.
Intervall
1-65'536
Diese Eigenschaft beinhaltet die Zeit in Millisekunden, die zwischen zwei Zählimpulsen des Timers liegen soll.
Tag
String
Diese Eigenschaft steht zur freien Verfügung, d.h. sie hat keinen direkten Einfluß auf das Steuerelement, sondern kann z.B. als Zwischenspeicher für das Steuerelement dienen.
Tabelle 4.6: Die wichtigsten Eigenschaften des Zeitgebers
4.14.1
Aufgabe
Es soll eine einfache Stoppuhr mit den Funktionen
Start,
Stop,
Restart und
Reset
Eine Aufgabe für den Zeitgeber
programmiert werden.
4.14.2
Lösung
Als Grundlage für das zu erstellende Programm kann das Programm Vorlage genommen werden. Die Schaltfläche btn_Ok ist dabei überflüssig und kann somit gelöscht werden. Die zusätzlich benötigten Steuerelemente werden in Tabelle 4.7 mit ihren einzustellenden Eigenschaften aufgeführt. Steuerelement
Eigenschaft
Inhalt
Textelement
Name
lab_Zeit
Label
Caption
Schaltfläche
Caption
&Start
Button
Name
btn_Start
Tag
Startet die Zeitmessung mit der Stoppuhr
Schaltfläche
Caption
S&top
Button
Name
btn_Stop
( #)
Die Lösung zur Aufgabe Zeitgeber
109
Sandini Bib
Steuerelement
Eigenschaft
Inhalt
Tag
Beendet die Zeitmessung mit der Stoppuhr
Schaltfläche
Caption
&Reset
Button
Name
btn_Null
Tag
Setzt die Stopuhr auf null zurück
tim_Stopuhr
Name
tim_Stopuhr
Timer
Interval
10
Tabelle 4.7: Benötigte Steuerelemente für das Stopuhrbeispiel
Für das Messen der vergangenen Zeit werden folgende Variablen benötigt: Dim Startzeit As Date Dim Zeit As Date
Die folgenden Funktionen bilden die Funktionalität der Stoppuhr ab: Private Sub btn_Null_Click() Startzeit = Time$ Zeit = Startzeit Lab_Zeit.Caption = Format(0, "Long Time") End Sub Private Sub btn_Start_Click() Zeit = Time$ Startzeit = Zeit - CDate(Lab_Zeit.Caption) tim_Stoppuhr.Enabled = True End Sub Private Sub btn_Stop_Click() tim_Stoppuhr.Enabled = False End Sub Private Sub Form_Load() Lab_Zeit = Format(0, "Long Time") Call btn_Stop_Click Call btn_Null_Click End Sub Private Sub tim_Stoppuhr_Timer() Zeit = Time$ Lab_Zeit.Caption = Format(Zeit - Startzeit, "Long _ Time") DoEvents End Sub
110
Sandini Bib
4.15
Das Liniensteuerelement Linie
Abbildung 4.16: Das Liniensteuerelement „Linie”
Das Steuerelement Linie ist ein grafisches Steuerelement und dient zum Unterteilen von Fenstern. Der Benutzer kann während der Laufzeit keine Veränderungen vornehmen, da es ausschließlich zur Visualisierung eingesetzt wird.
4.16
Das Figurensteuerelement Shape
Abbildung 4.17: Das Figurensteuerelement „Shape”
Das Figurensteuerelement Shape ist, analog zum Liniensteuerelement, ein grafisches Steuerelement. Es kann als Quadrat, Rechteck, Kreis, Oval, abgerundetes Rechteck oder als ein abgerundetes Quadrat angezeigt werden. Es wird zumeist für das visuelle Gruppieren von Steuerelementen eingesetzt. Das Figurensteuerelement wird zur Designzeit verwendet und entspricht den Methoden Circle und Line während der Laufzeit.
4.16.1
Beispiel zum Figurensteuerelement Shape
Bei dem folgenden Beispielprogramm handelt es sich um eine kleine Animation. Sie läßt einen Ball in einem Bildfeld-Steuerelement wie einen Gummiball hüpfen. Sobald der Ball an eine Seite stößt, prallt er von dieser ab, nach dem physikalischen Gesetz „Einfallswinkel gleich Ausfallswinkel” ab. Der Ball soll mit dem Steuerelement Shape dargestellt werden. In Die Programmoberfläche der „Gummiball-Simulation” ist die Programmoberfläche der „Gummiball-Simulation” dargestellt. Als Grundlage wurde das Vorgabe-Projekt auf der diesem Buch beiliegenden Diskette verwendet.
" "
111
Sandini Bib
Abbildung 4.18: Die Programmoberfläche der „Gummiball-Simulation”
In Tabelle 4.8: Die Steuerelemente der „Gummiball-Simulation” sind die für das Programm benötigten Steuerelemente und deren Eigenschaften beschrieben. Steuerelement
Eigenschaft
Inhalt
Beschreibung
Zeitgeber
(Name)
tim_Ball
Er steuert den Bewegungsablauf. Je kürzer das eingestellte Intervall ist, desto schneller bewegt sich der Ball.
Bildfeld-Steuerelement
pic_Ball
Dies ist das Grundelement, in dem sich der Ball bewegt. Beim Erstellen muß sich der Ball im Bildfeld befinden.
Figuren-Steuerelement
shp_Ball
Dies stellt den farbigen Gummiball dar, der sich über den Bildschirm bewegt.
BorderColor
&H00FF0000&
Dies bezeichnet die Farbe, die der Rand des Balls hat.
BorderStyle
1 - Ausgefüllt
Damit wird definiert, daß der Rahmen des Steuerelements ausgefüllt ist.
FillColor
&H00FF0000&
Hiermit wird die Farbe des Balls festgelegt.
FillStyle
0 - Ausgefüllt
Diese Eigenschaft definiert, daß der Ball komplett mit der vorgegebenen Farbe gefüllt wird.
Tabelle 4.8: Die Steuerelemente der „Gummiball-Simulation”
Beim Starten des Programmes müssen die Position, die Geschwindigkeit und die Startrichtung des Balls vorgegeben werden. Die Bewegungsrichtung setzt sich aus den horizontalen und vertikalen Anteilen zusammen.
112
Sandini Bib
Abbildung 4.19: Bewegungsanteile des Balls einer Zeiteinheit
Da bei jeder Bewegung die zurückgelegte Strecke gleich lang sein muß, reicht es, einen Bewegungsanteil zu definieren. Der andere Bewegungsanteil berechnet sich dann nach dem Satz des Pythagoras: Bewegungsanteil horizontal = mit 0 < Bewegungsanteil vertikal < 1 In dem Ereignis Load des Formulars wird die Initialisierung der Startparameter durchgeführt. Private Sub Form_Load() tim_Ball.Interval = 0 'Zeitgeber deaktivieren 'Ball im Mittelpunkt des Bildfeldes positionieren shp_Ball.Left = (Pic_ball.Width - shp_Ball.Width) / 2 shp_Ball.Top = (Pic_ball.Height - shp_Ball.Height) / 2 Geschw = 80 'Zurückzulegende Strecke einer 'Zeiteinheit 'Anteile der Bewegungsrichtungen berechnen Richtung(1) = 0.5 Richtung(0) = (1 - Richtung(1) ^ 2) ^ 0.5 End Sub
Stößt der Ball gegen eine der seitlichen Wände, muß der horizontale Bewegungsanteil mit –1 multipliziert werden, und schon „prallt” der Ball von der Wand ab. Das gleiche gilt für den vertikalen Bewegungsanteil, wenn der Ball auf die obere oder untere Wand trifft. Ob der Ball auf eine Wand trifft, läßt sich dadurch feststellen, daß der Rand des Balls einen Wert annimmt, der außerhalb der Eigenschaftswerte
113
Sandini Bib
Width
Breite des Bildfelds
Height
Höhe des Bildfelds
liegt. Ausgeführt wird die Berechnung für die neue Position des Balles bei jedem Bewegungszyklus. Private Sub tim_Ball_Timer() Dim x As Double Dim y As Double Dim Position(2) As Integer Position(0) = shp_Ball.Left Position(1) = shp_Ball.Top Position(0) = Position(0) + Richtung(0) * Geschw Position(1) = Position(1) + Richtung(1) * Geschw If Position(0) > Pic_ball.Width - shp_Ball.Width Then Position(0) = (Pic_ball.Width - shp_Ball.Width) Richtung(0) = -Richtung(0) Else If Position(0) < 0 Then Position(0) = 0 Richtung(0) = -Richtung(0) End If End If If Position(1) > Pic_ball.Height - shp_Ball.Height Then Position(1) = (Pic_ball.Height - shp_Ball.Height) Richtung(1) = -Richtung(1) Else If Position(1) < 0 Then Position(1) = 0 Richtung(1) = -Richtung(1) End If End If shp_Ball.Left = Position(0) shp_Ball.Top = Position(1) End Sub
Um die Bewegung des Balls zu starten, wird das Ereignis Click der Schaltfläche OK verwendet. Wird dieser Schalter ausgelöst, soll sich die Beschriftung in STOP ändern und dem Zeitgeber das Intervall zugewiesen werden, in dem er einen Bewegungsschritt des Balls ausführen soll. Private Sub btn_Ok_Click() Static Beschriftung As String If btn_Ok.Caption = "&Stop" Then btn_Ok.Caption = Beschriftung tim_Ball.Interval = 0
114
Sandini Bib
Else Beschriftung = btn_Ok.Caption btn_Ok.Caption = "&Stop" tim_Ball.Interval = 5 End If End Sub
Nach dem ersten Betätigen der Schaltfläche fängt der Ball an, sich über den Bildschirm zu bewegen. Trifft er auf eine Wand, prallt er wieder ab und ändert dabei seine Richtung. Wird nach einer gewissen Zeit die Schaltfläche STOP betätigt, verharrt der Ball auf der letzten Position. Nach einem erneuten Betätigen des Schalters führt er die Bewegung weiter, als sei diese nie unterbrochen worden.
4.17
Hinzufügen weiterer Steuerelemente
Visual Basic enthält mehr Steuerelemente, als im Werkzeugfenster eingetragen sind. Um weitere Steuerelemente in das Werkzeugfenster einzublenden, muß mit der rechten Maustaste auf das Werkzeugfenster geklickt werden. Hier erscheint nun ein Kontextmenü, aus dem der Menüpunkt KOMPONENTEN ausgewählt werden muß. Es öffnet sich der Dialog zum Hinzufügen weiterer Steuerelemente (Abbildung 4.20).
Weitere Steuerelemente zum Werkzeugfenster hinzufügen
Abbildung 4.20: Zusätzliche Steuerelemente
* +'
115
Sandini Bib
Durch Selektieren bzw. Deselektieren der Kontrollkästchen in der Liste können die zusätzlichen Steuerelemente in das Werkzeugfenster übernommen oder wieder aus dem Werkzeugfenster entfernt werden.
4.18
Der Standarddialog mit dem CommonDialog
Abbildung 4.21: Das Standarddialog-Steuerelement „CommonDialog”
Einer der großen Vorteile des Betriebssystems Windows besteht darin, daß viele Standarddialoge in allen Applikationen gleich aussehen; dies ermöglicht es dem Anwender, sich rascher und problemloser in einem neuen Programm zurechtzufinden. Bei Standarddialogen handelt es sich z.B. um Drucken, Dateien öffnen oder Systemfarben einstellen. In Visual Basic gibt es nun die Möglichkeit, diese vom System zur Verfügung gestellten Dialogboxen in ein eigenes Programm einzubinden. Dazu wird das Steuerelement CommonDialog benötigt. Hiermit lassen sich alle Einstellungen wie gewohnt setzen und auch abfragen, während das Programm läuft. Auf dem Fenster, auf dem das Steuerelement aufgebracht wurde, ist jedoch nur ein kleines Steuerelement zu sehen (vgl. Abschnitt „Der Zeitgeber Timer“). Während der Laufzeit des Programms ist gar kein Steuerelement auf der Oberfläche des Fensters zu sehen. Um das Steuerelement CommonDialog in die Werkzeugliste einzutragen, muß das Kontrollkästchen des Eintrages Microsoft Common Dialog Control 6.0
auf dem Registerblatt STEUERELEMENTE der Dialoges KOMPONENTEN aktiviert werden. Verschiedene Aufrufe sind jeweils den entsprechenden Dialogen zugeordnet. Dadurch kann das Programm erkennen, um welchen Standarddialog es sich handelt. Die Position des Dialogs auf der Programmoberfläche wird vom System selbst festgelegt.
116
Sandini Bib
Die Befehle zum AufAufruf
zugehöriger Dialog
rufen der einzelnen
ShowOpen
Öffnet die Dialogbox, um Dateien zu öffnen. Abschnitt
Standarddialoge
ShowSave
Öffnet die Dialogbox, um Dateien zu speichern. Abschnitt
ShowColor
Öffnet die Dialogbox, um die Farben einzustellen. Abschnitt
ShowFont
Öffnet die Dialogbox, um die Schriftart festzulegen. Abschnitt Die Eigenschaften des Dialogs Schriftart
ShowPrinter
Öffnet die Dialogbox, um den Drucker festzulegen. Abschnitt
ShowHelp
Öffnet die Dialogbox für die Hilfeeinstellungen. Abschnitt
Tabelle 4.9: Aufrufe der Standarddialoge
Damit ein Programm, das mit Standarddialogen arbeitet, auch verteilt werden kann, muß die dazugehörige OCX-Datei ebenfalls verteilt werden. Diese Datei befindet sich zumeist im Windows-Standardverzeichnis. In den folgenden Abschnitten werden die einzelnen Dialoge und ihre Eigenschaften erklärt. Es wird außerdem zu jedem Dialog ein kurzes Beispiel gegeben, um die Arbeitsweise des Dialogs zu verdeutlichen.
4.18.1
Die Eigenschaften des Dialogs Datei öffnen/ speichern
Abbildung 4.22: Die Eigenschaften des Dialogs „Datei öffnen/speichern”
117
Sandini Bib
Ein Standarddialog ist das Öffnen und Speichern von Dateien. Hierzu können Eigenschaften eingestellt werden, die dann im Dialogfenster berücksichtigt werden. Sie dienen u.a. dazu, um beispielsweise Dateien zu filtern oder um die Anzahl der darzustellenden Dateien in einem Verzeichnis zu begrenzen. In Tabelle 4.10 sind die Eigenschaften des Dialogs DATEI ÖFFNEN/SPEICHERN beschrieben. Eigenschaft
Beschreibung
DialogTitle
Hier wird die Überschrift des Standarddialogs festgelegt.
FileName
Innerhalb dieser Option wird der Dateiname, der gespeichert oder geladen werden soll, erfaßt.
InitDir
Innerhalb dieser Option wird das Verzeichnis, das nach dem Öffnen aktiv sein soll, festgelegt.
Filter
Mit dieser Option läßt sich festlegen, welche Dateitypen angezeigt werden sollen und welche nicht (z.B. nur Dateien mit der Endung BAK). Des weiteren können auch mehrere Filter und ihre Beschreibung eingegeben werden. Text (*.txt; *.csv) | *.txt; *.tsv | Paintbrush (*.pcx) | *.pcx;
Flags
Hier werden die Optionen für den Dialog festgelegt: welche Optionen angezeigt und eingestellt werden können und welche nicht.
DefaultExt
Diese Eigenschaft legt die Standard-Dateinamenserweiterung fest oder liefert diese zurück.
MaxFileSize
Diese Option reserviert den Speicher für die Länge der Dateinamen, die in der Dialogbox angezeigt werden können. Der Wert ist vom Typ Integer. Voreingestellt ist der Wert 256.
FilterIndex
Mit dieser Eigenschaft wird der Standardfilter definiert, wenn in der Eigenschaft Filter mehr als ein Filter angegeben wurde.
CancelError
Mit dieser Eigenschaft wird festgelegt, ob beim Drücken der Taste ABBRECHEN ein Fehlerwert generiert wird oder nicht. True Fehlerwert wird generiert. False Fehlerwert wird nicht generiert. Tabelle 4.10: Eigenschaften des Dialogs „Datei öffnen und speichern”
Aufgerufen wird der Dialog mit dem Befehl Name.ShowOpen
Danach ist das Fenster modal geöffnet, d. h. es kann erst mit dem Programm weitergearbeitet werden, wenn das Fenster zum Öffnen oder Speichern der Dateien wieder geschlossen wurde.
118
Sandini Bib
4.18.2
Die Eigenschaften des Dialogs Farbpalette
Abbildung 4.23: Die Eigenschaften des Dialogs „Farbpalette”
Für die Definition der Farben, die in Programmen optional eingestellt werden können, gibt es den Standarddialog Farbpalette. Mit ihm lassen sich die Farbeinstellungen mit dem von Windows zur Verfügung gestellten Dialog definieren. In Tabelle 4.11 sind die Eigenschaften des Dialogs aufgeführt. Eigenschaft
Beschreibung
Color
Diese Eigenschaft beinhaltet die Nummer der Farbe, die dargestellt werden soll.
Flags
Hier werden die Optionen für den Dialog festgelegt: welche Optionen angezeigt und eingestellt werden können und welche nicht.
CancelError
Mit dieser Eigenschaft wird festgelegt, ob beim Drücken der Taste ABBRECHEN ein Fehlerwert generiert wird oder nicht. True Fehlerwert wird generiert. False Fehlerwert wird nicht generiert.
Tabelle 4.11: Eigenschaften des Dialogs „Farbpalette”
Aufgerufen wird der Dialog mit dem Befehl Name.ShowColor
Danach ist das Fenster modal geöffnet, d. h. es kann erst mit dem Programm weitergearbeitet werden, wenn das Fenster zum Definieren der Farben wieder geschlossen wurde.
119
Sandini Bib
4.18.3
Die Eigenschaften des Dialogs Schriftart
Abbildung 4.24: Die Eigenschaften des Dialogs „Schriftart”
Um in einem Steuerelement eine Schriftart zu verändern oder dem Steuerelement eine neue zuzuweisen, wird der Standarddialog Schriftart von Visual Basic unterstützt. Er entspricht dem Standarddialog von Windows. Um eine Schriftart zu bearbeiten, werden folgende Eigenschaften zur Verfügung gestellt (Tabelle 4.12): Eigenschaft
Beschreibung
FontName
Diese Eigenschaft gibt die Schriftart an, die in dem Steuerelement verwendet wird oder verwendet werden soll.
FontSize
Diese Eigenschaft gibt die Größe der Schriftart an.
Min
Diese Eigenschaft definiert die kleinste zulässige Schriftgröße oder liefert diese zurück.
Max
Diese Eigenschaft definiert die größte zulässige Schriftgröße oder liefert diese zurück.
Flags
Diese Eigenschaft legt die Optionen für den Dialog fest: welche Optionen angezeigt und eingestellt werden können und welche nicht.
CancelError
Mit dieser Eigenschaft wird festgelegt, ob beim Drücken der Taste ABBRECHEN ein Fehlerwert generiert wird oder nicht. True Fehlerwert wird generiert. False Fehlerwert wird nicht generiert.
Bold
Hier wird festgelegt, ob die Schrift in Fettbuchstaben dargestellt werden soll (Beispiel).
Italic
Hier wird festgelegt, ob die Buchstaben in Kursivschrift dargestellt werden sollen (Beispiel).
Underline
Hier wird festgelegt, ob die Buchstaben unterstrichen werden sollen (Beispiel).
Strikethru
Hier wird festgelegt, ob die Buchstaben durchgestrichen werden sollen (Beispiel). Tabelle 4.12: Eigenschaften des Dialogs „Schriftart”
120
Sandini Bib
Aufgerufen wird der Dialog mit dem Befehl Name.ShowFont
Danach ist das Fenster modal geöffnet, d. h. es kann erst mit dem Programm weitergearbeitet werden, wenn das Fenster zum Definieren der Schriftart wieder geschlossen wurde.
4.18.4
Die Eigenschaften des Dialogs Drucken
Abbildung 4.25: Die Eigenschaften des Dialogs „Drucken”
Für die Steuerung des Druckers und die Druckerauswahl wird der Standarddialog Drucken unterstützt. Er entspricht dem von Windows zur Verfügung gestellten Dialog. Folgende Eigenschaften werden von diesem Dialog unterstützt und können somit gesetzt werden. Eigenschaft
Beschreibung
Copies
Diese Eigenschaft bestimmt die Anzahl der Kopien, die von dem Dokument gedruckt werden sollen.
Flags
Hier werden die Optionen für den Dialog festgelegt: welche Optionen angezeigt und eingestellt werden können und welche nicht.
FromPage
Hier muß die erste Seite des Bereichs, der gedruckt werden soll, definiert werden.
ToPage
Hier muß die letzte Seite des Bereichs, der gedruckt werden soll, definiert werden.
Min
Diese Eigenschaft legt den kleinsten zulässigen Wert für den Druckbereich fest oder liefert diesen zurück.
Max
Diese Eigenschaft legt den größten zulässigen Wert für den Druckbereich fest oder liefert diesen zurück.
121
Sandini Bib
Eigenschaft
Beschreibung
PrinterDefault
Mit dieser Eigenschaft wird festgelegt, ob die Einstellungen, die der Benutzer in dem Druckdialog verändert, auch die Einstellungen des Systems verändern, d. h. beim Bestätigen der Einstellungen im Druckdialog werden diese in der zugehörigen Konfigurationsdatei gespeichert. True Einstellungen speichern False Einstellungen verwerfen
CancelError
Mit dieser Eigenschaft wird festgelegt, ob beim Drücken der Taste ABBRECHEN ein Fehlerwert generiert wird oder nicht. True Fehlerwert wird generiert. False Fehlerwert wird nicht generiert. Tabelle 4.13: Eigenschaften des Eigenschaftsdialogs „Drucken”
Aufgerufen wird der Dialog mit dem Befehl Name.ShowPrinter
Danach ist das Fenster modal geöffnet, d. h. es kann erst mit dem Programm weitergearbeitet werden, wenn das Fenster zur Druckerausgabe wieder geschlossen wurde.
4.18.5
Die Eigenschaften des Dialogs Hilfe
Abbildung 4.26: Die Eigenschaften des Dialogs „Hilfe”
Mit dem Dialog Hilfe wird der Text aus einer Hilfedatei angezeigt. Dabei läßt sich festlegen, ob der Standardhilfedialog z.B. kontextabhängig ist, also zu dem aktuellen Menüpunkt oder Fenster Hilfe anbietet. Es kann aber auch der Index der Hilfedatei angezeigt werden.
122
Sandini Bib
Eigenschaft
Beschreibung
HelpContext
Diese Eigenschaft legt die Kennung für den Kontext fest, der zu dieser Hilfe gehört, oder liefert diesen zurück.
HelpCommand
Diese Eigenschaft legt fest, um welche Art von Hilfe es sich handelt: eine kontextabhängige oder eine Indexhilfe. Die Konstantenwerte, die dieser Eigenschaft zugeordnet werden können, sind im zugehörigen Objektkatalog enthalten.
HelpKey
Diese Eigenschaft legt das Stichwort fest, mit dem die zugehörige Hilfe verbunden ist, oder liefert dieses zurück.
HelpFile
Hiermit werden der Pfad und der Name der Hilfedatei, die dem Dialog zugeordnet ist, festgelegt oder zurückgeliefert.
Tabelle 4.14: Eigenschaften des Dialogs „Hilfe”
Aufgerufen wird der Dialog mit dem Befehl Name.ShowHelp
Danach ist das Fenster modal geöffnet, d. h. es kann erst mit dem Programm weitergearbeitet werden, wenn das Fenster wieder geschlossen wurde.
4.18.6
Zusammenfassung
Mit dem Steuerelement CommonDialogBox lassen sich alle Standarddialoge schnell und einfach in ein Visual Basic-Programm integrieren. Ein Anwender wird sich somit sehr schnell in diesen Dialogen zurechtfinden, da er sie von anderen Programmen bereits kennt.
Zusammenfassung zu dem Steuerelement CommonDialogBox
Beispiel 1 In diesem Beispiel wird der Standarddialog Schriftart aufgerufen. Nach erfolgter Definition des Benutzers werden die Einstellungen in das aufrufende Programm übernommen.
Beispielprogamm zum Schriftarten-Standarddialog
Public btn_Schrift_Click() dlg_Beispiel.ShowFont End Sub
Beispiel 2 In diesem Beispiel wird für jeden Dialog eine Schaltfläche definiert, die einen der Dialoge aufruft. Es werden keine Werte eingelesen. Dieses Beispiel dient lediglich dazu, die einzelnen Dialogfenster zu zeigen.
Beispielprogramm zum Aufrufen aller Standarddialoge
123
Sandini Bib
Public Sub btn_Dialog_Click(Index as Integer) select Case Index Case 0 dlg_Beispiel.ShowOpen Case 1 dlg_Beispiel.ShowSave Case 2 dlg_Beispiel.ShowColor Case 3 dlg_Beispiel.ShowFont Case 4 dlg_Beispiel.ShowPrinter Case 5 dlg_Beispiel.ShowHelp End Case End Sub
4.19
Das Registerblättersteuerelement SSTab
Abbildung 4.27: Das Steuerelement „Registerblätter”
Die Register in Visual Basic sind wie die Register eines Karteikastens aufgebaut. Auch dieses Steuerelement muß über den Dialog, der in Abschnitt 4.17 beschrieben wurde, hinzugefügt werden. In der Liste des Komponenten-Dialogs handelt es sich um den Eintrag Microsoft Tabbed Dialog Control 6.0
Auf jedem Register können Steuerelemente untergebracht werden, die einen bestimmten Programmteil unterstützen. Es lassen sich in einem Fenster viele Informationen übersichtlich anbringen. In den modernen Programmen sind diese Registerblätter Standard geworden. In diesem Buch wird das Steuerelement Registerblätter mit den drei Buchstaben tab identifiziert. Standardmäßig werden die Registerlaschen oben angeordnet. Um im Editiermodus von einem Registerblatt auf ein anderes zu wechseln, muß mit der linken Maustaste auf die zu wählende Lasche geklickt werden. In der Eigenschaft Caption wird das Registerblatt benannt. Es sollte jedoch darauf geachtet wer-
124
Sandini Bib
den, daß ein Register in einem Fenster nicht zu viele Registerblätter enthält, da sonst die Übersichtlichkeit wieder verlorengeht. Es bietet sich in solchen Fällen an, auf eine Seite des Registers ein neues Register aufzubringen. Eigenschaft
mögliche Werte
Beschreibung
(Name)
String
Über den Namen wird das Steuerelement im Programmcode angesprochen.
CurrentTab
Integer
Hier wird die Nummer des aktiven Registers aufgeführt.
Caption
String
Hier erfolgt die Aufführung des Laschentitels des aktuellen Registerblattes.
TabCount
Integer
Diese Eigenschaft gibt die Anzahl der Registerblätter auf dem Steuerelement an.
TabsPerRow
Integer
Diese Eigenschaft gibt die Anzahl der Registerlaschen an, die in einer Zeile dargestellt werden. Bei sechs Registerblättern und drei Laschen pro Zeile ergibt sich.
Abbildung 4.28: Anordnung der Registerblätter
Tag
String
Diese Eigenschaft steht zur freien Verfügung, d. h. sie hat keinen direkten Einfluß auf das Steuerelement, sondern kann z.B. als Zwischenspeicher für das Steuerelement dienen.
Tabelle 4.15: Die wichtigsten Eigenschaften des Steuerelements „Registerblätter”
4.19.1
Aufgabe
Es soll ein Programm entwickelt werden, das sechs Registerblätter hat und in ein Beschreibungsfeld schreibt, welches der Register aktiv ist.
Eine Aufgabe zum Steuerelement Registerblätter
4.19.2
Lösung
Private Sub tab_Beispiel_Click(PreviousTab As Integer) Lab_Ausgabe.Caption = tab_Beispiel.Caption End Sub
4.20
Die Lösung zu den Registerblättern
Das MDI-Formular
MDI steht für Multiple Document Interface und bedeutet, daß mehrere Fenster innerhalb eines Programmfensters enthalten sein können. In manchen Programmen ist es notwendig, daß mehrere Fenster unter einem Hauptfenster aktiv sind, z.B. in der Textverarbeitung.
,$
125
Sandini Bib
Das Programmfenster ist das Hauptfenster. Auch wenn kein Dokument geöffnet ist, ist dieses Hauptfenster aktiv. Werden Dokumente geöffnet, werden sie in Fenstern dargestellt, die sich innerhalb des Programmfensters befinden und auch innerhalb dieses Fensterrahmens das gleiche Verhalten zeigen wie ein Hauptfenster auf der Desktop-Oberfläche. Wird das MDI-Fenster über den Rand des Hauptfensters hinaus verschoben, wird dieser einfach abgeschnitten. Eigenschaft
mögliche Werte
Beschreibung
(Name)
String
Über den Namen wird das Steuerelement im Programmcode angesprochen.
Caption
String (Max. 255 Zeichen)
In Caption wird die Beschriftung des Fensters eingetragen, die während des Programmlaufs sichtbar ist.
MDIChild
TRUE/FALSE
Diese Eigenschaft gibt an, ob es sich bei dem aktuellen Fenster um ein Fenster im Fenster handelt.
Tag
String
Diese Eigenschaft steht zur freien Verfügung, d. h. sie hat keinen direkten Einfluß auf das Steuerelement, sondern kann z.B. als Zwischenspeicher für das Steuerelement dienen.
Tabelle 4.16: Wichtige Eigenschaften des MDI-Fensters
4.20.1 Eine Aufgabe zum MDI-Fenster
Aufgabe
Es soll ein Programm entwickelt werden, in dem über den Button MDI NEU ein Dokumentfenster geöffnet wird. Nach dem Öffnen des Fensters lautet der Fenstertitel folgendermaßen: Fenster Nr. N um Uhrzeit Uhrzeit geöffnet.
4.20.2
Die Lösung zur Aufgabe MDI-Fenster
Lösung
Fensterglobal Für die Realisierung wird eine globale Variable benötigt, die mitzählt, wie viele Fenster schon geöffnet wurden. Dim Nr As Integer
MDI-Fenster erzeugen Mit der folgenden Funktion wird das eigentliche MDI-Fenster erzeugt. Das Hauptfenster erhält in der Eigenschaft Name den Wert frmMDI. Als nächstes wird ein weiteres Formular benötigt dessen Name frm_Client ist und in der Eigenschaft MDIChild wird der Wert True festgelegt.
126
Sandini Bib
Private Sub MDIForm_Click() Dim Fenster As New frm_Client Nr = Nr + 1 Fenster.Caption = "Fenster Nr " & Nr & " um " & _ Time() & " geöffnet" Fenster.Show End Sub
,$
127
Sandini Bib
Sandini Bib
5
Wichtige Eigenschaften der Steuerelemente
Jedes Steuerelement hat bestimmte Eigenschaften, die vom Anwender, Entwickler oder vom Programm beeinflußt und geändert werden können. Die Eigenschaften der Steuerelemente lassen sich in drei Gruppen einteilen:
Eigenschaften der Steuerelemente nicht immer ändern
1. Eigenschaften, die nur zur Designzeit geändert werden können:
Die horizontale und vertikale Position eines Steuerelements
Der Name des Steuerelements
...
2. Eigenschaften, die vom Programm zur Laufzeit geändert werden
können:
Die Farbe des Steuerelements
Die Eigenschaft Sichtbar oder Unsichtbar des Steuerelements
...
3. Eigenschaften, die vom Anwender während der Programmausfüh-
rung geändert werden können:
Die Eingabetexte von Eingabesteuerelementen
Spaltenbreiten/Zeilenhöhen des Steuerelements Grid
...
In diesem Kapitel werden die wichtigsten Eigenschaften der Steuerelemente beschrieben und ihre Wirkungsweise auf die Steuerelemente erklärt.
129
Sandini Bib
5.1 Eigenname des Steuerelements
Die Eigenschaft (Name)
Die Eigenschaft (Name) identifiziert das Steuerelement oder das Formular im Programmcode. Diese Eigenschaft besitzen alle Elemente von Visual Basic. Der Name muß immer mit einem Buchstaben oder einem Unterstrich beginnen. Wird vom Entwickler kein (Name) vergeben, so vergibt Visual Basic den Namen selbständig. Der von Visual Basic vergebene Name ist so aufgebaut, daß er zum einen das Objekt beschreibt und zum anderen eine laufende Nummer enthält, deren Wert mit jedem neuen Objekt vom selben Typ um eins erhöht wird. Dieser Name sollte vom Entwickler dann in einen sogenannten sprechenden Namen umgewandelt werden. Wird zum Beispiel ein Textelement Label auf das Fenster aufgebracht, mit dem ein Ergebnis dargestellt werden soll, bietet sich der Name Lab_Ergebnis für dieses Steuerelement an. Der Name für ein Steuerelement sollte vergeben werden, bevor das erste Ereignis programmiert wird, da die verwendeten Ereignisse nicht umbenannt werden. Bei einer späteren Umbenennung sind dem Steuerelement somit keine Funktionen mehr zugeordnet. Die verwendeten Funktionen sind jedoch nicht gelöscht, sondern in dem Abschnitt GENERAL des Formulars gespeichert.
5.2 Darstellungsarten des Steuerelements
Die Eigenschaft Appearance
Die Eigenschaft Appearance definiert, wie das Objekt auf der Oberfläche dargestellt wird. Es gibt zwei Darstellungsarten: 0 Flat. Zeichnet das Objekt ohne Tiefeneffekte, also flach. 1 3D. Das Objekt wird im neuen Darstellungsmodus von Windows95/ NT gezeichnet, also mit einem 3D-Effekt.
5.3 Beschriftung des Steuerelements
Die Eigenschaft Caption
Die Eigenschaft Caption ist die Beschriftung eines Steuerelements. Diese Eigenschaft kann während der Laufzeit nur vom Programm geändert werden. Der Inhalt der Eigenschaft Caption ist im Fenster in der farbigen Titelleiste abgebildet.
Abbildung 5.1: Beispiel zur Eigenschaft „Caption”
130
Sandini Bib
Die Zeichenkette, die in diese Eigenschaft eingegeben werden kann, darf nicht länger als 255 Zeichen sein. Dieses Limit wird zumeist nicht überschritten, da die Beschreibungstexte selten die entsprechende Länge erreichen.
5.4
Die Eigenschaft Cancel
Mit Cancel wird die Schaltfläche definiert, die auf die (Esc)-Taste reagieren soll. Zumeist handelt es sich um die Schaltfläche Abbrechen. Wenn ein Fenster mit einer Cancel-Taste aktiv ist, löst das Drücken der Taste (Esc) die Aktion aus, die normalerweise durch Betätigen der Schaltfläche mit der Maus gestartet wird. Die Eigenschaft Default definiert die Schaltfläche, die auf die Taste (¢) reagiert
Definiert, ob eine Schaltfläche auf die (Esc)-Taste reagiert
Die Eigenschaft Cancel kann folgende Zustände annehmen: True = Diese Taste reagiert standardmäßig auf das Betätigen der Taste (Esc). False = Diese Taste reagiert nicht standardmäßig auf das Betätigen der Taste (Esc). Auf jedem Formular kann es nur ein Steuerelement geben, dessen Eigenschaft den Wert True besitzt.
5.5
Die Eigenschaft Default
Mit der Eigenschaft Default wird das Steuerelement definiert, das auf die Eingabetaste ENTER reagieren soll. Zumeist handelt es sich um die Schaltflächen BESTÄTIGEN oder OK. Wenn ein Fenster mit einer Default-Taste aktiv ist, löst das Drücken der Taste RETURN die Aktion aus, die normalerweise durch Betätigen der Schaltfläche mit der Maus gestartet wird. Die Eigenschaft Cancel definiert die Schaltfläche, die auf die Taste (Esc) reagiert.
Definiert, ob eine Schaltfläche auf die (¢)-Taste reagiert
Die Eigenschaft Default kann folgende Zustände annehmen: True = Diese Taste reagiert standardmäßig auf das Betätigen der Taste (¢). False = Diese Taste reagiert nicht standardmäßig auf das Betätigen der Taste (¢). Auf jedem Formular kann es nur ein Steuerelement geben, dessen Eigenschaft den Wert True besitzt.
131
Sandini Bib
5.6 Verfügbarkeit der Steuerelemente
Die Eigenschaft Enabled
Um ein Steuerelement für den Anwender zu sperren, wird die Eigenschaft Enabled zur Verfügung gestellt. Mit Hilfe dieser Eigenschaft läßt sich definieren, ob ein Anwender ein Steuerelement, z.B. eine Schaltfläche, nur sieht oder er sie auch auch betätigen darf. Bei Programmen, die benutzerabhängig, z.B. von einem Paßwort gesteuert sind, ist es mit Hilfe dieser Eigenschaft sehr einfach, die Funktionalität von Programmen einzuschränken. Zum Teil ist es auch sinnvoll, Steuerelemente, die einen aufwendigen Prozeß starten, zu deaktivieren, um ein zweites Aufrufen der Funktion solange zu vermeiden, bis der Prozeß vollkommen abgearbeitet wurde. Wird im folgenden Beispiel die Taste OK während des Abarbeitens der Funktion gedrückt, hält die Funktion an und startet neu. Private Sub btn_Eingabe_Click () Dim I As Integer lab_Ausgabe1.Caption = "" 'Löschen des Inhaltes der 'beiden Textausgaben lab_Ausgabe2.Caption = "" For I = 1 To 1000 'Erste Schleife, die in 'das erste Label den 'Schleifenindex schreibt lab_Ausgabe1.Caption = CStr(I) DoEvents Next i For I = 1 To 1000 'Zweite Schleife, die in 'das zweite Label den 'Schleifenindex schreibt lab_Ausgabe2.Caption = CStr(I) DoEvents Next i End Sub
5.6.1
Hintergrund- und Vordergrundfarbe
Farben des Steuerelements
Abbildung 5.2: Die Menüs für das Einstellen der Steuerelementfarben
132
Sandini Bib
Zum Einstellen der Hintergrund- und Vordergrundfarbe stellt Visual Basic die Menüs aus Abbildung 5.2 zur Verfügung. Auf dem Register Palette sind alle Farben dargestellt, die für das Steuerelement ausgewählt werden können. Mit dem Registerblatt System wird die Farbverteilung des Systems dem Steuerelement zugeordnet. Wenn dem Steuerelement die Systemfarbeinstellung von Button Face zugewiesen und diese Farbe im System geändert wird, ändert sich auch die Farbe des Steuerelements. Wurde die Farbe über das Registerblatt Palette zugewiesen, dann ist die Farbe von den Systemeinstellungen unabhängig.
5.7
Die Eigenschaft MousePointer
Mit dieser Eigenschaft ist es möglich, das Aussehen des Mauszeigers zu verändern. Standardmäßig ist der Mauszeiger ein Pfeil. Um dem Anwender zu zeigen, daß das Programm aktiv ist, kann der Mauszeiger z.B. in eine Sanduhr geändert werden. Für die Eingabe wird zumeist die Darstellung eines senkrechten Strichs („|”) verwendet. Visual Basic unterstützt die folgenden verschiedenen Darstellungen: Wert
Aussehen
Wert
0
Vorgabe
8
1
9
2
10
3
11
4
12
5
13
6
14
7
15 99
Verändern der Darstellungsart des Mauszeigers
Aussehen
Benutzerdefiniert
Tabelle 5.1: Die möglichen Mauspfeile
133
Sandini Bib
5.8
Die Eigenschaft TabIndex
Mit der Eigenschaft TabIndex wird die Reihenfolge der Steuerelemente festgelegt, in der sie durch das Drücken der (ÿ)-Taste abgearbeitet werden. Visual Basic vergibt diese Werte selbständig durch einfaches Numerieren der Steuerelemente in der Reihenfolge, in der sie auf die aktuelle Form aufgebracht wurden. Muß man die Reihenfolge, in der die Steuerelemente angesprungen werden, ändern, so gibt der Entwickler dem Steuerelement die neue Nummer ein. Das Steuerelement, welches zuvor diese Nummer besessen hat, erhält die Nummer des Steuerelements, dessen Eigenschaftswert sich geändert hat. Der Wert der Eigenschaft kann zwischen 0 und der Anzahl der Steuerelemente – 1 auf dem aktiven Fenster liegen.
5.9 Reihenfolge der Steuerelementaktivierung über Tabulator-Taste
Um bei einem Steuerelement die Möglichkeit abzuschalten, daß es den Fokus über die (ÿ)-Taste erhält, kann die Eigenschaft TabStop auf False gesetzt werden. Ist TabStop auf True gesetzt, kann das Steuerelement über die (ÿ)-Taste erreicht werden.
5.10 Zur freien Verfügung
Programmlaufzeit
134
Die Eigenschaft Tag
Die Eigenschaft Tag ist keine Eigenschaft, die Einfluß auf das Steuerelement hat. Fast jedes Steuerelement stellt diese Eigenschaft zur Verfügung. Der Programmierer kann sie benutzen, um Zeichenketten oder Einstellungen des Steuerelements zwischenzuspeichern. Eine Verwendung dieser Eigenschaft wäre z.B. die Versionskontrolle des einzelnen Steuerelements.
5.11 Dient zur Dateneingabe während der
Die Eigenschaft TabStop
Die Eigenschaft Text
Steuerelemente mit der Eigenschaft Text ermöglichen die Eingabe von Daten während der Programmlaufzeit. In diese Steuerelemente können vom Benutzer Daten eingegeben werden, die dann vom Programm ausgewertet und weiterverarbeitet werden können. Die Eigenschaft Text entspricht ansonsten der Eigenschaft Caption (siehe Abschnitt 5.3).
Sandini Bib
5.12
Die Eigenschaft ToolTipText
Mit dieser Eigenschaft kann der Text eingegeben werden, der in der Sprechblase erscheinen soll, wenn der Mauszeiger auf das Steuerelement zeigt, ohne bewegt zu werden. Wenn z.B. eine Schaltfläche eingesetzt wird, der nur ein Bild zugeordnet ist, kann diese Eigenschaft die Aktion beschreiben, die von dem Steuerelement ausgelöst wird.
5.13
Hilfetext zum Steuerelement in einer Sprechblase
Die Eigenschaft Visible
Mit dieser Eigenschaft wird dem Steuerelement mitgeteilt, ob es für den Anwender sichtbar ist oder nicht. In einigen Programmen ist es zum Teil wichtig, daß manche Programmteile ausgeschaltet werden können, z.B. um Programmteile vor Anwendern zu verbergen (Paßwortschutz). Des weiteren kommt es vor, daß sich bestimmte Dialoge sehr ähneln; über das Aus- und Einblenden von Steuerelementen kann die Dialogmaske genau an die Bedürfnisse angepaßt werden. Visible kann zwei Zustände annehmen: True
Das Steuerelement ist sichtbar.
False
Das Steuerelement ist unsichtbar.
5.14
Die Eigenschaft WindowState
Ein Fenster kann in Windows drei verschiedene Größendefinitionen besitzen. Es kann minimiert sein, d. h. es ist nur als Icon auf der Windows-Oberfläche zu erkennen. Weiterhin kann es als sogenanntes Vollbild den gesamten Bildschirm ausfüllen. Und schließlich kann es als Bildschirmausschnitt auf der Oberfläche dargestellt werden. Die Standardeinstellung von Visual Basic sieht einen Bildschirmausschnitt vor.
Sichtbarkeit eines Steuerelements
Darstellung des Fensters
Folgende drei Parameter sind für diese Eigenschaft möglich: 0 - Normal
Das Programmfenster ist ein Bildschirmausschnitt auf der Oberfläche.
1 - Minimized Das Programmfenster wird als Icon auf der Oberfläche dargestellt. 2 - Maximized Die gesamte Oberfläche wird vom Programmfenster eingenommen.
135
Sandini Bib
Sandini Bib
6
Wichtige Ereignisse der Steuerelemente
Jedes Steuerelement kann auf bestimmte Ereignisse reagieren. Diese Ereignisse können dann Ausgaben erzeugen, Eigenschaften der Steuerelemente ändern oder Programmodule ausführen. Ereignisse werden meistens durch den Benutzer ausgelöst. Ein Ereignis ist z.B. das Klicken mit der linken Maustaste auf ein Steuerelement. Jedes Ereignis ist vom Aufbau her eine Prozedur, die beim Eintreffen des Ereignisses ausgeführt wird. Diese Prozeduren können ebenfalls, wie alle anderen Prozeduren auch, von anderen Funktionen und Prozeduren aufgerufen werden. Die Ereignisprozeduren sind immer wie folgt aufgebaut: Private Sub ElementName_Ereignis([Parameterliste]) ElementName:
Der Name, unter dem das Steuerelement im Programm bekannt ist. Der Name entspricht der Eigenschaft Name (Abschnitt ).
Ereignis:
Das Ereignis, das eintreffen muß, um die Prozedur auszuführen. Dieses Ereignis kann entweder von einem Anwender oder vom System ausgelöst werden.
Parameterliste:
Die Parameterliste enthält alle Variablen, die beim Eintreffen des Ereignisses abgefragt werden können. Wird zum Beispiel eine Taste gedrückt, so ist in der Parameterliste enthalten, welche Taste gedrückt wurde. Die Parameterliste ist vom Ereignis abhängig und somit nicht immer vorhanden.
In diesem Kapitel werden die wichtigsten Ereignisse erklärt und ihre jeweiligen Funktionen anhand von Beispielen aufgezeigt.
137
Sandini Bib
6.1 Reagieren auf einmaliges Klicken mit der linken Maustaste
Click – der einfache Mausklick
Das Ereignis Click wird ausgelöst, wenn sich der Mauspfeil auf einem Steuerelement befindet und die linke Maustaste einmal gedrückt wird. Die Prozedur benötigt keine Parameter, da es immer nur eine Maus gibt, mit der dieses Ereignis ausgelöst wird. Click selbst reagiert nur auf die linke Maustaste oder das Bestätigen mit der (¢)-Taste. Hauptsächlich findet das Ereignis Click bei den Schaltflächen BUTTON Anwendung. Private Sub Form_Click() Private Sub Name_Click([Index As Integer]) Parameter
Beschreibung
Index
Wenn das Steuerelement ein Teil eines Feldes von Steuerelementen ist, identifiziert diese Indexnummer das Steuerelement eindeutig.
6.2 Reagieren auf das Doppelklicken mit der Maus
Der doppelte Mausklick: DblClick
Diese Prozedur wird mit einem Doppelklick der linken Maustaste auf ein Steuerelement ausgelöst. Ein Doppelklick ist das zweimalige Drücken der linken Maustaste in rascher Abfolge. Einfacher und doppelter Mausklick starten oft bestimmte Programmteile. In ListBoxen wird mit diesem Ereignis zumeist eine Aktion für das aktive Listenelement gestartet. Private Sub Form_DblClick() Private Sub Name_DblClick([Index As Integer]) Parameter
Beschreibung
Index
Wenn das Steuerelement ein Teil eines Feldes von Steuerelementen ist, identifiziert diese Indexnummer das Steuerelement eindeutig.
6.3 Reagieren auf das Laden eines Formulars in den Speicher
138
Das Laden eines Formulars durch Load
Das Ereignis Load tritt ein, wenn ein Fenster in den Hauptspeicher geladen wird. Dieses Ereignis wird z.B. immer vom Hauptfenster ausgeführt, wenn das Programm gestartet wird. Aus diesem Grund läßt sich das Ereignis hervorragend für die Initialisierung von Variablen verwenden. Zumeist werden auch in dieser Prozedur die Initialisierungen für das Programm geladen.
Sandini Bib
Für die Wiederholung dieses Ereignisses reicht es nicht aus, das Fenster zu verstecken und wieder anzuzeigen, sondern es muß aus dem Hauptspeicher entfernt werden. Private Sub Form_Load() Private Sub MDIForm_Load([Index]) Parameter
Beschreibung
Index
Wenn das Steuerelement ein Teil eines Feldes von Steuerelementen ist, identifiziert diese Indexnummer das Steuerelement eindeutig.
Mit den folgenden Befehlen lassen sich Fenster aus dem Hauptspeicher entfernen und wieder hineinladen. 'Wenn ein Fenster in den Hauptspeicher geladen werden 'soll Load Fenstername 'Wenn ein Fenster ein anderes aus dem Hauptspeicher 'entfernen soll UnLoad Fenstername 'Wenn sich ein Fenster selbst aus dem Speicher 'entfernen soll UnLoad Me
6.4
GotFocus
Dieses Ereignis wird ausgelöst, wenn das Steuerelement als aktives Element auf die Oberfläche gesetzt wird. Dies geschieht mit einem Mausklick auf das Steuerelement, mit der (ÿ)-Taste oder mit dem Programmcode über den Befehl SetFokus. Das Gegenstück zu GotFocus ist LostFocus (den Fokus verlieren).
Wenn ein Steuerelement oder ein Formular selektiert wird
Private Sub Form_GotFocus () Private Sub Name_GotFocus ([Index As Integer]) Parameter
Beschreibung
Index
Wenn das Steuerelement ein Teil eines Feldes von Steuerelementen ist, identifiziert diese Indexnummer das Steuerelement eindeutig.
139
Sandini Bib
6.5
Reagieren auf das Drücken oder Loslassen einer beliebigen Taste auf der Tastatur
KeyDown und KeyUp – Drücken und Loslassen einer Tastaturtaste
Wenn eine Taste auf der Tastatur gedrückt wird, tritt das Ereignis KeyDown ein. Wird die gedrückte Taste wieder losgelassen, tritt das Ereignis KeyUp ein. Wenn sich auf dem Fenster eine Schaltfläche mit der Eigenschaft Default = True befindet, kann bei keinem anderen Steuerelement geprüft werden, ob die Taste (¢) gedrückt wurde. Dasselbe gilt für die Taste (Esc), wenn sich auf dem Fenster eine Schaltfläche mit der Eigenschaft Cancel = True befindet. Private Form_KeyDown(KeyCode As Integer, Schift As Integer) Private Name_KeyDown([Index As Integer,] KeyCode As Integer, Schift As Integer) Private Form_KeyUp(KeyCode As Integer, Schift As Integer) Private Name_KeyUp([Index As Integer,] KeyCode As Integer, Schift As Integer) Parameter
Beschreibung
Index
Wenn das Steuerelement ein Teil eines Feldes von Steuerelementen ist, identifiziert diese Indexnummer das Steuerelement eindeutig.
KeyCode
Dieser Parameter liefert den Tastencode der gedrückten Taste zurück. Die Definitionen der einzelnen Tasten sind in der Datei Constant.txt von Visual Basic enthalten.
Shift
Diese Variable enthält den Status der Tasten (ª), (Strg) und (Alt): 1 Die (ª)-Taste ist gedrückt. 2 Die (Strg)-Taste ist gedrückt. 4 Die (Alt)-Taste ist gedrückt.
6.6
Reagieren auf das Drücken oder Loslassen einer beliebigen Maustaste
140
Drücken und Loslassen einer Maustaste mit MouseDown und MouseUp
Um festzustellen, welche Maustaste vom Anwender gerade gedrückt oder losgelassen wird, gibt es die Funktionen MouseDown und MouseUp. Die Funktion MouseDown wird vor dem Ereignis Click ausgeführt, wenn es sich um die linke Maustaste handelt. Wird eine gedrückte Maustaste losgelassen, tritt das Ereignis MouseUp ein. Dieses Ereignis tritt, im Falle der linken Maustaste, immer nach dem Ereignis Click ein. Im Gegensatz zum Ereignis MouseMove, das die Menge der gedrückten Tasten prüft, treten diese Ereignisse für jede gedrückte Maustaste auf.
Sandini Bib
Private Sub Form_MouseDown (Button As Integer, Shift As Integer, X As Single, Y As Single) Private Sub Name_MouseDown ([Index As Integer,] Button As Integer, Shift As Integer, X As Single, Y As Single) Private Sub Form_MouseUp (Button As Integer, Shift As Integer, X As Single, Y As Single) Private Sub Name_MouseUp ([Index As Integer,] Button As Integer, Shift As Integer, X As Single, Y As Single) Parameter
Beschreibung
Index
Wenn das Steuerelement ein Teil eines Feldes von Steuerelementen ist, identifiziert diese Indexnummer das Steuerelement eindeutig.
Button
Diese Variable gibt an, welche Maustaste dieses Ereignis ausgelöst hat: 1 Die linke Maustaste ist gedrückt. 2 Die rechte Maustaste ist gedrückt. 4 Die mittlere Maustaste ist gedrückt.
Shift
Diese Variable enthält den Status der Tasten (ª), (Strg) und (Alt): 1 Die (ª)-Taste ist gedrückt. 2 Die (Strg)-Taste ist gedrückt. 4 Die (Alt)-Taste ist gedrückt. Anhand des Wertes in der Variablen Shift läßt sich genau nachprüfen, welche Tastenkombination dieser Sondertasten gerade gedrückt wird.
X,Y
Diese beiden Variablen enthalten die aktuelle Mausposition: X Horizontale Mausposition. Y Vertikale Mausposition.
6.7
Mit MouseMove die Maus über ein Steuerelement bewegen
Wenn sich die Maus über ein Steuerelement bewegt, tritt das Ereignis MouseMove ein. Mit diesem Ereignis können Sie z.B. Hilfemeldungen in Statuszeilen ausgeben oder Systemvariablen setzen, die dann andere Steuerelemente ein- oder ausblenden. Des weiteren läßt sich hierbei feststellen, welche Tasten der Maus mit welchen Tastatur-Umschalttasten gedrückt sind. Tastatur-Umschalttasten sind in diesem Falle die Tasten (ª), (Strg) und (Alt).
Reagieren auf die Bewegung der Maus über ein Steuerelement
Private Sub Form_MouseMove (Button As Integer, Shift As Integer, X As Single, Y As Single) Private Sub Name_MouseMove ([Index As Integer,] Button As Integer, Shift As Integer, X As Single, Y As Single)
141
Sandini Bib
Parameter
Beschreibung
Index
Wenn das Steuerelement ein Teil eines Feldes von Steuerelementen ist, identifiziert diese Indexnummer das Steuerelement eindeutig.
Button
Diese Variable gibt an, welche Maustaste dieses Ereignis ausgelöst hat: 1 Die linke Maustaste ist gedrückt. 2 Die rechte Maustaste ist gedrückt. 4 Die mittlere Maustaste ist gedrückt. Anhand des Wertes in der Variablen Button läßt sich genau prüfen, welche Maustasten gedrückt sind.
Shift
Diese Variable enthält den Status der Tasten (ª), (Strg) und (Alt): 1 Die (ª)-Taste ist gedrückt. 2 Die (Strg)-Taste ist gedrückt. 4 Die (Alt)-Taste ist gedrückt. Anhand des Wertes in der Variablen Shift läßt sich genau nachprüfen, welche Tastenkombination dieser Sondertasten gerade gedrückt wird.
X,Y
Diese beiden Variablen enthalten die aktuelle Mausposition: X Horizontale Mausposition. Y Vertikale Mausposition.
6.7.1
Beispiel zum Ereignis MouseMove
In dem folgenden Beispiel soll die Position der Maus in einem Rahmensteuerelement ermittelt werden. Die aktuellen Koordinaten werden in zwei Beschriftungselementen ausgegeben. Wird zusätzlich eine Maustaste oder eine der Tasten (ª), (Strg) oder (Alt) gedrückt, während die Maus bewegt wird, so soll ebenfalls in einem Textfeld ausgegeben werden, welche dieser Tasten gedrückt wurde. In Abbildung 6.1 ist die Programmoberfläche abgebildet.
142
Sandini Bib
Abbildung 6.1: Die Programmoberfläche für das Beispiel „MouseMove“
In Tabelle 6.1 sind die zugehörigen Steuerelemente mit den Eigenschaften beschrieben, die für den Beispiel-Programmcode eingestellt sein müssen. Steuerelement
Eigenschaft
Inhalt
Beschreibung
RahmenSteuerelement
(Name)
frm_Maus
Es handelt sich hier um das Rahmensteuerelement, in dem die Mausdaten abgefragt werden sollen.
lab_X, lab_Y
Hier finden sich Beschriftungselemente zur Ausgabe der X- und Y-Mausposition im Koordinatensystem.
lab_Maus
Hier liegen Beschriftungselemente zur Ausgabe der Maustaste vor, die gedrückt wird.
lab_Taste
Diese Option dient zur Ausgabe der Information, welche der drei Tasten (ª), (Strg) oder (Alt) gedrückt wurde.
TextausgabeElemente
Tabelle 6.1: Die Steuerelemente des Beispiels „MouseMove“
Wenn die Maus in dem Rahmensteuerelement bewegt wird, sollen die Ausgabewerte in den Beschriftungsfeldern aktualisiert werden. Da der Programmcode in dem Ereignis MouseMove jedesmal aufgerufen wird, wenn der Anwender die Maus bewegt, muß somit auch hier die Ausgabe der geforderten Daten in die Steuerelemente stattfinden. Private Sub frm_Maus_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) 'Ausgabe der Mauskoordinaten lab_X.Caption = X lab_Y.Caption = Y
143
Sandini Bib
'Prüfen, welche der Maustasten gedrückt wird Select Case Button Case 0: lab_Maus.Caption = "" Case 1: lab_Maus.Caption = "Linke Maustaste" Case 2: lab_Maus.Caption = "Rechte Maustaste" Case 4: lab_Taste.Caption = "Mittlere Maustaste" End Select 'Prüfen, ob eine der Tasten Umschalt, Strg oder 'ALT gedrückt wird Select Case Shift Case 0: lab_Taste.Caption = "" Case 1: lab_Taste.Caption = "Umschalt-Taste" Case 2: lab_Taste.Caption = "Ctrl-Taste" Case 4: lab_Taste.Caption = "Alt-Taste" End Select End Sub
Befindet sich die Maus nicht mehr in dem Rahmensteuerelement, so müssen auch alle Ausgabewerte gelöscht werden. Eine Möglichkeit wäre, über die Berechnung der Koordinaten festzustellen, ob sich die Maus noch im zu prüfenden Bereich befindet. Die zweite, jedoch sehr viel einfachere Methode bedient sich des Ereignisses MouseMove vom Formular. Dieses Ereignis trifft dann ein, wenn das Rahmensteuerelement verlassen wird. Somit ist es am einfachsten, dort den Programmcode zu implementieren, der alle Ausgabewerte löscht. Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) lab_X.Caption = "" lab_Y.Caption = "" lab_Maus.Caption = "" lab_Taste.Caption = "" lab_Status.Caption = frm_Maus.Tag End Sub
144
Sandini Bib
6.8
Den Fokus verlieren: LostFocus
Dieses Ereignis wird ausgelöst, wenn das Steuerelement seinen Status von „aktiv“ auf „passiv“ wechselt. Dies geschieht, sobald mit der Maus ein anderes Steuerelement angeklickt oder mit der TAB-Taste das nächste Steuerelement aktiviert wird. Das Gegenstück zu LostFocus ist GotFocus (den Fokus erhalten).
Reagieren auf das Deaktivieren eines Steuerelements
Private Sub Form_LostFocus () Private Sub Form_LostFocus ([Index As Integer]) Parameter
Beschreibung
Index
Wenn das Steuerelement ein Teil eines Feldes von Steuerelementen ist, identifiziert diese Indexnummer das Steuerelement eindeutig.
!
145
Sandini Bib
Sandini Bib
7
Fehlerbehandlung in Visual Basic
In einem Programm können immer wieder Fehler auftreten, die nicht vorhersehbar sind. Wird z. B. eine Datei auf die Festplatte gespeichert, kann es passieren, daß der benötigte Platz größer ist als der zur Verfügung stehende. Auch bei Zugriffen auf eine Datenbank ist es möglich, daß das Programm auf Anfragen der Visual Basic-Applikation nicht mehr antwortet, da die Datenbank sich in einem Fehlerzustand befindet. Um zu verhindern, daß solche Systemfehler einen Programmabsturz verursachen, stellt Visual Basic eine Routine für die Fehlerbehandlung zur Verfügung. In diesem Kapitel werden die Befehlssyntax und ihre Arbeitsweise vorgestellt und durch zwei kurze Beispielprogramme verdeutlicht.
7.1
Vorgehensweise beim Auftreten eines Laufzeitfehlers
Fehlertolerante Programme
informieren den Anwender, daß ein Fehler aufgetreten ist,
beenden eventuell das Programmmodul, ohne daß Daten verlorengehen oder das gesamte System blockiert wird,
beeinträchtigen jedoch nicht den Programmablauf, sondern arbeiten dort weiter, wo der Fehler keinen Einfluß mehr hat – zumeist in dem Modul, welches das fehlerhafte Modul aufgerufen hat.
Für die Entwicklung eines solchen Programmes bietet Visual Basic 6.0 die im folgenden aufgeführten Befehle an.
147
Sandini Bib
7.1.1 Einleitung der Fehlerbehandlungsroutine
Der Befehl On Error
Wenn in einem Visual Basic-Programm während des Betriebs ein Fehler auftritt, so erscheint eine Fehlermeldung, und das Programm wird abgebrochen. Mit dem Befehl On Error kann dem Programm jedoch gesagt werden, wie es beim Auftreten eines Fehlers reagieren soll. Für die genaue Spezifikation, was explizit bei einem Fehler zu geschehen hat, werden die beiden Befehle Resume und Goto im Zusammenhang mit dem Befehl On Error verwendet. Der Befehl Goto
Sprungbefehl in einen beliebigen Programmteil
Der Befehl Goto (gehe zu) ist ein sog. direkter Sprungbefehl. Bei seiner Verwendung muß man als Parameter immer eine Zieladresse angeben, zu der hin der Sprung erfolgen soll. Im allgemeinen sollte dieser Befehl nicht verwendet werden, da er die Übersichtlichkeit der prozedualen Programmierung zerstört. In Verbindung mit dem Befehl On Error wird er jedoch sinnvoll verwendet (man sieht, keine Regel ohne Ausnahme). On Error Goto Sprungmarke ... Sprungmarke: ...
Tritt in dem Programmteil nach dem Befehl On Error Goto Sprungmarke ein Fehler auf, so wird die normale bzw. vorgesehene Abarbeitung unterbrochen und an der Sprungmarke fortgesetzt. Hier kann nun eine Ausgabe an den Benutzer erfolgen, um ihm mitzuteilen, daß ein Fehler aufgetreten ist, oder aber es wird eine besondere Funktion aufgerufen, die die Ursache des Fehlers bereinigt. Die Standardvorgabe hierfür lautet: On Error Goto 0
Mit dem Befehl Goto 0 wird das Visual Basic-Programm im Fehlerfall mit der Ausgabe einer Fehlermeldung beendet. Ist im Programm keine Fehlerbehandlung programmiert, so hat diese Zeile standardmäßig Gültigkeit. Das folgende Beispiel überprüft, ob eine Datei mit dem Namen DATEIexistiert. Wenn die Datei zum Lesen geöffnet werden kann, ist sie auch vorhanden. Die Funktion liefert den Wahrheitswert True zurück. Tritt beim Öffnen der Datei ein Fehler auf, wird der Wahrheitswert False zurückgeliefert. NAME
148
Sandini Bib
Function Datei_vorhanden(Dateiname As String) As Boolean Dim Datei As Integer On Error Goto Fehler_Division Datei = FreeFile Open Dateiname For Input As Datei close Datei Datei_vorhanden = True Exit Function Fehler_Division: Datei_vorhanden = False Exit Function End Function
Der Befehl Resume Der Befehl Resume kann mit „Wiederaufnahme“ übersetzt werden, d. h. bei Resume wird der Befehl an der Fehlerstelle solange wiederholt, bis kein Fehler mehr auftritt. Es kann also leicht eine Endlosschleife entstehen. Die Verwendung dieses Befehls in der Fehlerbehandlung geschieht wie folgt:
Wiederholen des letzten Befehles
On Error Resume
Diese Fehlerbehandlung hat zur Folge, daß eine Programmzeile solange ausgeführt wird, bis kein Fehler mehr auftritt. Sollte es sich bei diesem Fehler um eine nicht zu behebende Ursache handeln, entsteht eine Endlosschleife. Das folgende Beispiel ist eine solche Endlosschleife, wenn der Teiler 0 ist. Dieses Programm kann dann nur noch mit der Tastenkombination (Strg)+(Pause) beendet werden. Dim Zahl As Double Dim Teiler As Double 'Der Wert Teiler wird vom Benutzer eingegeben Zahl = 100 On Error Resume Ergebnis = Zahl / Teiler ...
Der Teiler wird vom Benutzer eingegeben. Sollte der Benutzer für den Teiler den Wert 0 wählen, kann die Division nicht durchgeführt werden, und es tritt ein Fehler auf. Der Programmcode bestimmt aber, daß die Zeile solange ausgeführt werden soll, bis der Fehler nicht mehr auftritt. Da sich aber der Wert der Variablen Teiler nicht ändert, sondern immer 0 bleibt, wird sich dieser Fehler nie beseitigen lassen – das Programm läuft endlos weiter. Aus diesem Grund gibt es eine Erweiterung des Befehls Resume.
149
Sandini Bib
Wiederaufsetzen des Programmablaufes beim nächsten Befehl
On Error Resume Next
Resume Next ignoriert die Befehlszeile, in der ein Fehler auftritt, und
verhindert, daß das Programm in der Endlosschleife bleibt. Das Programm sieht dann folgendermaßen aus: Dim Zahl As Double Dim Teiler As Double 'Der Wert Teiler wird vom Benutzer eingegeben. Zahl = 100 On Error Resume Next Ergebnis = Zahl / Teiler ...
Jetzt ist zwar das Problem mit der Endlosschleife gelöst, aber ein neues Problem ist entstanden: ein Fehlverhalten des Programms. Es rechnet nicht richtig, wenn der Wert der Variablen Teiler 0 ist, weil die Programmzeile, die die Berechnung durchführt, ignoriert wird. Folglich ist der Wert der Variablen Ergebnis nicht berechnet, sondern wurde auf den beim Funktionsaufruf initialisierten Wert 0 gesetzt. Das Objekt Err Das Objekt zur Fehlercodebehandlung
Um einen Fehler im Programm weiterverarbeiten zu können, werden für bestimmte Fehler, die auftreten können, Fehlernummern vergeben. Diese Fehlernummern werden im Objekt Err gespeichert. Solange kein Fehler auftritt, ist der Wert des Objekts Err gleich 0. Tritt ein Fehler auf, so kann der Fehlercode, also die Fehlerursache, über den Inhalt der Variablen Err ermittelt werden. Für das Beeinflussen des in Err gespeicherten Fehlers stehen folgende Funktionen zur Verfügung:
Funktion
Beschreibung
Err.Clear
Löscht den Fehlercode im Object Err. Diese Funktion entspricht der Zuweisung Err = 0
Err.Raise n...
Löst den Fehler mit dem Code n aus, wobei die Nummer n ein selbst definierter Fehlerwert sein kann.
Err.Description
Enthält den Fehlertext zur Fehlernummer.
Err. HelpContext
Ist ein Verweis auf den Hilfetext zum aktuellen Fenster.
Err.HelpFile
Ist ein Verweis auf die Hilfedatei.
Err.LastDLLError
Liefert den Fehlercode zur letzten aufgerufenen DLL-Datei.
Err.Number
Liefert die Fehlernummer; entspricht dem Wert in Err.
Err.Source
Ist die Zeichenkette, die das Modul oder den Befehl identifiziert, in dem der Fehler erzeugt wurde. Tabelle 7.1: Funktionen des Objekts „Err“
150
Sandini Bib
7.1.2
Der Befehl Error
Den Befehl Error gibt es in zwei Varianten: Die erste liefert als Ergebnis die Beschreibung zu einer Fehlernummer als String zurück, die zweite erzeugt einen Fehler mit dem Fehlercode n, d. h. dem Object Err wird ein Fehlercode zugewiesen. Error(n) Error n
7.2
Die Funktion für die Fehlercodebehandlung
'Liefert den Fehlertext zum Fehlercode n 'Erzeugt den Fehler mit dem Code n
Ein Programm zum Erstellen der Fehlercodetabelle
Das folgende Programm soll alle Fehlercodes, die in Visual Basic bekannt sind, in eine Tabelle schreiben. In der Tabelle sind dann die folgenden Angaben enthalten:
die Fehlernummer
die Fehlerbeschreibung
die zugehörige Hilfedatei
die ID des Hilfetextes in der Hilfedatei
Als Ausgangsprogramm dient das Projekt VORLAGE.VBP, das schon in einem Vorangegangenem Kapitel entwickelt wurde. Es befindet sich auf der beigefügten Diskette im Verzeichnis Vorlage. Um die Originalversion nicht zu verändern, sollte das Projekt mit dem Formular VORLAGE.FRM in ein neues Verzeichnis, zum Beispiel ERR_TAB, kopiert werden. Nachdem dies geschehen ist und die Projektdatei in Visual Basic geöffnet wurde, muß das Steuerelement DBGrid auf die Oberfläche gezogen werden. Die Eigenschaften des Grids müssen an diejenigen in Tabelle 7.1 angepaßt werden. Eigenschaft
Parameter
Name
grd_Fehler
Tag
Hier werden alle von Visual Basic definierten Fehler eingetragen.
Tabelle 7.2: Eigenschaften des Grids zur Ausgabe der Fehlercodes
Der Button OK kann von der Oberfläche gelöscht werden, da beim Aufrufen des Programms das Grid automatisch gefüllt wird. Folgende Funktionen werden gebraucht:
151
Sandini Bib
Sub Ueberschriften_eintragen() grd_Fehler.Col = 0 grd_Fehler.Row = 0 grd_Fehler.Text = "Nummer" grd_Fehler.ColWidth(0) = 750 grd_Fehler.Col = 1 grd_Fehler.Text = "Fehlermeldung" grd_Fehler.ColWidth(1) = 4000 grd_Fehler.Col = 2 grd_Fehler.Text = "Hilfedatei" grd_Fehler.ColWidth(2) = 2000 grd_Fehler.Col = 3 grd_Fehler.Text = "ID" grd_Fehler.ColWidth(3) = 1000 End Sub Sub Fehlertabelle_erzeugen() Dim I As Integer Dim MaxInt As Integer MaxInt = 1000 grd_Fehler.Cols = 4 grd_Fehler.Rows = 1 Call Ueberschriften_eintragen On Error GoTo Fehler For I = 1 To MaxInt Error I lab_Status.Caption = "Es ist " & CInt((I / MaxInt) * 100) & "% fertig" DoEvents Next I Exit Sub Fehler: If Len(Err.Description) > 0 Then grd_Fehler.Rows = grd_Fehler.Rows + 1 grd_Fehler.Row = grd_Fehler.Rows - 1 grd_Fehler.Col = 0 grd_Fehler.Text = Err.Number grd_Fehler.Col = 1 grd_Fehler.Text = Err.Description grd_Fehler.Col = 2 grd_Fehler.Text = Err.HelpFile grd_Fehler.Col = 3 grd_Fehler.Text = Err.HelpContext End If
152
Sandini Bib
Resume Next End Sub Private Sub Form_Activate() Call Fehlertabelle_erzeugen End Sub
Die Fehlercodetabelle
7.3
Fehlercode
Fehlermeldung
ID in der Hilfedatei
3
Return ohne GoSub.
1000003
5
Unzulässiger Prozeduraufruf oder ungültiges Argument.
1000005
6
Überlauf.
1000006
7
Nicht genügend Speicher.
1000007
9
Index außerhalb des gültigen Bereichs.
1000009
10
Datenfeld ist unveränderlich oder momentan gesperrt.
1000010
11
Division durch 0.
1000011
13
Typen unverträglich.
1000013
14
Nicht genügend Zeichenfolgenspeicher.
1000014
16
Ausdruck zu komplex.
1000016
17
Angeforderte Operation nicht durchführbar.
1000017
18
Unterbrechung durch Benutzer.
1000018
20
Resume ohne Fehler.
1000020
28
Nicht genügend Stapelspeicher.
1000028
35
Sub oder Function nicht definiert
1000035
47
Zu viele Clients für DLL-Anwendung.
1000047
48
Fehler beim Laden einer DLL.
1000048
49
Falsche DLL-Aufrufkonvention.
1000049
51
Interner Fehler.
1000051
52
Dateiname oder -nummer falsch.
1000052
53
Datei nicht gefunden.
1000053
54
Dateimodus falsch.
1000054
55
Datei bereits geöffnet.
1000055
57
Fehler beim Lesen von/Schreiben auf Gerät.
1000057
58
Datei existiert bereits.
1000058
59
Falsche Datensatzlänge.
1000059
61
Datenträger voll.
1000061
62
Einlesen hinter Dateiende.
1000062
153
Sandini Bib
Fehlercode
Fehlermeldung
ID in der Hilfedatei
63
Falsche Datensatznummer.
1000063
67
Zu viele Dateien.
1000067
68
Gerät nicht verfügbar.
1000068
70
Zugriff verweigert.
1000070
71
Datenträger nicht bereit.
1000071
74
Umbenennen bei Angabe unterschiedlicher Laufwerke nicht möglich.
1000074
75
Fehler beim Zugriff auf Pfad/Datei.
1000075
76
Pfad nicht gefunden.
1000076
91
Objektvariable oder With-Blockvariable nicht festgelegt.
1000091
92
For-Schleife nicht initialisiert.
1000092
93
Ungültige Musterzeichenfolge.
1000093
94
Unzulässige Verwendung von Null.
1000094
96
Ereignisse des Objekts können nicht aufgefangen werden, da von dem Objekt bereits Ereignisse für die maximale Anzahl an Ereignisempfängern ausgelöst werden.
1000096
97
Friend-Funktion eines Objekts, das keine Instanz der definierenden Klasse ist, kann nicht aufgerufen werden.
1000097
98
Eine Eigenschaft oder ein Methodenaufruf kann keinen Verweis auf ein privates Objekt enthalten, weder als Argument noch als Rückgabewert.
1000098
321
Ungültiges Dateiformat.
1000321
322
Erforderliche temporäre Datei kann nicht angelegt werden.
1000322
325
Ungültiges Format in Ressourcendatei.
1000325
380
Unzulässiger Eigenschaftswert.
1000380
381
Ungültiger Index für Eigenschaftenfeld.
1000381
382
Set wird zur Laufzeit nicht unterstützt.
1000382
383
Set wird nicht unterstützt (schreibgeschützte Eigenschaft).
1000383
385
Index für Eigenschaftenfeld benötigt.
1000385
387
Set nicht erlaubt.
1000387
393
Get wird zur Laufzeit nicht unterstützt.
1000393
394
Get wird nicht unterstützt (Eigenschaft kann nur gesetzt werden).
1000394
422
Eigenschaft nicht gefunden.
1000422
423
Eigenschaft oder Methode nicht gefunden.
1000423
424
Objekt erforderlich.
1000424
429
Objekterstellung durch ActiveX-Komponente nicht möglich.
1000429
430
Klasse unterstützt keine Automatisierung.
1000430
432
Datei- oder Klassenname während Automatisierungsoperation nicht gefunden.
1000432
438
Objekt unterstützt diese Eigenschaft oder Methode nicht.
1000438
154
Sandini Bib
Fehlercode
Fehlermeldung
ID in der Hilfedatei
440
Automatisierungsfehler.
1000440
442
Verbindung zur Klassen- oder Objektbibliothek für den Remote-Prozeß nicht mehr verfügbar. Klicken Sie auf 'OK', um einen Dialog anzuzeigen, mit dem Sie den Verweis entfernen können.
1000442
443
Automatisierungsobjekt hat keinen Standardwert.
1000443
445
Objekt unterstützt diese Aktion nicht.
1000445
446
Objekt unterstützt keine benannten Argumente.
1000446
447
Objekt unterstützt die aktuelle Ländereinstellung nicht.
1000447
448
Benanntes Argument nicht gefunden.
1000448
449
Argument ist nicht optional.
1000449
450
Falsche Anzahl an Argumenten oder ungültige Eigenschaftszuweisung.
1000450
451
Objekt ist keine Auflistung.
1000451
452
Ungültiger Ordinalwert.
1000452
453
Angegebene DLL-Funktion nicht gefunden.
1000453
454
Code-Ressource nicht gefunden.
1000454
455
Fehler durch gesperrte Code-Ressource.
1000455
457
Dieser Schlüssel ist bereits einem Element dieser Auflistung zugeordnet.
1000457
458
Variable verwendet einen in Visual Basic nicht unterstützten Typ der Automatisierung.
1000458
459
Objekt oder Klasse unterstützt diese Ereignismenge nicht.
1000459
460
Zwischenablagenformat ungültig.
1000460
481
Ungültiges Bild.
1000481
482
Druckerfehler.
1000482
735
Datei kann nicht in TEMP-Verzeichnis gespeichert werden.
1000735
744
Suchtext nicht gefunden.
1000744
746
Ersetzungen zu lang.
1000746
Tabelle 7.3: Fehlercodetabelle
155
Sandini Bib
Sandini Bib
8
Meldungen anzeigen
Um Meldungen an den Benutzer auszugeben, die bestätigt werden müssen, kann entweder ein Formular generiert, oder das Meldungsfenster MsgBox (Messagebox) verwendet werden, das Visual Basic zur Verfügung stellt. MsgBox(Meldungstext [, Schaltflächen][, Fenstertitel] [, Hilfedatei, HilfeID]
Beim Aufruf des Meldungsfensters können
der Meldungstext, der im Meldungsfenster ausgegeben werden soll,
der Fenstertitel des Meldungsfensters,
die Schaltflächen, die auf dem Meldungsfenster erscheinen sollen, und
die zugehörige Hilfe (Hilfedatei und HilfeID), die beim Drücken der Taste (F1) erscheinen soll,
festgelegt werden. Der Meldungstext und der Fenstertitel sind Zeichenketten. Im Meldungstext können – für eine übersichtlichere Darstellung – die Sonderzeichen
chr(9) für einen Tabulatorsprung,
chr(10) für den Zeilenvorschub (LineFeed),
chr(13) für den Wagenrücklauf sowie
chr(10) & chr(13) für den Zeilenvorschub mit Wagenrücklauf
verwendet werden. Die Länge der Zeichenkette im Meldungstext ist auf 1024 Zeichen begrenzt. Der Fenstertitel ist optional und braucht somit nicht angegeben zu werden. In diesem Fall tragen wir einfach den Namen des Projekts ein.
157
Sandini Bib
Der Parameter für die Schaltflächen ist ein numerischer Wert. Mit ihm wird angegeben, welche Schaltflächen in dem Meldungsfenster verfügbar sind. Wenn kein Wert für den Parameter Schaltflächen angegeben ist, werden folgende Standardeinstellungen gesetzt:
Das Meldungsfenster hat die Schaltfläche OK.
Die erste Schaltfläche wird beim Betätigen der (¢)-Taste aktiviert.
Das Fenster ist modal, d. h. die Applikation wird solange blockiert, bis eine Schaltfläche betätigt wurde.
In Tabelle 8.1 sind alle möglichen Werte, die die Eigenschaft Schaltflächen annehmen darf, definiert und erklärt.
vbOKOnly
vbOKCancel
vbAbortRetryIgnore
!
"#$%& $'$
vbYesNoCancel
(
)"$
vbYesNo
*
) $
vbRetryCancel
+
#$%&
vbCritical
,
" - .
vbQuestion
(!
" " / 01 . -
vbExclamation
*2
" " / 01 . #
vbInformation
,*
" " / 01 . $ 3 .3
vbDefaultButton1
% 34# 5(¢)6 7" 8 . 7 . 7 1
vbDefaultButton2
!+,
% %%6 7 5(¢) 8 . 7 . 7 1 3
158
Sandini Bib
vbDefaultButton3
+!
% % 5(¢) 8 . 7 . 7 1
vbApplicationModal
%- 8873 .3 %67 7 - 3 8873 00
vbSystemModal
*9,
%- :..33. /- %6 7 3 "0;3 8873 ; 60
Tabelle 8.1: Die Schaltflächenkonstanten mit Werten und ihrer Beschreibung
Durch die Kombination der einzelnen Werte können unterschiedliche Meldungsfenster erzeugt und den Bedürfnissen des Programms angepaßt werden. Die Eigenschaft Hilfedatei ist optional und enthält bei Bedarf den Dateinamen der Datei, in der sich die gewünschte Hilfe befindet. Wenn der Parameter Hilfedatei angegeben wurde, muß auch der Parameter HilfeID angegeben werden, damit festgelegt wird, welche Hilfe in der Datei geladen werden soll. Das folgende Beispiel verarbeitet alle von Visual Basic definierten Fehlermeldungen. Tritt ein Fehler auf, kann durch Drücken der Taste (F1) eine kontextbezogene Hilfe zum aktuellen Fehler angefordert werden. Sub Fehlermeldung(Fehler As Integer) Dim Meldung As String 'Die auszugebende Meldung Err.Number = Fehler
'Den aufgetretenen Fehler 'der Fehleranalyse 'zuweisen 'Erzeugen des Meldungstextes mit den Err-Objektdaten Meldung = "Fehler Nr: " & Err.Number & " im " & _ Programm: " & Err.Source & Chr(13) & _ "Fehlermeldung: " & Error(Err.Number) 'Ausgabe des Fehlers in einem Meldungsfenster. Call MsgBox(Meldung, 16, "Fehlermeldung", _ Err.HelpFile, Err.HelpContext) End Sub
159
Sandini Bib
Diese Funktion wird aus einer Fehlerbehandlungsroutine aufgerufen. Für Testzwecke reicht es aus, diese Funktion in das Standardprojekt Vorgabe einzubinden und in der Funktion btn_Ok_Click() folgende Programmzeilen zu implementieren: Private Sub btn_Ok_Click() On Error GoTo weiter
'Wenn ein Fehler auftritt, gehe 'zur Sprungmarke weiter Error 3 'Erzeuge Fehler mit Nummer 3 Exit Sub 'Wenn noch kein Fehler 'aufgetreten ist, verlasse die 'Funktion weiter: 'Wenn ein Fehler aufgetreten 'ist, mache hier weiter Call Fehlermeldung(Err.Number) 'Fehlermeldung 'ausgeben End Sub
Wird das Programm gestartet, erscheint das Meldungsfenster in Abbildung 8.1. Mit dem Befehl Error 3 wird der Fehler „Nr. 3“ von Visual Basic erzeugt. Dieser Wert kann für Testzwecke geändert werden. In einem regulären Programm würde diese Programmzeile natürlich nicht enthalten sein. Würde dann ein Fehler im Programm auftreten, gäbe Visual Basic eine Meldung aus, und mit der Taste (F1) erhielte man Hilfe zu dem aufgetretenen Fehler.
Abbildung 8.1: Meldungsfenster mit Ausgabe einer erzeugten Fehlermeldung
160
Sandini Bib
9
Grafikprogrammierung
Ein großer Vorteil der grafischen Benutzeroberfläche ist – wie der Name schon sagt – die Möglichkeit, Grafiken darzustellen. In diesem Abschnitt wird die Programmierung von verschiedenen Grafiken beschrieben. Zuerst werden jedoch die Grundlagen erörtert und einige Befehle erklärt.
9.1
Grundlagen zur Grafikausgabe
9.1.1
Farben
Es gibt in Visual Basic 6.0 zwei Funktionen, mit denen die Farbe definiert werden kann: zum einen die Funktion QBColor für die Darstellung von 16 Farben, zum anderen die Funktion RGB für die TrueColorFarbdarstellung. Die Farbfunktion „QBColor“ Farbe = QBColor(Farbnummer As Integer)
Parameter
Beschreibung
Farbe
Dieser Parameter enthält den Farbwert für den RGB-Farbenmodus von Visual Basic, der für die Farbgebung von Steuerelementen und Objekten benötigt wird.
Farbnummer
Dieser Parameter listet die Farbnummern aus dem 16-Farben-Modus auf. 0 Schwarz
8
Dunkelgrau
1 Blau
9
Hellblau
2 Grün
10 Hellgrün
3 Türkis
11 helles Türkis
4 Rot
12 Hellrot
5 Fuchsinrot
13 helles Fuchsinrot
6 Braun
14 Gelb
7 Hellgrau
15 Weiß
161
Sandini Bib
Die Funktion QBColor rechnet die Farben aus dem 16-Farben-Modus in die Farben des RGB-Modus um. Dieser Befehl ist noch aus Gründen der Kompatibilität zu älteren Visual Basic-Versionen vorhanden. Er findet in der Programmierung unter den Visual Basic-Versionen ab Version 4.0 wenig Einsatz. Die „RGB“-Farbfunktion Farbe = RGB(Rot As Integer, Grün As Integer, Blau As Integer)
Parameter
Beschreibung
Farbe
Enthält den Farbwert für den RGB-Farben-Modus von Visual Basic, der für die Farbgebung der Steuerelemente und Objekte benötigt wird.
Rot
Gibt den Rotanteil an, den der Ergebnisfarbwert besitzt.
Grün
Gibt den Grünanteil an, den der Ergebnisfarbwert besitzt.
Blau
Gibt den Blauanteil an, den der Ergebnisfarbwert besitzt.
Mit der RGB-Methode können Farben mit 256 verschiedenen Rot-, Grün- und Blauanteilen ausgegeben werden. Rein rechnerisch können somit 256 x 256 x 256 = 16.777.216 verschiedene Farben dargestellt werden.
9.1.2
Die Line-Methode
Mit dieser Methode können einzelne oder miteinander verbundene Linien sowie Rechtecke gezeichnet werden. Um die Eigenschaften einer Linie festzulegen, stehen die folgenden Befehle zur Verfügung:
162
DrawWidth Definiert die Linienbreite.
DrawMode
Definiert die Art der Linie vor dem Hintergrund.
DrawStyle
Definiert die Art der Linie bezüglich ihres Aussehens (durchgezogen, gestrichelt ...).
Sandini Bib
Die Line-Methode setzt sich wie folgt zusammen: Object.Line [Step][(X1, Y1)] [Step](X2, Y2), [Farbe], [B][F] Parameter
Beschreibung
Objekt
Wenn das Steuerelement ein Teil eines Feldes von Steuerelementen ist, identifiziert diese Indexnummer das Steuerelement eindeutig.
Step
Mit dem Schlüsselwort Step wird angegeben, ob die in den Parametern (X1, Y1) angegebene Anfangsposition der Linie relativ zur aktuellen Grafikposition ist oder ob es sich um absolute Koordinaten in dem aktuellen Object handelt. Wird das Schlüsselwort Step angegeben, ist die Anfangsposition relativ zur aktuellen Grafikposition.
(X1, Y1)
Diese beiden Parameter sind optional, d. h., wenn diese Parameter fehlen, wird der Anfang der Linie auf die aktuelle Grafikposition festgelegt.
Step
Das zweite Schlüsselwort Step bezieht sich auf die Endkoordinaten der Linie und ist ebenfalls optional. Für dieses Schlüsselwort gilt dasselbe wie für das Schlüsselwort Step, das sich auf die Anfangskoordinaten bezieht.
(X2, Y2)
Mit diesen Koordinaten wird der Endpunkt der Linie festgelegt und somit auch die neue Grafikposition. Dieses Parameterpaar ist unbedingt anzugeben.
Farbe
Dieser Parameter definiert die Farbe, in der die Linie oder das Rechteck gezeichnet wird. Es handelt sich hierbei um eine Variable vom Typ Long, die die RGB-Farbe festlegt. Legt man keine Farbe fest, wird automatisch die Einstellung der ForeColor-Eigenschaft verwendet.
B
Ist der Parameter B angegeben, wird ein Rechteck gezeichnet, wobei die Koordinaten dann die diagonale Linie in dem Rechteck definieren. Also sind die Koordinaten gleichbedeutend mit den gegenüberliegenden Ecken des Rechtecks.
F
Dieser Parameter wird immer nur in Verbindung mit dem Parameter B verwendet. F gibt an, ob das Rechteck mit der Farbe gefüllt werden soll, die auch zum Zeichnen des Rechteckrahmens verwendet wurde, oder ob die Einstellungen aus den Eigenschaften
FillColor
FillStyle
verwendet werden sollen. Ist F angegeben, wird das Rechteck mit der Rahmenzeichenfarbe gefüllt.
163
Sandini Bib
9.1.3
Die Methode Circle
Mit Circle können Sie Kreise, Ellipsen oder Kreisbögen zeichnen. Zur Definition der Linienstärke und der Fläche stehen folgende Befehle zur Verfügung:
DrawWidth Definiert die Linienbreite.
DrawMode
Definiert die Art der Linie vor dem Hintergrund.
DrawStyle
Definiert die Art der Linie bezüglich ihres Aussehens (durchgezogen, gestrichelt ...).
Die Methode Circle setzt sich wie folgt zusammen: Object.Circle [Step] (X,Y), Radius, [Farbe, Start, Ende, Verhältnis] Parameter
Beschreibung
Step
Mit dem Schlüsselwort Step wird angegeben, ob der Mittelpunkt des Zeichnungselements die aktuelle Grafikposition ist oder ob es sich um absolute Koordinaten in dem aktuellen Objekt handelt. Wird das Schlüsselwort Step angegeben, ist die Anfangsposition relativ zur aktuellen Grafikposition.
(X, Y)
Diese beiden Parameter sind unbedingt erforderlich: Diese Koordinaten geben den Mittelpunkt des Zeichnungselements an.
Radius
Dieser Parameter ist ebenfalls erforderlich und gibt den Radius des Zeichnungselements an.
Farbe
Mit diesem Parameter wird die Farbe des Zeichnungselements festgelegt; er ist optional. Wenn kein Farbwert definiert wird, erfolgt die Färbung des Zeichnungselements in der Farbe, die in der Eigenschaft ForeColor des Objekts definiert wurde. Der Wert, der die Farbe definiert, kann entweder ein RGB-Farbwert oder ein Farbwert der QBColor-Funktion sein.
164
Start
Dieser Parameter gibt den Startpunkt an, wenn es sich bei dem Zeichnungselement um kein geschlossenes Element handeln soll (wie z.B. einen Kreis).
Ende
Dieser Parameter gibt den Endpunkt an, wenn es sich bei dem Zeichnungselement um kein geschlossenes Element handeln soll (wie z.B. einen Kreis).
Verhältnis
Mit diesem Parameter wird das Seitenverhältnis der Ellipse angegeben. Ist das Verhältnis 1, erhält man einen Sonderfall, den Kreis. Wird dieser Parameter nicht angegeben, ist der Wert 1 voreingestellt und somit ein Kreis vorgegeben.
Sandini Bib
9.2
Grafische Beispiele
In dem folgenden Abschnitt werden zwei grafische Beispielprogramme gezeigt, mit denen die Möglichkeiten der grafischen Programmierung unter Visual Basic dargestellt werden sollen. Als Grundlage dient ebenfalls das mitgelieferte Vorgabeprojekt auf der Diskette, so daß man sich ganz auf die Grafikprogrammierung konzentrieren kann.
9.2.1
RGB-Farbenbeispiel
In diesem Beispiel wird ein Programm entwickelt, mit dem alle RGBFarben in einem Bildfeld-Steuerelement dargestellt werden können. Die Farbwerte der drei Grundfarben Rot, Grün und Blau werden über Bildlaufleisten eingestellt. In drei Bildfeld-Steuerelementen wird die jeweilige Grundfarbe angezeigt, in einer weiteren, vierten die Farbe, die sich als Mischung aus den drei Farben ergibt. Zu jedem BildfeldSteuerelement gibt es ein Texteingabeelement, in dem der jeweilige Farbwert ausgegeben wird. Der Farbwert kann aber auch über das Texteingabeelement geändert werden. Die Programmoberfläche Um die gestellten Anforderungen zu erfüllen, ist eine Programmoberfläche wie in Abbildung 9.1 nötig.
Abbildung 9.1: Die Programmoberfläche für das RGB-Farbenbeispiel
165
Sandini Bib
Für jede der drei Grundfarben gibt es eine Bildlaufleiste mit einem zugehörigen Texteingabeelement und einer Bildschaltfläche. In einer zusätzlichen Bildschaltfläche und einem Texteingabeelement wird der gesamte RGB-Farbwert aller drei Farben ausgegeben. Mit der Taste AUTOMATISCH werden die drei Farbregler vom Programm verschoben und erzeugen automatisch einige mögliche Farben. In Tabelle 9.1 sind die Eigenschaften der benötigten Steuerelemente beschrieben. Als Projektgrundlage kann das Programm VORLAGE, das Sie auf der beigefügten Diskette finden, verwendet werden. Steuerelement
Eigenschaft
Inhalt
Beschreibung
Bildlaufleisten
(Name)
hsc_Farbe(0-2)
Dient zum Regeln des Anteils der jeweiligen Grundfarbe an die RGB-Farbe.
pic_Farbe(0-2)
Stellt den jeweiligen Farbwert dar, der mit den Bildlaufleisten definiert wurde.
pic_RGB
Stellt die Farbe dar, die aus dem Mischen der eingestellten Grundfarben entsteht.
txt_Farbe(0-2)
Dient zur Ein- und Ausgabe des aktuellen Farbwerts einer Grundfarbe.
txt_RGB
Dient zur Ein- und Ausgabe des aktuellen RGB-Farbwerts.
Bildfeld-Steuerelemente
TexteingabeElement
Tabelle 9.1: Die Steuerelemente zum RGB-Farbenbeispiel
Die Programmentwicklung Wird das Programm gestartet, müssen zuerst alle Farbwerte initialisiert werden. Für diesen Vorgang wird das Ereignis Load des Formulars benutzt. Als erstes wird der Wertebereich festgelegt, in dem sich die Bildlaufleisten bewegen. Da die RGB-Funktion in allen drei Eingabeparametern einen Wertebereich von 0 bis 255 hat, wird auch der Wertebereich der Bildlaufleisten von 0 bis 255 definiert. Dann werden die Bildlaufleisten auf 0 zurückgesetzt und alle anderen Steuerelemente an die eingestellten Farbwerte in den Bildlaufleisten angepaßt. Nach der Initialisierung sind somit alle drei Farbwerte ausgeschaltet. Private Sub Form_Load() Dim i As Integer 'Initialisieren der Farbbereiche For i = 0 To 2 hsc_Farbe(i).Min = 0 hsc_Farbe(i).Max = 255 hsc_Farbe(i).Value = 0 pic_Farbe(i).BackColor = 0
166
Sandini Bib
txt_Farbe(i).Text = 0 Next i 'Initialisieren des Misch-Farbfeldes pic_RGB.BackColor = 0 txt_RGB.Text = 0 End Sub
Als nächstes muß der Programmcode entwickelt werden, der jede Änderung der Bildlaufleisten in den Bildfeld- und Texteingabe-Elementen aktualisiert. Hierfür wird das Ereignis Change der Bildlaufleisten verwendet. Private Sub hsc_Farbe_Change(Index As Integer) Dim Farbe(3) As Integer 'In Index ist die Bildlaufleiste enthalten, deren Wert sich 'geändert hat die beiden anderen Farben sind unverändert. Farbe(Index) = 1 'Aktualisiere den RGB_Farbwert pic_RGB.BackColor = RGB(hsc_Farbe(0).Value, _ hsc_Farbe(1).Value, hsc_Farbe(2).Value) 'Aktualisiere die Farbe in dem der Bildlaufleiste zugehörigen 'Bildfeld-Steuerelement. pic_Farbe(Index).BackColor = RGB( _ Farbe(0) * hsc_Farbe(0).Value, _ Farbe(1) * hsc_Farbe(1).Value, _ Farbe(2) * hsc_Farbe(2).Value) 'Aktualisiere auch die jeweiligen Textschaltflächen txt_RGB.Text = pic_RGB.BackColor txt_Farbe(Index).Text = hsc_Farbe(Index).Value End Sub
Werden nun die Bildlaufleisten verschoben, werden ebenfalls alle Farben, die sich ändern, aktualisiert. Um auch die Farben anzupassen, wenn sich der Inhalt der Textelemente ändert, muß in dem Ereignis KeyUp die Einstellung der jeweiligen Bildlaufleiste geändert werden. Durch das Ändern der Bildlaufleistenvariablen wird das Ereignis Change ausgelöst, und alle Felder werden nach dem zuvor beschriebenen Ablauf aktualisiert. Der Programmcode muß im KeyUpEreignis enthalten sein, damit es keine Rückkopplung geben kann und das Programm keinen Fehler verursacht. Des weiteren muß die Eingabe in die Textelemente auf ihre Gültigkeit hin geprüft werden. Wird z.B. eine Zahl in die Grundfarbenelemente eingegeben, die größer als 255 oder kleiner als 0 ist, so muß dieser falsche Wert erkannt und ersetzt werden. Der zulässige Höchstwert bei dem RGB-Farb-Textelement ist (256 x 256 x 256) – 1 = 16777215.
167
Sandini Bib
Private Sub txt_Farbe_KeyUp(Index As Integer, KeyCode As Integer, Shift As Integer) Dim Speicher As Long On Error GoTo Fehler_txt_Farbe_KeyUp Speicher = CLng("0" & txt_Farbe(Index).Text) If Speicher > 255 Or Speicher < 0 Then Speicher = 255 End If hsc_Farbe(Index).Value = Speicher Exit Sub Fehler_txt_Farbe_KeyUp: txt_Farbe(Index).Text = Speicher Exit Sub End Sub Private Sub txt_RGB_KeyUp(KeyCode As Integer, Shift As Integer) Dim Speicher As Long On Error GoTo Fehler_txt_RGB_KeyUp Speicher = CLng("0" & txt_RGB.Text) If Speicher > 16777215 Or Speicher < 0 Then Speicher = 16777215 End If hsc_Farbe(0).Value = Speicher Mod 256 Speicher = (Speicher – (Speicher Mod 256)) / 256 hsc_Farbe(1).Value = Speicher Mod 256 Speicher = (Speicher – (Speicher Mod 256)) / 256 hsc_Farbe(2).Value = Speicher Mod 256 Exit Sub Fehler_txt_RGB_KeyUp: txt_RGB.Text = Speicher Exit Sub End Sub
Zum Schluß wird noch der automatische Ablauf für den Farbenwechsel programmiert. Hierbei werden die Bildlaufleisten über For-Schleifen bewegt. Diese Funktion läßt sich beliebig erweitern. Die hier aufgeführte Funktion ist nur ein kleiner Auszug aus den möglichen Bewegungsabläufen. Private Sub btn_Ok_Click() Dim i As Integer Dim Farbe As Long 'Alle Eingabemöglichkeiten sperren frm_RGB_Farben.Enabled = False 'Die Farben neu initialisieren hsc_Farbe(0).Value = 0 hsc_Farbe(1).Value = 0
168
Sandini Bib
hsc_Farbe(2).Value = 0 For i = 0 To 2 'Alle Farbregler nacheinander For Farbe = 0 To 255 'nach oben aussteuern hsc_Farbe(i).Value = Farbe DoEvents Next Farbe For Farbe = 0 To 255 'und wieder zurückregeln hsc_Farbe(i).Value = 255 – Farbe DoEvents Next Farbe Next i 'Alle drei Farben gleichzeitig aufs Maximum hochregeln For Farbe = 0 To 255 hsc_Farbe(0).Value = Farbe hsc_Farbe(1).Value = Farbe hsc_Farbe(2).Value = Farbe DoEvents Next Farbe 'Alle Eingabemöglichkeiten wieder frei schalten frm_RGB_Farben.Enabled = True End Sub
9.2.2
Chaos auf dem Bildschirm – das „fraktale Apfelmännchen“
Wer kennt es nicht, das „fraktale Apfelmännchen“! Es ist ein sehr schönes Beispiel, um einzelne Bildpunkte in einem Fenster zu definieren. Das Beispielprogramm soll das „fraktale Apfelmännchen“ in einem Anzeige-Steuerelement ausgeben (ohne daß hierbei näher auf die Definition des Apfelmännchens eingegangen wird). Dies soll die Möglichkeit bieten, einige Grafikbefehle kennenzulernen. Der Algorithmus, der dieser Berechnung zugrundeliegt, kann im Buch „Visual Basic 5.0. Effiziente Programmentwicklung unter Windows 95“ von Michael Kofler bzw. in anderen Fachbüchern nachgelesen werden. Die Vorgaben des „fraktalen Apfelmännchens“ Die folgenden Konstanten definieren den Wertebereich, in dem die Berechnung der Fraktale durchgeführt wird. Const Aufloesung = 250 Const X_Oben = 1.7 Const X_Unten = –0.8 Const Y_Oben = 1.2 Const Y_Unten = –1.2 Dim Farben As Long
169
Sandini Bib
Berechnung des Farbwerts Die folgende Funktion berechnet den Farbwert, den ein Bildpunkt in dem Ausgabefenster erhalten soll. Private Function Fraktale(X As Integer, y As Integer) As Integer Dim u As Double Dim a As Double Dim Merker As Double Dim Real As Double 'Realteil der komplexen Zahl Dim Imaginaer As Double 'Imaginärteil der komplexen 'Zahl Dim Iteration As Integer 'Anzahl der Berechnungen u = 0 'Initialisierung der Startwerte a = 0 'für die Iteration Iteration = 0 On Error GoTo Err_Fraktale 'Berechnung des Realanteiles und des Imaginäranteiles 'der komplexen Zahl Real = X_Unten + X * ((X_Oben – X_Unten) _ / Aufloesung) Imaginaer = Y_Oben – y * ((Y_Oben – Y_Unten) _ / Aufloesung) 'Berechnen des Farbwertes anhand der benötigten 'Iterationsdurchläufe While a < 4 And Iteration < 15 DoEvents Merker = (u ^ 2 – a ^ 2) – Real a = 2 * u * a – Imaginaer u = Merker Iteration = Iteration + 1 Wend Fraktale = Iteration Exit Function Err_Fraktale: Fraktale = Iteration End Function
Aufruf des Berechnungsalgorithmus Mit der folgenden Funktion wird die Größe des Ausgabefensters ermittelt, an die sich die geforderte Auflösung des „fraktalen Apfelmännchens“ anpaßt. Durch Betätigen der Schaltfläche OK wird die Berechnung für jeden Bildpunkt gestartet.
170
Sandini Bib
Private Sub btn_Ok_Click() Dim i As Integer 'Zähler der X–Achse des Koordinatensystems Dim j As Integer 'Zähler der Y–Achse des Koordinatensystems Dim X As Double Dim y As Double Dim Iteration As Integer 'Anzahl der benötigten Berechnungen 'Berechnung der Länge und Höhe eines Bildpunkts X = pic_Bild.ScaleWidth / Aufloesung y = pic_Bild.ScaleHeight / Aufloesung 'Berechnung des Farbwertes von jedem Bildpunkt im Koordinatensystem For i = 0 To Aufloesung - 1 For j = 0 To Aufloesung - 1 DoEvents Iteration = Fraktale(i, j) pic_Bild.Line (i * X, j * y)-((i + 1) * X, _ (j + 1) * y), QBColor(Iteration), BF Next j Next i End Sub
Das Ergebnis In Abbildung 9.2 ist das fertig berechnete „fraktale Apfelmännchen“ dargestellt. Je nach Leistungsfähigkeit des eingesetzten Computers und gewählter Auflösung kann die Berechnung dieses Bildes mehrere Minuten in Anspruch nehmen.
Abbildung 9.2: Das „fraktale Apfelmännchen“
171
Sandini Bib
Sandini Bib
10
Der Menüdesigner
Alle bisher entwickelten Applikationen bestanden nur aus den Steuerelementen. Unter Windows besitzen aber die meisten Programme auch eine Menüzeile. Auch in Visual Basic hat man die Möglichkeit, eine Menüzeile für die Programme zu generieren. Hierfür wird der Menüdesigner bereitgestellt (Abbildung 10.1). Man startet ihn über das Menü EXTRAS | MENÜ-EDITOR...
Abbildung 10.1: Der Menüdesigner
Im Menüdesigner müssen zwei grundsätzliche Einträge gemacht werden: zum einen die Menüoption, zum anderen die Funktion bzw. Prozedur, die mit diesem Menüpunkt aufgerufen werden soll. Bevor mit dem Entwurf des Menüs begonnen werden kann, sollten die Menüeinträge und ihre Struktur definiert sein. Für dieses Design bietet sich die Baumstruktur an, wie sie z.B. zur Darstellung des Dateisystems im Datei-Manager verwendet wird. Des weiteren sollten Standardfunktionen, die durch Windows-Standards unterstützt werden,
173
Sandini Bib
in Menüs implementiert sein. Im allgemeinen sind dies Funktionen aus den Menüs
DATEI SPEICHERN, SPEICHERN UNTER, DRUCKEN, BEENDEN;
BEARBEITEN RÜCKGÄNGIG, WIEDERHOLEN, AUSSCHNEIDEN, KOPIEREN, EINFÜGEN, INHALTE EINFÜGEN, LÖSCHEN, MARKIEREN, SUCHEN, ERSETZEN;
Fenster NEUES FENSTER, ANORDNEN, TEILEN;
? (für HILFE) INHALT, SUCHEN, INDEX.
In dem Feld Caption werden die Menütexte eingetragen. Um die einzelnen Menübefehle über die (Alt)-Taste aktivieren zu können, muß vor den Buchstaben, der mit der (Alt)-Taste das Menü aktivieren soll, das kaufmännische „Und“ (&) gesetzt werden. Dieser Buchstabe erscheint dann unterstrichen im Menü. Im Textfeld Name muß die interne Bezeichnung des Menüpunkts eingetragen werden. Dieser Name identifiziert dann den Menüpunkt, so wie der Name in einem Steuerelement das Steuerelement identifiziert. Aus diesem Grund sollte auch für diesen Namen eine Kennung zur Identifizierung vergeben werden. In den angeführten Beispielen wird dies die Kennung mnu sein. Sollten in einem Programm dann etwa eine Schaltfläche und ein Menüeintrag zum Beenden des Programmes vorhanden sein, können beide die gleiche Bezeichnung haben, z.B. ABBRECHEN, und durch die Kennung, die vorangestellt wird, unterschieden werden: btn_Abbrechen mnu_Abbrechen.
Diese Art der Namensvergabe ist sehr übersichtlich, da anhand des Namens erkennbar ist, daß beide Funktionen das Programm gleichermaßen beeinflußen sollen, aber unterschiedliche Steuerelemente sind. In Visual Basic ist es zwar erlaubt, daß zwei Pull-Down-Einträge in einem Menü den gleichen Namen haben, sie müssen sich dann jedoch in ihren Indexwerten unterscheiden. Über die Schaltflächen (Abbildung 10.2) kann man die Position eines Menüeintrags im Menü definieren. Die beiden linken Buttons geben die Ebenen im Menü an, die beiden rechten Buttons die vertikale Position im Menü. Für die Menüleiste gilt: der oberste Eintrag im Menüdesigner ist im Menü ganz links, der unterste ganz rechts positioniert.
174
Sandini Bib
Abbildung 10.2: Die Pfeilschaltflächen des Menüdesigners
Die CheckBox Enabled gibt an, ob der Menüpunkt verfügbar ist. Mit dieser Eigenschaft kann während der Laufzeit eine Menüoption abgeschaltet werden. Wenn z. B. ein bestimmter Prozeß in einem Programm ausgeführt wird, der nicht abgebrochen werden darf, läßt sich über diese Eigenschaft der Menüpunkt BEENDEN deaktivieren. Der Benutzer sieht diesen Menüeintrag, kann ihn jedoch nicht aktivieren. Die CheckBox Visible gibt an, ob dieser Menüeintrag sichtbar ist. Also: Wenn im Pull-Down-Menü unter DATEI im Menüdesigner fünf Punkte eingetragen werden und dabei zwei als unsichtbare gesetzt werden, erscheinen während der Programmausführung nur die anderen drei Einträge. Mit dieser Option läßt sich somit das sog. kontextabhängige Menü realisieren: Es sind dadurch immer nur diejenigen Menübefehle sichtbar, die auch ausgeführt werden können. Um bei einem Menüeintrag das Checked-Zeichen („“) anzuzeigen, z.B. um zu verdeutlichen, daß diese Option aktiviert wurde, gibt es die ebenso genannte Eigenschaft Checked. Das Zeichen befindet sich im Menü FENSTER, wo es ausgibt, welches aktiviert ist. Mit der Option Shortcut kann man einstellen, mit welcher Tastenkombination dieser Menüpunkt ausgeführt werden kann. In Windows gibt es z.B. folgende standardmäßige Shortcuts: (Strg)+(X) für Ausschneiden, (Strg)+(K) für Kopieren, (Strg)+(V) für Einfügen,
10.1
Aufgabe
Sie sollen nun ein Programmenü entwickeln, das alle Windows-Standardmenüs enthält.
10.2
Lösung
Das Lösungsprogramm befindet sich auf der Diskette im Verzeichnis \MENU. In Abbildung 10.3 ist das Menü dargestellt, wie es im Menüdesigner aussieht. Abbildung 10.4 zeigt das Dateimenü während der Programmausführung.
175
Sandini Bib
Abbildung 10.3: Das Beispielmenü im Menüdesigner während der Designphase
Abbildung 10.4: Das fertige Beispielmenü
176
Sandini Bib
11
Aufbau eines Visual BasicProjekts
Es gibt in der Programmierung zwei große Klassen, denen die meisten Programmiersprachen zugeordnet werden können: die ablaufgesteuerten und die ereignisgesteuerten Programmiersprachen.
11.1
Ablaufgesteuerte Programmierung
Ablaufgesteuerte Programmierung bedeutet, daß der Programmfluß eindeutig definiert ist. In diesem Fall kann man ein sogenanntes Flußdiagramm mit einem Anfang und einem Ende zeichnen (siehe Abbildung 11.1).
Abbildung 11.1: Beispiel eines schematischen Ablaufplans
177
Sandini Bib
Der Programmfluß mit Programmanfang und Programmende ist eindeutig erkennbar. Programme, die immer eine sog. Start- oder Hauptfunktion benötigen, fallen in die Kategorie der ablaufgesteuerten Programmiersprachen. 11.2
Ereignisgesteuerte Programmierung
Visual Basic ist eine ereignisgesteuerte Sprache und reagiert deshalb auf unterschiedliche Ereignisse, die auf das Programm einwirken, in unterschiedlicher Weise. Das Programmbeispiel zeigt, daß ein Ereignis, das während der Ausführung eines Programmteils eintrift, diesen unterbricht und einen neuen startet. Die Programmteile sind zwar voneinander unabhängig; dennoch kann das Programm nur einen Ablauf steuern. Als Grundlage für das Beispielprogramm dient ebenfalls das Vorgabeprojekt auf der Diskette. Die Schaltfläche OK wird in EREIGNIS1 umbenannt. Zusätzlich wird eine dritte Schaltfläche mit Namen EREIGNIS2 benötigt. Um den Status der einzelnen Ereignisse anzuzeigen, werden zwei Textelemente benötigt. Die beiden Ereignisse sind einfach nur zwei For-Schleifen, die den Inhalt der Zählvariablen in das jeweilige Textelement schreiben. Im folgenden ist der zugehörige Programmcode abgebildet. Private Sub btn_Ereignis1_Click() Dim i As Integer For i = 0 To 32000 DoEvents lab_Ereignis1.Caption = i Next i End Sub Private Sub btn_Ereignis2_Click() Dim i As Integer For i = 0 To 32000 DoEvents lab_Ereignis2.Caption = i Next i End Sub
Wird die Schaltfläche EREIGNIS1 betätigt, beginnt die For-Schleife mit der Ausgabe des aktuellen Zählschleifenwerts im Textelement. Wird nun die Schaltfläche EREIGNIS2 betätigt, bleibt der aktuelle Schleifenwert des ersten Ereignisses im Textelement bestehen. Im Textelement für das zweite Ereignis wird mit der Ausgabe des aktuellen Schleifenwertes begonnen.
178
Sandini Bib
Im ersten Moment mag dies sehr vorteilhaft aussehen. Dennoch passieren durch diesen Effekt viele Programmabstürze. Folgendes theoretisches Programmbeispiel soll das Problem erläutern: Durch Betätigen der Schaltfläche EREIGNIS1 wird eine Tabelle Adressen aus einer Datenbank erzeugt. Das Ereignis, das durch die Schaltfläche EREIGNIS2 ausgelöst wird, greift auf die Tabelle Adressen zu und generiert nun eine Tabelle Städte. Wird nun die Schaltfläche EREIGNIS2 betätigt, während noch die Tabelle Adressen generiert wird, ist dieser Prozeß noch nicht abgeschlossen, und die Ergebnistabelle Städte ist falsch. Um solche Fehler zu vermeiden, sollten die Steuerelemente nur verfügbar sein, wenn kein Prozeß aktiv ist. Wird ein Prozeß gestartet, werden alle Steuerelemente, die einen Fehler erzeugen können, solange auf gesperrt gesetzt, bis der Prozeß erfolgreich abgeschlossen ist.
179
Sandini Bib
Sandini Bib
12
12.1
Entwicklung einer komplexen Applikation
Beschreibung des Programms „StackTaschenrechner“
In diesem Kapitel soll nun endlich eine komplexere Anwendung entwickelt werden, als dies bisher der Fall war – ein Stack-Taschenrechner. Diese Art Taschenrechner arbeitet mit der Postfix-Notation, d. h. es sind zunächst der oder die Operanden einzugeben und dann erst der Operator, da die Zahlen in einem Stack gespeichert werden. Dieser Stack arbeitet wie eine LiFo-Liste1. Es ist zwar für einen Taschenrechner ungewöhnlich, nach dieser Art zu rechnen, doch hat dies den Vorteil, daß kein expliziter Speicher mehr benötigt wird. In Tabelle 12.1 sind die drei Rechenarten Präfix, Infix und Postfix für die Berechnung der Gleichung 12.1 dargestellt.
R ges =
R1 * R2 R1 + R2
Gleichung 12.1: Berechnung des Gesamtwiderstands aus einer Parallelschaltung von zwei Widerständen
Präfix
Infix
Postfix
/ *R1R2 +R1R2
(R1*R2)/(R1+R2)
R1R2* R1R2+ /
Die Operatoren stehen vor den Operanden
Die Operatoren stehen zwischen den Operanden
Die Operatoren stehen hinter den Operanden
Tabelle 12.1: Vergleich der drei Notationsarten „Präfix“, „Infix“ und „Postfix“
1. „Last in, first out“: Die Zahl, die als letzte in die Liste geschrieben wurde, wird als erste entnommen.
181
Sandini Bib
In Tabelle 12.2 werden die einzelnen Eingaben in den Stackrechner und in einen normalen Infixrechner einander gegenübergestellt. Für R1 soll der Widerstandswert 200 Ω, für R2 der Widerstandswert 100 Ω angenommen werden. Postfix
Infix
Stackrechner
normaler Taschenrechner
Eingabe von R1
200
Eingabe von R1
200
Eingabe von R2
100
Drücken der Taste ADDITION
+
Drücken der Taste MULTIPLIKATION
*
Eingabe von R2
100
Eingabe von R1
200
Zwischenergebnis in den Speicher
MR
Eingabe von R2
100
Eingabe von R1
200
Drücken der Taste ADDITION
+
Drücken der Taste MULTIPLIKATION
*
Drücken der Taste DIVISION
/
Eingabe von R2
100
Drücken der Taste DIVISION
/
Inhalt des Speichers abfragen
MR
Tabelle 12.2: Berechnung der Gleichung 12.1 mit Postfix- und Infix-Taschenrechner
Wie in Tabelle 12.1 zu sehen ist, wird die Gleichung in der richtigen Reihenfolge eingegeben, nämlich 1. Multiplikation, 2. Addition und 3. Division.
Es wird kein Speicher benötigt, um das Zwischenergebnis zu behalten. Ein weiterer Vorteil dieses Taschenrechnerprogramms ist, daß es ohne Probleme erweitert und den persönlichen Bedürfnissen angepaßt werden kann.
12.2
Planung des Projekts
Zuerst muß geklärt werden, welche Funktionen der Taschenrechner biten soll. Zunächst wird natürlich ein numerischer Tastaturblock für die Eingabe der Zahlen benötigt. 0...9
Darüber hinaus wird jeweils eine Taste benötigt, um Eingaben zu bestätigen und zu löschen. Enter, Del
Des weiteren müssen die vier Grundrechenarten vorhanden sein:
182
!
Sandini Bib
+ – * /
Als zusätzliche Funktionen werden schließlich noch die Winkelfunktionen eingebaut. Ebenso ist eine Funktion zu realisieren, die ermittelt, ob es sich bei der eingegebenen Zahl um eine Primzahl handelt. Sin, Cos, Tan IstPrim Invers
Es sollen immer die letzten vier Werte, die auf dem Stack gespeichert sind, sichtbar sein. Um die Farben einstellen zu können, soll ein Menü auf einem Tabulator verwendet werden.
12.3
Die verwendeten Steuerelemente und ihre Eigenschaften
In Tabelle 12.3 sind alle Steuerelemente und ihre Namen eingetragen. Auf diese Tabelle wird dann im weiteren Verlauf der Programmentwicklung verwiesen, um identische Programme zu erhalten. Steuerelemente
Wert
Labelfelder
lab_Ausgabe(1-3) lab_FarbeAusgabe
Schaltflächen
btn_Ziffer(0-9) btn_Komma btn_Enter btn_Del btn_Clear btn_Plus btn_Minus btn_Mal btn_Geteilt btn_Undo btn_Cosinus btn_Tangens btn_Sinus btn_Invers btn_Pi
" #
$
183
Sandini Bib
Steuerelemente
Wert btn_Istprim btn_SchriftAusgabe btn_Farbe_Ausgabe
CommonDialog
cmd_Einstellungen
Tabelle 12.3: Eigenschaften der Taschenrechner-Steuerelemente
12.4
Programmglobale Definitionen
Die folgenden Einstellungen sollen in dem Visual Basic-Modul Global gemacht werden. Sie dienen zur Definition von Zahlen wie z.B. der Zahl Pi (p) oder anderen Definitionen, die im gesamten Programm bekannt sein sollen. In diesem Modul werden auch die neuen Variablentypen definiert, die dem gesamten Programm zur Verfügung stehen müssen. Option Explicit Type Stack Inhalt() As String Anzahl As Integer End Type Global Global Global Global Global Global Global Global
Const Const Const Const Const Const Const Const
PLUS = 0 MINUS = 1 MAL = 2 GETEILT = 3 SINUS = 4 COSINUS = 5 TANGENS = 6 INVERS = 7
Global Const Komma = "," Global Const PI = 3.141592654 Global Const MAXLONG = 2147483647
184
!
Sandini Bib
12.5
Funktionen im Formular
12.5.1
Formularglobale Definitionen
Option Explicit Dim Liste As Stack Dim Merker As Stack
12.5.2
'Enthält alle eingegebenen Zahlen 'Enthält die Zahlen der letzten Berechnung
Initialisieren der Variablen
Die Initialisierung der Variablen erfolgt beim Programmstart in der Eigenschaft Form_Load. Startet man das Programm, wird diese Funktion abgearbeitet. Da beim Programmstart noch keine Werte auf den Stack geschrieben wurden, ist die Anzahl der eingetragenen Werte 0. Zur Verdeutlichung der Initialisierung der Stackvariablen sollten die Felder, in welchen die Stackwerte gespeichert werden, ebenfalls initialisiert werden. Für die Initialisierung der Farbenauswahl wird die momentane Farbeinstellung des Ausgabefensters dem Label zugewiesen, das die Einstellungen auf dem Registerblatt Optionen darstellt. Private Sub Form_Load() Liste.Anzahl = 0 Erase Liste.Inhalt btn_Undo.Enabled = False lab_FarbeAusgabe.BackColor = lab_Ausgabe(0).BackColor lab_FarbeAusgabe.ForeColor = lab_Ausgabe(0).ForeColor End Sub
12.5.3
Speichern des letzten Zustandes
Um Eingaben oder Berechnungen rückgängig zu machen, muß die Veränderung, die mit einem Rechenschritt oder einer Eingabe gemacht wird, zwischengespeichert werden. Hierzu wird die Funktion Merke_den_Wert benötigt. Sie speichert in einem Feld, das wie die Stackvariable aufgebaut ist, die letzten Werte. Als Parameter benötigt diese Funktion deshalb zum einen den Wert, der gespeichert werden soll, und zum anderen die Nummer des Werts, um den es sich dabei handelt. Die Funktion arbeitet wie folgt:
% %
185
Sandini Bib
Wird ihr ein Wert übergeben, verändert sie die Feldgröße so, daß der neue Wert genau an der letzten Stelle eingetragen wird. Durch diese Methode braucht das Feld nicht initialisiert zu werden, da die Feldgröße auf 1 gesetzt wird, wenn der erste Wert eingetragen ist. Wird dann ein Rechenschritt zwischengespeichert, kann die Schaltfläche UNDO auf verfügbar geschaltet werden. Function Merke_den_Wert(Inhalt As String, Wert As Integer) 'Erweitere das Feld der zu merkenden Einträge und 'speichere den neuen Inhalt ReDim Preserve Merker.Inhalt(Wert) Merker.Inhalt(Wert – 1) = Inhalt Merker.Anzahl = Wert btn_Undo.Enabled = True End Function
12.5.4
Vorbereitung der Berechnung
Um die Berechnung durchzuführen, müssen einige Vorgänge zuvor geprüft werden. Wird eine Berechnung mit einem Wert durchgeführt, z. B. das Invertieren einer Zahl, muß zuerst überprüft werden, ob das Eingabefeld eine Zahl enthält; diese wird dann in die Stackvariable übernommen. Ist im Eingabefeld keine Zahl enthalten, wird die Stackvariable überprüft. Bei Berechnungen mit zwei Zahlen muß dies für beide Zahlen erfolgen usw. Ist diese Überprüfung abgeschlossen, kann die eigentliche Berechnung erfolgen. Dies geschieht dann aber im Programm-Modul Rechnen. Function Rechnen(Operation As Integer) Dim i As Integer Dim Operanden As Integer 'Anzahl der benötigten 'Operanden für die 'Funktion Dim Ergebnis As String 'Das Ergebnis der 'Berechnung 'Wenn sich eine Zahl noch in der Eingabe befindet, 'schiebe sie auf den Stack Call Stack_aktualisieren Select Case Operation Case PLUS, MINUS, MAL, GETEILT Operanden = 2 If Liste.Anzahl >= Operanden Then Ergebnis = Zweier_Tupel((CDbl( _ Liste.Inhalt(Liste.Anzahl – _ 2))), (CDbl(Liste.Inhalt( _ Liste.Anzahl – 1))), Operation)
186
!
Sandini Bib
Else Operanden = 0 End If Case SINUS, COSINUS, TANGENS, INVERS Operanden = 1 If Liste.Anzahl >= Operanden Then Ergebnis = Einer_Tupel((CDbl(Liste.Inhalt _ (Liste.Anzahl – 1))), Operation) Else Operanden = 0 End If End Select 'Lösche alle Operanden aus dem Stack und speichere 'sie zwischen For i = 1 To Operanden Call Merke_den_Wert(Liste.Inhalt( _ Liste.Anzahl – 1), i) Call Stack_Wert_loeschen Call Stack_anzeigen Next i lab_Eingabe.Caption = Ergebnis 'Schreibe das Ergebnis auf den Stack und 'aktualisiere die Anzeige Call Stack_aktualisieren End Function
12.5.5
Eingabe von der Tastatur
Um Eingaben von der Tastatur durchführen zu können, muß eine Funktion entwickelt werden, die in den richtigen Rechenschritt verzweigt. Diese Funktion ruft dann nur noch die Ereignisse der einzelnen Schaltflächen auf, die mit der Maus betätigt werden können. Function Rechner_betätigen(KeyAscii As Integer) Select Case KeyAscii Case Asc(0) To Asc(9) 'Eine Ziffer wird 'eingegeben Call btn_Ziffer_Click(Chr(KeyAscii)) Case Asc("."), Asc(",") If btn_Komma.Enabled = True Then Call btn_Komma_Click End If Case 13 'Die Taste Return Call btn_Enter_Click Case 43 'Das Plus-Zeichen "+" Call btn_Plus_Click
% %
187
Sandini Bib
Case 45 'Das Call btn_Minus_Click Case 42 'Das Call btn_Mal_Click Case 47 'Das Call btn_Geteilt_Click Case Asc("d"), Asc("D") 'Die Call btn_Del_Click Case Asc("l"), Asc("L") 'Die Call btn_Clear_Click Case Asc("u"), Asc("U") 'Die Call btn_Undo_Click Case Asc("c"), Asc("C") 'Den Call btn_Cosinus_Click Case Asc("s"), Asc("S") 'Den Call btn_Sinus_Click Case Asc("t"), Asc("T") 'Den Call btn_Tangens_Click Case Asc("i"), Asc("I") Call btn_Invers_Click End Select End Function
12.5.6
Minus-Zeichen "–" Mal-Zeichen "*" Geteilt-Zeichen "/" Del-Taste Clear-Taste Undo-Taste Cosinus berechnen Sinus berechnen Tangens berechnen
Den Stack aktualisieren
Um die Liste aller Zahlen zu verwalten, die in den Taschenrechner eingegeben wurden, werden noch folgende Funktionen benötigt:
Die Liste nach Berechnung aktualisieren Stack_aktualisieren
Die Liste neu anzeigen Stack_anzeigen
Einen neuen Wert in die Liste eintragen Stack_eintragen
Einen alten Wert aus der Liste entfernen Stack_Wert_loeschen
Function Stack_aktualisieren() 'Wenn keine Eingabe erfolgt, verlasse die Funktion If Len(lab_Eingabe.Caption) < 1 Then tab_Rechner.SetFocus 'Aber vorher das Tab wieder 'aktivieren Exit Function End If 'Wenn das letzte Zeichen ein Komma ist, entferne 'dieses
188
!
Sandini Bib
If Right(lab_Eingabe.Caption, 1) = Komma Then lab_Eingabe.Caption = Left(lab_Eingabe.Caption, _ Len(lab_Eingabe.Caption)–1) End If Call Stack_eintragen(lab_Eingabe.Caption) Call Stack_anzeigen lab_Eingabe.Caption = "" btn_Komma.Enabled = True tab_Rechner.SetFocus End Function Function Dim i For i If
Stack_anzeigen() As Integer = 0 To 3 i < Liste.Anzahl Then lab_Ausgabe(i).Caption = Liste.Inhalt( _ Liste.Anzahl – (i + 1)) Else lab_Ausgabe(i).Caption = "" End If Next i End Function Function Stack_eintragen(Wert As String) 'Das dynamische Feld um 1 vergrößern, ReDim Preserve Liste.Inhalt(Liste.Anzahl + 1) Liste.Inhalt(Liste.Anzahl) = Wert 'Neuer Wert kommt 'hinzu. Liste.Anzahl = Liste.Anzahl + 1 'Erhöhen der 'eingetragenen Werte End Function Function Stack_Wert_loeschen() 'Wenn es mindestens einen Eintrag in die Liste gibt If Liste.Anzahl > 0 Then 'Entferne den letzten Wert aus dem Listenfeld ReDim Preserve Liste.Inhalt(Liste.Anzahl – 1) 'Erniedrige die registrierten Einträge um 1 Liste.Anzahl = Liste.Anzahl – 1 End If End Function
% %
189
Sandini Bib
12.5.7
Programm beenden
Mit der folgenden Funktion wird das Programm beendet, wenn die Schaltfläche ABBRECHEN betätigt wird: Private Sub btn_Abbrechen_Click() End End Sub
12.5.8
Gesamten Stack löschen
Um alle Einträge auf dem Stack zu löschen, muß der Inhalt des Listenfelds gelöscht werden, und alle Werte, die in der Liste eingetragen waren, müssen für die Funktion Widerrufen zwischengespeichert werden. Private Sub btn_Clear_Click() Dim i As Integer For i = 0 To Liste.Anzahl – 1 Call Merke_den_Wert(Liste.Inhalt(Liste.Anzahl – _ (i + 1)), i + 1) Next i Erase Liste.Inhalt Liste.Anzahl = 0 Call Stack_anzeigen lab_Eingabe.Caption = "" tab_Rechner.SetFocus End Sub
12.5.9
Den letzten Wert auf dem Stack löschen
Damit auch der letzte Eintrag auf dem Stack getilgt wird, muß der letzte Wert des Listenfelds gelöscht und in der Zwischenspeicherliste für die Funktion Widerrufen abgelegt werden. Private Sub btn_Del_Click() If Len(lab_Eingabe.Caption) > 0 Then lab_Eingabe.Caption = "" Else If Liste.Anzahl > 0 Then Call Merke_den_Wert(Liste.Inhalt( _ Liste.Anzahl–1), 1) If Liste.Anzahl > 1 Then Call Merke_den_Wert(Liste.Inhalt( _ Liste.Anzahl – 2), 2) End If
190
!
Sandini Bib
End If Call Stack_Wert_loeschen End If Call Stack_anzeigen tab_Rechner.SetFocus End Sub
12.5.10
Bestätigung einer Eingabe
Wird eine erfolgte Eingabe bestätigt, muß geprüft werden, ob diese im eingegebenen Format gültig ist. Wurde etwa als letztes Zeichen ein Komma eingegeben, so soll dieses entfernt werden. Private Sub btn_Enter_Click() If Len(lab_Eingabe.Caption) < 1 And Liste.Anzahl > 0 Then lab_Eingabe.Caption = Liste.Inhalt( _ Liste.Anzahl – 1) End If btn_Undo.Enabled = True If Merker.Anzahl > 0 Then Erase Merker.Inhalt Merker.Anzahl = 0 End If Call Stack_aktualisieren End Sub Private Sub btn_Komma_Click() If Len(lab_Eingabe.Caption) = 0 Then 'Wenn keine 'Ziffer vor dem lab_Eingabe.Caption = 0 'Komma eingegeben 'wurde End If lab_Eingabe.Caption = lab_Eingabe.Caption & Komma btn_Komma.Enabled = False End Sub
12.5.11
Farben definieren
Um einige Farbeinstellungen durchzuführen, werden folgende Funktionen benötigt: Private Sub Btn_Farbe_Ausgabe_Click() Dim i As Integer cmd_Einstellungen.DialogTitle = "Farbe auswählen" cmd_Einstellungen.ShowColor
% %
191
Sandini Bib
lab_FarbeAusgabe.BackColor = cmd_Einstellungen.Color For i = 0 To 3 lab_Ausgabe(i).BackColor = _ lab_FarbeAusgabe.BackColor Next i End Sub Private Sub btn_SchriftAusgabe_Click() Dim i As Integer cmd_Einstellungen.DialogTitle = "Farbe auswählen" cmd_Einstellungen.ShowColor lab_FarbeAusgabe.ForeColor = cmd_Einstellungen.Color For i = 0 To 3 lab_Ausgabe(i).ForeColor = lab_FarbeAusgabe.ForeColor Next i End Sub
12.5.12
Berechnungsfunktionen
Die folgenden Funktionen rufen die in der Aufgabe geforderten Berechnungen auf; sie sind den zugehörigen Schaltflächen hinterlegt. Private Sub btn_Cosinus_Click() Call Rechnen(COSINUS) End Sub Private Sub btn_Mal_Click() Call Rechnen(MAL) End Sub Private Sub btn_Minus_Click() Call Rechnen(MINUS) End Sub Private Sub btn_Sinus_Click() Call Rechnen(SINUS) End Sub Private Sub btn_Tangens_Click() Call Rechnen(TANGENS) End Sub Private Sub btn_Geteilt_Click() Call Rechnen(GETEILT) End Sub
192
!
Sandini Bib
Private Sub btn_Invers_Click() Call Rechnen(INVERS) End Sub Private Sub btn_Istprim_Click() If lab_Eingabe.Caption "" Then 'Wenn eine Zahl 'im Eingabefeld 'steht Call btn_Enter_Click End If If lab_Ausgabe(0).Caption "" Then Call Teste_auf_Prim(lab_Ausgabe(0).Caption) End If End Sub Private Sub btn_Pi_Click() Call btn_Enter_Click lab_Eingabe.Caption = PI Call btn_Enter_Click End Sub Private Sub btn_Plus_Click() Call Rechnen(PLUS) End Sub
12.5.13
Die letzte Aktion widerrufen
Um die letzte Aktion widerrufen zu können, muß die nachfolgende Funktion Undo implementiert werden. Sie schreibt die Werte, die sich in der Zwischenspeicherliste befinden, wieder zurück auf den Stack. Wenn diese Aktion ausgeführt wurde, muß die Schaltfläche, die diese Aktion auslöst, auf nicht verfügbar gesetzt werden, da nur der letzte Schritt widerrufen werden kann. Private Sub btn_Undo_Click() Dim i As Integer Call Stack_Wert_loeschen For i = 1 To Merker.Anzahl Call Stack_eintragen(Merker.Inhalt(Merker.Anzahl – i)) Next i btn_Undo.Enabled = False Call Stack_aktualisieren Call Stack_anzeigen End Sub
% %
193
Sandini Bib
12.5.14
Die Eingabe der Ziffern
Die beiden nachfolgenden Funktionen lesen die Ziffern in das Eingabefenster ein. Die erste liest die Ziffer von dem Tastenfeld, welches mit der Maus gesteuert wird, die zweite Funktion reagiert auf einen Tastendruck der Tastatur. Private Sub btn_Ziffer_Click(Index As Integer) lab_Eingabe.Caption = lab_Eingabe.Caption & Index tab_Rechner.SetFocus End Sub Private Sub tab_Rechner_KeyPress(KeyAscii As Integer) If tab_Rechner.Tab = 0 Then Call Rechner_betätigen(KeyAscii) End If End Sub
12.6
Das Modul für die Berechnungen
In diesem Modul finden die gesamten Berechnungen statt, die mit dem Taschenrechner durchgeführt werden können. Um eine Berechnung durchzuführen, muß jedoch zuerst ermittelt werden, wie viele Operanden benötigt werden.
12.6.1
Funktion zum Überprüfen eines Operanden
Die Funktion für die Überprüfung, ob es sich bei der eingegebenen Zahl um eine Primzahl handelt, liefert keinen Ergebniswert zurück, der eine sinnvolle Weiterverarbeitung erlaubt. Für den Anwender ist in diesem Fall nur wichtig:
Handelt es sich um eine Primzahl?
Wenn es sich um keine Primzahl handelt, welche Zahl ist dann der Teiler?
Die folgende Funktion ermittelt den kleinsten Teiler der eingegebenen Zahl und gibt diesen in einem Meldungsfenster aus, wenn es sich um keine Primzahl handelt. Der eingesetzte Algorithmus, mit dem eine Zahl auf Prim geprüft wird, arbeitet wie folgt: Die Zahl wird durch 2 geteilt. Ist die Division ohne Rest durchführbar, ist 2 ein Teiler dieser Zahl. Ist ein Rest vorhanden, wird die nächste ganze Zahl als Teiler genommen. Dies wird so lange durchgeführt, bis eine Division ohne Rest möglich oder der Teiler größer ist als das Ergebnis der Berechnung „Zahl/Teiler“.
194
!
Sandini Bib
Sub Teste_auf_Prim(Zahl As String) Dim Testzahl As Long Dim Teiler As Integer Dim Rest As Boolean Rest = False 'Wenn die Zahl zu groß ist If Abs(CDbl(Zahl)) > MAXLONG Or CDbl(Zahl) < 0 Then Call MsgBox("Zahl nicht im Definitionsbereich", _ , "Primzahl") Exit Sub End If Testzahl = CLng(Zahl) 'Die zu ermittelnde Zahl muß 'eine Ganzzahl sein If Testzahl = CDbl(Zahl) Then 'Wenn es eine ganze 'Zahl ist, Teiler = 2 'initialisiere den kleinsten 'Teiler While Testzahl / Teiler > Teiler And Rest = False If Testzahl Mod Teiler = 0 Then 'Wenn bei der 'Division kein Rest = True 'Rest bleibt, beende 'die Berechnung Else Teiler = Teiler + 1 'Nehme die nächste 'ganze Zahl als Teiler End If Wend If Rest = False Then Call MsgBox(Zahl & " ist eine Primzahl", , _ "Primzahl") Else Call MsgBox(Zahl & " ist durch " & _ Teiler & " teilbar", , "Primzahl") End If End If End Sub
12.6.2
Berechnungen mit einem Operanden
Um Berechnungen mit nur einem Operanden durchzuführen, wird nachfolgende Funktion benötigt. Sie prüft, um welche Berechnung es sich handelt, führt dann die Berechnung aus und liefert schließlich das Ergebnis an die aufrufende Funktion zurück.
" & $'
195
Sandini Bib
Function Einer_Tupel(Operand As Double, OPERATOR As Integer) As String On Error GoTo Fehler_Einer_Tupel Select Case OPERATOR Case SINUS Einer_Tupel = Sin(Operand) Case COSINUS Einer_Tupel = Cos(Operand) Case TANGENS Einer_Tupel = Tan(Operand) Case INVERS Einer_Tupel = Operand * (–1) End Select Exit Function Fehler_Einer_Tupel: Call Fehlermeldung((Err.Number)) Einer_Tupel = "" Exit Function End Function
12.6.3
Arithmetische Funktionen
Die folgenden mathematischen Funktionen führen die eigentlichen Berechnungen mit zwei Operanden aus. Function Addition(Operand1 As Double, Operand2 As Double) As String Addition = Operand1 + Operand2 End Function Function Multiplikation(Operand1 As Double, Operand2 As Double) As String Multiplikation = Operand1 * Operand2 End Function Function Subtraktion(Operand1 As Double, Operand2 As Double) As String Subtraktion = Operand1 – Operand2 End Function Function Division(Operand1 As Double, Operand2 As Double) As String Division = Operand1 / Operand2 End Function
196
!
Sandini Bib
12.6.4
Berechnungen mit zwei Operanden
Genauso wie im Fall mit einem Operanden wird auch im Falle von zwei Operanden eine Funktion benötigt, um die Berechnungen mit ihnen durchzuführen. Auch sie prüft, um welche Berechnung es sich handelt, führt danach die Berechnung aus und liefert am Ende das Ergebnis an die aufrufende Funktion zurück. Function Zweier_Tupel(Operand1 As Double, Operand2 As Double, OPERATOR As Integer) As String On Error GoTo Fehler_Zweier_Tupel Select Case OPERATOR Case PLUS Zweier_Tupel = Addition(Operand1, Operand2) Case MINUS Zweier_Tupel = Subtraktion(Operand1, Operand2) Case MAL Zweier_Tupel = Multiplikation(Operand1, Operand2) Case GETEILT Zweier_Tupel = Division(Operand1, Operand2) End Select Exit Function Fehler_Zweier_Tupel: Call Fehlermeldung((Err.Number)) Zweier_Tupel = "" Exit Function End Function
12.7
Das Modul zur Fehlerbehandlung
Um Fehler wie z.B. die Division durch 0 im Programm abzufangen, wird eine Funktion benötigt, die die auftretende Fehlermeldung in einem Meldungsfenster ausgibt. Wie das Behandeln von Fehlern und deren Abarbeitung funktioniert, wurde schon in Kapitel 7, „Fehlerbehandlung in Visual Basic“, vorgestellt. Auch auf den Aufruf eines Meldungsfensters und dessen Parameter wird nicht nochmals eingegangen. Sub Fehlermeldung(Nummer As Integer) Dim Meldung As String 'Die auszugebende Meldung Err.Number = Nummer 'Weise den aufgetretenen 'Fehler der Fehleranalyse 'zu 'Erzeugen des Meldungstextes mit den Err–Objektdaten
" & ( %
197
Sandini Bib
Meldung = "Fehler Nr: " & Err.Number & " im _ Programm: " & Err.Source & Chr(13) & _ "Fehlermeldung: " & Error(Err.Number) 'Ausgabe des Fehlers in einem Meldungsfenster Call MsgBox(Meldung, 16, "Fehlermeldung", _ Err.HelpFile, Err.HelpContext) End Sub
198
!
Sandini Bib
13
Weitere Programmiergrundlagen
In diesem Kapitel werden weitere Aktionen behandelt, die mit Visual Basic programmiert werden können. Es wird erklärt, wie Dateien bearbeitet werden oder wie auf der Oberfläche das Ziehen und Fallenlassen („Drag and Drop“) von Objekten programmiert wird. Ebenfalls wird erklärt, wie die Rekursion arbeitet.
13.1
Arbeiten mit Dateien
Für das Arbeiten mit Dateien werden von Visual Basic zahlreiche Funktionen zur Verfügung gestellt, mit denen sich Dateien u.a. erzeugen, öffnen, lesen, schreiben und löschen lassen.
13.1.1
Dateien öffnen
Der Befehl Open Zum Öffnen von Dateien gibt es in Visual Basic den Befehl Open. Mit ihm werden vorhandene Dateien für den Datenzugriff geöffnet. Existiert eine Datei nicht, so kann sie mit diesem Befehl erzeugt werden. Die Funktion ist folgendermaßen definiert: Open Name For Modus [Access access][lock] As [#]Nr [Len=Länge]
199
Sandini Bib
Parameter
Beschreibung
Name
Dieser Parameter stellt den Namen der Datei, die zum Bearbeiten geöffnet werden soll, dar. Der Name kann auch das Laufwerk und den Dateipfad enthalten, in dem sich die Datei befindet. Existiert die Datei nicht, so wird sie erzeugt, wenn sie in einem anderen Modus als Input geöffnet wird. Der Name einer Datei darf unter Windows95 max. 250 Zeichen lang sein (inkl. Laufwerks- und Pfadangaben).
Modus
Der Modus gibt an, für welche Dateizugriffe die Datei geöffnet wird. Append Binary Input Output Random
An die Datei werden Daten angehängt Binärer Dateizugriff Datei nur zum Lesen öffnen Datei nur zum Schreiben öffnen Datei zum Lesen und Schreiben öffnen
access
Ein optionales Paßwort zur Angabe, welche Zugriffe auf die geöffnete Datei erlaubt sind: Read, Write und ReadWrite.
lock
Ein optionaler Parameter zur Angabe, welche Zugriffe von anderen Prozessen erlaubt sind, wenn die Datei geöffnet ist.
Nr
Dieser Parameter ist unbedingt erforderlich: Er gibt den Datenkanal an, über den der Zugriff auf die Datei stattfinden soll. Der Wert dieser Zahl muß im Bereich zwischen 1 und 511 (inkl.) liegen.
Länge
Dieser optionale Parameter muß kleiner als 32768 sein. Mit ihm wird die Länge eines Satzes in Bytes festgelegt, wenn die Datei im Modus Random geöffnet wurde.
Im folgenden sind einige Befehlszeilen als Beispiel zum Öffnen einer Datei aufgeführt: Open "AUTOEXEC.BAT" For Input As #1 Dateiname$ = "AUTOEXEC.BAT" Open Dateiname$ For Random Access Read Shared As #511 Len = 20
Dateiname$ = "AUTOEXEC.BAT" Dateinummer& = 2 Open Dateiname$ For Output Access Write As Dateinummer&
Die Funktion FreeFile Mit der Funktion FreeFile kann der nächste freie Datenkanal zum Öffnen einer Datei ermittelt werden. Durch die Verwendung dieses Befehls ist immer gewährleistet, daß kein Programmfehler durch das Überschreiben eines Datenkanals auftritt, der gerade in Benutzung ist.
200
Sandini Bib
Datenkanal = FreeFile[(Bereich)]
Parameter
Beschreibung
Bereich
Dies ist ein optionaler Parameter, der angibt, in welchem Wertebereich die Nummer des freien Datenkanals liegen soll. Bei 0 wird eine freie Datenkanalnummer im Bereich 1 bis 255 zurückgemeldet, bei 1 im Bereich 256 bis 511. Wird kein Parameter angegeben, so wird er mit 0 voreingestellt.
Datenkanal
Dies ist die Nummer des nächsten freien Datenkanals, über den Dateizugriffe stattfinden können.
Dateinummer& = FreeFile Open "AUTOEXEC.BAT" For Input As Dateinummer&
13.1.2
Lesen und Schreiben in Dateien
Um in geöffneten Dateien Daten lesen oder schreiben zu können, werden von Visual Basic die in Tabelle 13.1 aufgeführten Befehle bereitgestellt. Befehl
Beschreibung
Print #
Schreibt Daten in eine sequentielle Datei. Die Daten sind dabei genauso formatiert wie bei der Ausgabe auf den Bildschirm – es sind keine Steuerzeichen sichtbar.
Write #
Schreibt Daten in eine sequentielle Datei. Die auzugebenden Daten werden aber automatisch wie folgt formatiert: Zeichenketten: "Dies ist ein Text" Boolsche Ausdrücke: #TRUE#, #FALSE#. Datum: #tt-dd-jjjj hh:mm:ss# Fehler: #ERROR Nummer# Null: #NULL#
Put
Schreibt Daten in eine binäre oder in eine Datei, die im Modus Random geöffnet wurde.
Input
Liest Daten aus einer Datei, die mit den Befehlen Print # oder Put geschrieben wurden.
Input #
Liest Daten aus einer sequentiellen Datei, die mit Write # geschrieben wurden.
Line Input #
Liest einen ganzen Datensatz, eine ganze Zeile aus einer Datei, in die Daten mit dem Befehl Print # oder Put geschrieben wurden.
Get
Liest Daten aus einer binären Datei oder einer Datei, die im Modus Random geöffnet wurde.
Tabelle 13.1: Befehle zum Lesen und Schreiben in Dateien
201
Sandini Bib
13.1.3
Dateien schließen
Um das Arbeiten an einer Datei abzuschließen, muß diese wieder geschlossen werden. Dadurch wird auch der Datenkanal, der für die Kommunikation zwischen Datei und Programm geöffnet wurde, wieder frei. Der Befehl für das Schließen einer Datei heißt close. close [[#]Datenkanal_1][, [#]Datenkanal_2]...
Parameter
Beschreibung
Datenkanal_n
Die Datenkanalnummer enthält die Nummer des Datenkanals, der geschlossen werden soll. Wird keine Datenkanalnummer angegeben, werden alle geöffneten Dateien geschlossen.
Wenn Dateien geschlossen werden, die im Modus Append oder Output geöffnet wurden, werden alle Daten, die sich noch im Speicher befinden, zum Speichern an das Betriebssystem weitergegeben.
13.1.4
Umbenennen von Dateien
Dateien oder Verzeichnisse können mit dem Befehl Name umbenannt werden. Es wird keine neue Kopie der Datei oder des Verzeichnisses angelegt, sondern nur der Eigenname der Datei geändert. Name alterName As neuerName
alterName
Hierbei handelt es sich um den Namen der Datei oder des Verzeichnisses, die bzw. das umbenannt werden soll. Diese Zeichenkette darf ein Verzeichnis mit Laufwerksangabe enthalten.
neuerName
Dieser Parameter stellt den neuen Namen der Datei oder des Verzeichnisses dar. Diese Zeichenkette darf ein Verzeichnis mit Laufwerksangabe enthalten, es darf jedoch noch keine Datei mit dem neuen Dateinamen existieren.
Wird eine Datei mit dem Befehl Name umbenannt, muß das Quelllaufwerk mit dem Ziellaufwerk in der Pfadangabe der Datei übereinstimmen. Die Verzeichnisse in der Pfadangabe können jedoch unterschiedlich sein. In diesem Fall wird die Datei umbenannt und in das neue Verzeichnis verschoben. Dateien lassen sich auch nur verschieben, wenn der Name der Quelldatei identisch mit dem der Zieldatei ist, sie sich jedoch in der Pfadangabe unterscheiden. Der Pfad des Ver-
202
Sandini Bib
zeichnisses in das die Datei verschoben werden soll, muß vorhanden sein, sonst tritt ein Fehler auf. 'Umbenennen einer Datei Name "TESTDATEI\TEST.TXT" AS "TESTDATEI\TESTNEU.TXT" 'Verschieben einer Datei in ein anderes Verzeichnis Name "TESTDATEI\TEST.TXT" AS "TEST.TXT" 'Umbenennen und Verschieben einer Datei Name "TESTDATEI\TEST.TXT" AS "TESTNEU.TXT"
13.1.5
Löschen von Dateien
Zum Löschen von Dateien kann unter Visual Basic der Befehl Kill verwendet werden. Kill Dateiname
Parameter
Beschreibung
Dateiname
Die Zeichenkette Dateiname definiert eine oder mehrere Dateien, die gelöscht werden sollen. Es darf auch ein Verzeichnis mit Laufwerksangabe enthalten.
Um mehrere Dateien in einem Verzeichnis löschen zu können, sind auch die Sonderzeichen „?“ für ein beliebiges Zeichen und „*“ für mehrere beliebige Zeichen erlaubt. Wird der Befehl Kill verwendet, um eine geöffnete Datei zu löschen, tritt ein Fehler auf. Es ist auch nicht möglich, Verzeichnisse damit zu löschen. Kill "TESTDATEI\TEST"
13.1.6
Formatieren von Dateien
Um die Ausgabedaten in einer Datei zu positionieren, werden von Visual Basic zwei Befehle zur Verfügung gestellt. Mit dem einen werden Tabulatoren, mit dem anderen Leerzeichen gesetzt. Die Tab-Methode Mit der Methode Tab werden Tabulatoren in einer Datei gesetzt, um z.B. Daten mit unterschiedlicher Länge spaltenweise untereinander schreiben zu können (Abbildung 13.1).
203
Sandini Bib
Abbildung 13.1: Durch Tabulatoren getrennte Daten in einer Datei
In Abbildung 13.2 wurden die Daten nur mit einem Leerzeichen getrennt. Wenn die Datei mit einem Texteditor angeschaut oder ausgedruckt wird, lassen sich die Daten aus Abbildung 13.1 leichter verstehen.
Abbildung 13.2: Durch Leerzeichen getrennte Daten einer Datei
Verwendet wird die Funktion wie folgt: Tab[(Anzahl])
Parameter
Beschreibung
Anzahl
Mit diesem Parameter wird definiert, wieviele Zeichen mit dem Tabulator übersprungen werden sollen. Ist die Anzahl der zu überspringenden Zeichen größer als die Länge einer Zeile, erfolgt die Ausgabe des nächsten Zeichens in einer neuen Zeile.
Der Anfang eines neuen Tabulators ist immer abhängig vom Ende des alten Tabulators, nicht vom Ende des Wortes, welches vor dem Tabulator steht. 'Ausgabe zweier Wörter mit der Standard-Tabulatoreinstellung Print #1, "Hallo"; Tab; "Visual Basic" 'Ausgabe zweier Wörter mit einem Tabulatorsprung von 30 Print #1, "Hallo"; Tab(30); "Visual Basic"
Die SPC-Funktion Mit der Funktion SPC werden Leerzeichen zwischen zwei Ausdrücken geschrieben. Mit dieser Funktion werden die Ausdrücke abhängig von der Position des zuletzt ausgegebenen Zeichens, gesetzt. Spc(Anzahl]
204
Sandini Bib
Parameter
Beschreibung
Anzahl
Mit diesem Parameter wird definiert, wieviele Leerzeichen eingefügt werden sollen, bevor die Ausgabe des nächsten Zeichens erfolgt. Ist die Anzahl der auszugebenden Leerzeichen größer als die Länge einer Zeile, werden die noch nicht geschriebenen Leerzeichen in den folgenden Zeilen ausgegeben.
Der Anfang des neu auszugebenden Zeichens ist immer abhängig vom Ende des zuletzt ausgegebenen Zeichens. 13.1.7
Beispiel zu „Arbeiten mit Dateien“
,
Es soll ein einfaches Programm erstellt werden, mit dem eine Datei erzeugt, umbenannt und wieder gelöscht werden kann. Als Grundlage dient das Programm VORGABE, welches sich auf der beigelegten Diskette befindet. Die Programmoberfläche Für das Beispielprogramm müssen noch folgende Steuerelemente auf das Formular aufgebracht werden: 1. Drei Schaltflächen:
ERZEUGEN
UMBENENNEN
LÖSCHEN
2. Drei Texteingabeelemente:
Name der zu erzeugenden Datei
Neuer Name der umzubenennenden Datei
Name der zu löschenden Datei.
3. Ein Beschriftungsfeld:
AKTUELLES VERZEICHNIS
4. Die Schaltfläche BTN_OK kann entfernt werden.
205
Sandini Bib
Abbildung 13.3: Programmoberfläche für das Beispiel „Arbeiten mit Dateien“
Der Programmcode Beim Starten des Programms müssen alle Schaltflächen, die das Arbeiten mit Dateien steuern, deaktiviert werden, da das zugehörige Texteingabeelement noch keinen Dateinamen enthält, auf den die auszulösende Aktion wirken soll. Ebenfalls soll in dem Beschriftungsfeld ausgegeben werden, in welchem Verzeichnis sich die Datei befindet. Private Sub Form_Load() Lab_Verzeichnis.Caption = CurDir Call txt_Dateiname_Change Call txt_NeuerName_Change Call txt_loeschen_Change End Sub
Nach dem Start können die Dateinamen in die Texteingabeelemente eingegeben werden. Es bleibt dabei jedoch zu berücksichtigen, daß der Quellname von Dateien, die umbenannt werden sollen, im Texteingabeelement für den zu erzeugenden Dateinamen steht. Aus diesem Grund darf die Schaltfläche DATEI UMBENENNEN für den Fall, daß ein Zielname eingegeben wurde, jedoch der Quellname fehlt, nicht verfügbar sein. Private Sub txt_Dateiname_Change() If Len(txt_Dateiname.Text) < 1 Then btn_Erzeugen.Enabled = False Call txt_NeuerName_Change Else btn_Erzeugen.Enabled = True Call txt_NeuerName_Change End If End Sub
206
Sandini Bib
Private Sub txt_NeuerName_Change() If Len(txt_NeuerName.Text) > 0 And _btn_Erzeugen.Enabled = True Then btn_Umbenennen.Enabled = True Else btn_Umbenennen.Enabled = False End If End Sub Private Sub txt_loeschen_Change() If Len(txt_loeschen.Text) < 1 Then btn_Loeschen.Enabled = False Else btn_Loeschen.Enabled = True End If End Sub
Sind die Dateinamen in die Textelemente eingegeben, sind auch die zugehörigen Schaltflächen verfügbar und können die jeweilige Aktion auslösen. Mit der Schaltfläche DATEI ERZEUGEN wird eine Datei mit dem Namen erzeugt, der in dem Texteingabeelement txt_Dateiname eingetragen wurde. Private Sub btn_Erzeugen_Click() Dim Kanal As Integer On Error GoTo Fehler_btn_Erzeugen_Click Kanal = FreeFile Open txt_Dateiname.Text For Output As Kanal Print #Kanal, "Neue Testdatei" Print #Kanal, "Der geöffnete Kanal ist " & Kanal Print #Kanal, Print #Kanal, "Zwei Wörter, getrennt mit Standardtabulator" Print #Kanal, "Hallo"; Tab; "Welt" Print #Kanal, Print #Kanal, "Zwei Wörter, getrennt mit Tabulator 30" Print #Kanal, "Hallo"; Tab(30); "Welt" Print #Kanal, Print #Kanal, "Zwei Wörter, getrennt mit 30 Leerzeichen" Print #Kanal, "Hallo"; Spc(30); "Welt" Close Exit Sub Fehler_btn_Erzeugen_Click: Call MsgBox("Fehler Nr.: " & Err.Number & Chr(13) & _ & & Err.Description, 16, "Fehler") End Sub
207
Sandini Bib
Mit der Schaltfläche DATEI UMBENENNEN wird der Name der Datei, der im Texteingabeelement txt_Dateiname eingetragen ist, geändert in den Namen, der im Texteingabeelement txt_NeuerName eingetragen wurde. Private Sub btn_Umbenennen_Click() On Error GoTo Fehler_btn_Umbenennen_Click Name txt_Dateiname.Text As txt_NeuerName.Text Exit Sub Fehler_btn_Umbenennen_Click: Call MsgBox("Fehler Nr.: " & Err.Number & Chr(13) _ & & Err.Description, 16, "Fehler") End Sub
Mit der Schaltfläche DATEI LÖSCHEN wird die Datei gelöscht, deren Name im Texteingabeelement TXT_LOESCHEN eingetragen wurde. Private Sub btn_Loeschen_Click() On Error GoTo Fehler_btn_Loeschen_Click Kill (txt_loeschen) Exit Sub Fehler_btn_Loeschen_Click: Call MsgBox("Fehler Nr.: " & Err.Number & Chr(13) _ & Err.Description, 16, "Fehler") End Sub
13.1.8
Testen des Programms
Nach dem Programmstart müssen alle Schaltflächen auf „nicht verfügbar“ geschaltet sein. Wird nun zum Erstellen einer Datei der Name „Test“ in das Textelement eingegeben und die Schaltfläche DATEI ERZEUGEN betätigt, wird diese Datei in dem Verzeichnis erzeugt. Diese Datei läßt sich ansehen, indem mit dem Windows Explorer in das Verzeichnis in welchem diese Datei abgelegt ist, gewechselt und auf das Dateisymbol geklickt wird. In dem Fenster, welches nun erscheint, kann zur Darstellung der Datei das Programm „Notepad“ ausgewählt werden.
208
Sandini Bib
Abbildung 13.4: Mit dem Beispielprogramm erzeugte Datei
Als nächstes kann zum Umbenennen der Datei der Dateiname in das Texteingabeelement txt_NeuerName eingegeben werden, der der Datei neu zugewiesen werden soll. Mit dem Betätigen der Schaltfläche DATEI UMBENENNEN wird dieser Vorgang ausgeführt. Wird diese Schaltfläche ein zweites Mal gedrückt, erscheint eine Fehlermeldung, da die Datei, die umbenannt werden soll, nicht mehr existiert. Zum Löschen der Datei kann der Name aus dem Texteingabeelement txt_NeuerName kopiert und in das Textfeld, in welchem die zu löschende Datei enthalten ist, eingetragen werden. Nach dem Auslösen der Schaltfläche DATEI LÖSCHEN wird die Datei vom Datenträger entfernt. Auch hier löst ein zweites Aktivieren der Schaltfläche eine Fehlermeldung aus, da die Datei nicht mehr existiert.
13.1.9
Weitere Funktionen für das Arbeiten mit Dateien
Das Ende einer Datei Um zu prüfen, ob das Ende einer Datei erreicht wurde, gibt es die Funktion EOF („End of File“). Wurde eine Datei im Modus Random oder Input geöffnet, so meldet die EOF-Funktion den Wahrheitswert True zurück, wenn das Ende der Datei erreicht wurde. Ansonsten lautet der zurückgelieferte Wert False. Wahrheitswert = EOF(Dateinummer)
209
Sandini Bib
Parameter
Beschreibung
Dateinummer
Die Dateinummer ist die Datenkanalnummer der Datei, bei der überprüft werden soll, ob das Ende schon erreicht ist.
Das folgende Programmbeispiel gibt die Datei AUTOEXEC.BAT Zeile für Zeile im Beschriftungsfeld aus. Dim Datei As Integer Dim Datensatz As String ... Datei = FreeFile Open "C:\AUTOEXEC.BAT" For Input As Datei While Not EOF(Datei) ... Line Input #Datei, Datensatz lab_Ausgabe.Caption = Datensatz DoEvents Wend ... Close
Eine komplette Datei laden Um eine komplette Datei vom Typ RTF („Rich Text Format“) oder TXT („Text“) in ein Steuerelement zu laden, gibt es die Methode LoadFile. Die Methode ist nur bei Rtf-Steuerelementen verfügbar. Name.LoadFile(Dateiname as String, Dateityp)
Parameter
Beschreibung
Dateiname
Der Dateiname kann einen Laufwerksbuchstaben und ein Verzeichnis zusätzlich zu der zu ladenden Datei enthalten. Der Name der Datei muß eindeutig sein.
Dateityp
Der Dateityp gibt an, um welche Art von Datei es sich handelt, die in das -Steuerelement geladen werden soll. rtfRTF 0 Eine Datei vom Typ RTF rtfText 1 Eine Datei vom Typ Text
Wird eine Datei mit der Methode LoadFile in ein Rtf-Steuerelement geladen, wird der gesamte Inhalt des Steuerelementes überschrieben. Dabei werden auch die Werte der Eigenschaften Text und RTF geändert.
210
Sandini Bib
Um ein Rtf-Steuerelement in der Werkzeugleiste zu erhalten, muß aus dem Visual Basic-Menü PROJEKT die Option KOMPONENTEN ausgewählt werden. Hier werden alle weiteren Steuerelemente, die mit Visual Basic 5.0 mitgeliefert wurden, angezeigt. Diese können durch Selektieren in die Benutzeroberfläche aufgenommen werden. Das Steuerelement, das die Methode LoadFile unterstützt, ist Microsoft Rich TextBox Control 5.0. Die folgende Funktion lädt die Datei AUTOEXEC.BAT beim Starten des Programmes in das Rtf-Steuerelement: Private Sub Form_Load() Call RTF_Datei.LoadFile("C:\AUTOEXEC.BAT", rtfText) End Sub
13.1.10
Funktionen für das Arbeiten mit Verzeichnissen
Für das Arbeiten mit Verzeichnissen stellt Visual Basic folgende Befehle zur Verfügung:
ChDir Pfad
Diese Funktion verhält sich ebenso wie die Funktion CD unter MS-DOS. Mit dieser Funktion wird das neue aktive Verzeichnis festgelegt.
ChDrive Laufwerk
Mit dieser Funktion kann das aktive Laufwerk gewechselt werden. Das neue Laufwerk, auf das gewechselt werden soll, wird im Parameter Laufwerk angegeben. Wird kein Laufwerk angegeben, wird das Laufwerk nicht gewechselt.
CurDir Laufwerk Laufwerk
Diese Funktion liefert als Ergebnis das momentan aktive Verzeichnis auf dem in dem Parameter Laufwerk angegebenen Laufwerk. Wird kein Laufwerk angegeben, so wird das aktuelle Laufwerk gewählt.
MkDir Pfad
Diese Funktion ist vergleichbar mit dem Befehl MD unter MS-DOS. Damit wird das Verzeichnis, das im Parameter Pfad angegeben wurde, erzeugt.
RmDir Pfad
Diese Funktion entfernt das Verzeichnis, das in dem Parameter Path angegeben wurde. Dabei ist zu beachten, daß das zu entfernende Verzeichnis keine weiteren Dateien oder Unterverzeichnisse enthält.
211
Sandini Bib
13.2
Ziehen und Fallenlassen – „Drag and Drop“
Mit Ziehen und Fallenlassen bzw. Drag and Drop können Objekte auf der grafischen Oberfläche kopiert und verschoben werden. Ein alltägliches Beispiel hierfür findet sich im Kopieren von Dateien im DateiManager bzw. Explorer. Dort werden selektierte Dateien durch das Gedrückthalten der linken Maustaste in andere Verzeichnisse verschoben oder kopiert. Die Programmierung von Drag and Drop ist am einfachsten durch „learning by doing“ zu verstehen. 13.2.1
Verschieben von Objekten
Es soll ein Programm entwickelt werden, auf dessen Oberfläche ein Gesicht abgebildet ist. Dieses Gesicht kann mittels Drag and Drop auf die Schaltflächen ABBRECHEN oder ZURÜCKSETZEN verschoben werden. Wird das Gesicht auf die Schaltfläche ZURÜCKSETZEN verschoben, verwandelt es sich in ein lachendes Gesicht. Wird es auf die Schaltfläche ABBRECHEN verschoben, so wird daraus ein ernstes Gesicht. Wurde das Gesicht auf einer der beiden Schaltflächen fallengelassen, wird das aktuelle Gesicht in die Schaltfläche übernommen und das Bild, aus dem das Gesicht entnommen wurde, wird unsichtbar. Durch Betätigen der Schaltfläche ZURÜCKSETZEN wird der Ausgangszustand wiederhergestellt. Die Programmoberfläche
Abbildung 13.5: Oberfläche des Beispiels „Verschieben mit Drag and Drop“
In Abbildung 13.5 ist die Programmoberfläche im Ausgangszustand abgebildet. Wird das Gesicht mit Hilfe von Drag and Drop auf eine der beiden Schaltflächen verschoben, so erscheint das neue Bild auf dieser Schaltfläche, und das Ursprungsbild wird unsichtbar (Abbildung 13.6).
212
Sandini Bib
Abbildung 13.6: Nach dem Verschieben des Gesichts auf eine Schaltfläche
Die Steuerelement-Eigenschaften Damit ein Objekt auf der Oberfläche verschoben werden kann, müssen einige Eigenschaften dieses Objekts daraufhin eingestellt werden. In Tabelle 13.2 sind die Eigenschaften zum Verschieben des Gesichtes auf der Programmoberfläche aufgeführt und beschrieben. Steuerelement
Eigenschaft
Inhalt
Beschreibung
Schaltflächen
(Name)
btn_Ok
Dieses Steuerelement dient der Wiederherstellung des Ausgangzustands, den das Programm nach dem Start hatte.
Style
1 – Grafisch
Wenn der Eigenschaft Picture ein Bild zugeordnet wird, ist dieses auf der Schaltfläche zu sehen.
DragIcon
(Symbol)
(Name)
btn_Abbruch
Damit wird das Programm beendet.
Style
1 – Grafisch
Wenn der Eigenschaft Picture ein Bild zugeordnet wird, ist dieses auf der Schaltfläche zu sehen.
DragIcon
(Symbol)
(Name)
pic_Gesicht
Enthält das Gesicht, das auf der Programmoberfläche verschoben werden soll.
DragMode
1 – Automatisch
Wird das Steuerelement mit der linken Maustaste selektiert, verändert sich der Mauskursor automatisch und stellt das Symbol dar, welches der Eigenschaft DragIcon zugewiesen ist.
DragIcon
(Symbol)
Picture
(Symbol)
Bild-Schaltfläche
Tabelle 13.2: Steuerelement-Eigenschaften zum Thema „Verschieben mit Drag and Drop“
213
Sandini Bib
Das Ereignis DragOver Mit dem Ereignis DragOver wird bestimmt, was innerhalb einer Ziehoperation passieren kann. Es kann z.B. signalisiert werden, ob das aktuell gezogene Steuerelement auf dem Ziel abgelegt werden darf oder nicht, indem sich das Symbol, in das sich der Mauszeiger verwandelt hat, in ein anderes verändert. Private Sub Form_DragOver(Source As Control, X As Single, Y As Single, State As Integer) Private Sub MDIForm_DragOver(Source As Control, X As Single, Y As Single, State As Integer) Private Sub Name_DragOver([Index As Integer,] Source As Control, X As Single, Y As Single, State As Integer)
Parameter
Beschreibung
Index
Wenn das Steuerelement ein Teil eines Feldes von Steuerelementen ist, identifiziert diese Indexnummer das Steuerelement eindeutig
Source
Dieser Parameter enthält das Steuerelement, das gezogen wird, mit all seinen Eigenschaften und Methoden. So kann z.B. der Eindruck erzeugt werden, daß das zu ziehende Steuerelement sein Aussehen verändert.
Source.DragIcon = Name.DragIcon X
Dieser Parameter gibt die aktuelle horizontale Position des Mauszeigers innerhalb des Zielelements an. Die Maßeinheit ist immer die gleiche, wie die des Zielsystems in den Eigenschaften
ScaleWidth, ScaleLeft. Y
Dieser Parameter gibt die aktuelle vertikale Position des Mauszeigers innerhalb des Zielelementes an. Die Maßeinheit ist immer die gleiche, wie die des Zielsystems in den Eigenschaften
ScaleHight, ScaleTop. State
Gibt den Bewegungszustand des gezogenen Steuerelements an, das sich in den folgenden Übergangsphasen befinden kann: 0 = Betreten (Das Quell-Steuerelement wird in den Bereich eines Zieles hineingezogen). 1 = Verlassen (Das Quell-Steuerelement wird aus dem Bereich eines Zieles herausgezogen). 2 = Darüber (Das Quell-Steuerelement wurde von einer Position im Zielbereich zu einer anderen Position verschoben).
Mit dem Parameter State kann die Aktion bestimmt werden, die an den Übergangspunkten stattfinden soll. Hat State den Wert 0 für Betreten, wird das Symbol verändert; hat State den Wert 1, wird es wieder in den Ausgangszustand zurückversetzt.
214
Sandini Bib
Das Ereignis DragDrop Das Ereignis DragDrop tritt beim Fallenlassen eines Objekts nach dem Ziehen auf der Oberfläche ein. Drag and Drop kann z.B. für das Verschieben von Steuerelementen oder das Kopieren von Dateien benutzt werden. Private Sub Form_DragDrop(Source As Control, X As Single, Y As Single) Private Sub MDIForm_DragDrop(Source As Control, X As Single, Y As Single) Private Sub Object_Form_DragDrop(Source As Control, X As Single, Y As Single)
Parameter
Beschreibung
Index
Wenn das Steuerelement ein Teil eines Feldes von Steuerelementen ist, identifiziert diese Indexnummer das Steuerelement eindeutig
Source
Dieser Parameter enthält das Steuerelement, das gezogen wird, mit all seinen Eigenschaften und Methoden. So kann z.B. der Eindruck erzeugt werden, daß das zu ziehende Steuerelement sein Aussehen verändert.
Source.DragIcon = Name.DragIcon X
Dieser Parameter gibt die aktuelle horizontale Position des Mauszeigers innerhalb des Zielelementes an. Die Maßeinheit ist immer die gleiche, wie die des Zielsystems in den Eigenschaften
ScaleWidth, ScaleLeft. Y
Dieser Parameter gibt die aktuelle vertikale Position des Mauszeigers innerhalb des Zielelementes an. Die Maßeinheit ist immer die gleiche, wie die des Zielsystems in den Eigenschaften
ScaleHight, ScaleTop.
Der Programmcode Wenn das Programm zu diesem Zeitpunkt gestartet wird, verändert sich der Mauszeiger bereits in dem Moment, in dem das Gesicht angeklickt und die Maus mit gedrückter Taste über den Bildschirm bewegt wird. Bewegt man den Mauszeiger über ein Steuerelement, so tritt das Ereignis DragOver ein. Damit der Mauszeiger auf den Hintergrund reagiert, über den er bewegt wird, muß in diesem Ereignis des zugehörigen Steuerelements die Zuweisung des neuen Symbols erfolgen. Private Sub btn_Abbruch_DragOver(Source As Control, X As Single, Y As Single, State As Integer) If State = 1 Then Source.DragIcon = Source.Picture
215
Sandini Bib
Else Source.DragIcon = btn_Abbruch.DragIcon End If End Sub Private Sub btn_Ok_DragOver(Source As Control, X As Single, Y As Single, State As Integer) If State = 1 Then Source.DragIcon = Source.Picture Else Source.DragIcon = btn_Ok.DragIcon End If End Sub
In dem Status, in dem sich das Programm jetzt befindet, kann das Gesicht über die Oberfläche bewegt werden und sich auch schon den Schaltflächen anpassen. Bewegt man den Mauszeiger über die Schaltfläche ZURÜCKSETZEN, verändert sich das freundliche Gesicht zu einem lachenden, bewegt man den Mauszeiger über die Schaltfläche ABBRECHEN, wird das Gesicht traurig. Damit die zugehörigen Gesichter auch auf die Steuerelemente fallengelassen werden können, muß das Ereignis DragDrop eintreffen. Mit den folgenden Funktionen wird das Fallenlassen des Gesichts auf das zugehörige Steuerelement programmiert: Private Sub btn_Abbruch_DragDrop(Source As Control, X As Single, Y As Single) btn_Abbruch.Picture = Source.DragIcon pic_Gesicht.Visible = False End Sub Private Sub btn_Ok_DragDrop(Source As Control, X As Single, Y As Single) btn_Ok.Picture = Source.DragIcon pic_Gesicht.Visible = False End Sub
Zum Abschluß das Programms fehlt noch das Zurücksetzen auf die Ausgangsposition, denn wenn ein Gesicht auf der Oberfläche einer Schaltfläche verschoben wurde, ist das Ursprungsbild unsichtbar, und von der Schaltfläche kann das Bild nicht wieder entfernt werden. Private Sub btn_Ok_Click() btn_Ok.Picture = Nothing btn_Abbruch.Picture = Nothing pic_Gesicht.Visible = True End Sub
216
Sandini Bib
13.2.2
Verschieben von Objekten mit anschließender Reaktion
Es soll ein Programm erstellt werden, mit dem Objekte visuell vernichtet werden können. So wird z.B. durch Ziehen des Objekts auf ein Faß dieses verbrannt. Es gibt in diesem Zusammenhang zwei Objektarten: ein Bildfeld- und ein Anzeigenfeld-Steuerelement. Die Bildfelder können in den Mülleimer und in der Fabrik, die Anzeigefelder können nur in der Fabrik entsorgt werden. Wird ein Symbol „entsorgt“, läuft eine kurze Animation ab. In Tabelle 13.3 werden die Symbole, die zur Verfügung stehen, aufgeführt und beschrieben. Bilder
Beschreibung Hier darf kein Objekt abgelegt werden.
TRFFC14.ICO
POINT03.ICO
MAC02.ICO
MAIL01A.ICO MAIL01B.ICO
TRASH02A.ICO TRASCH02B.ICO
MISC01.ICO MISC02.ICO
Das aktuelle Objekt darf hier nicht abgelegt werden, es muß im anderen Objekt zur Entsorgung abgegeben werden. Der Computer ist ein Objekt, das zur Entsorgung zur Verfügung steht. Da Computer nicht verbrannt werden dürfen, wird dieses Symbol in ein Anzeigefeld eingefügt. Der Brief ist das Symbol für brennbare Materialien und darf somit verbrannt werden. Wird das Symbol durch Anklicken selektiert, so wandelt sich der offene Brief in einen geschlossenen um. Da das Verbrennen von Papier bedingt erlaubt ist, wird dieses Symbol in ein Bildfeld-Steuerelement eingefügt. Die Entsorgung durch Verbrennen wird durch den Mülleimer symbolisiert, der beim Fallenlassen eines erlaubten Objekts für kurze Zeit vom linken Symbol in das rechte wechselt. Das Entsorgen von Objekten wird mit dem Rotieren des Symbols dargestellt. Beide Symbole werden abwechselnd eine Zeitlang dargestellt, um eine Rotation zu simmulieren.
Tabelle 13.3: Grafische Elemente für das Beispiel von Drag and Drop mit kleiner Animation
Die Programmoberfläche Als Grundlage für das Beispielprogramm dient das Projekt Vorgabe von der Diskette, das mit den folgenden Steuerelementen erweitert werden muß.
217
Sandini Bib
1. Drei Bildfeld-Steuerelemente:
der Briefumschlag (Datei MAIL01A. ICO)
der Mülleimer (Datei TRASH02A.ICO)
die Entsorgungsanlage (Datei MISCO01.ICO)
2. Ein Anzeigefeld-Steuerelement:
der Computer (Datei MAC02.ICO)
3. Die Schaltfläche BTN_OK wird entfernt.
Die Programmoberfläche für das „Entsorgungsprogramm“ ist in Abbildung 13.7 dargestellt.
Abbildung 13.7: Programmoberfläche für das Entsorgungsprogramm
Der Briefumschlag kann auf beide Entsorgungssymbole, der Computer kann nur auf das untere Entsorgungssymbol gezogen werden. Wird während des Modus Drag das Symbol über die Schaltfläche ABBRECHEN bewegt, verwandelt es sich in ein Stoppzeichen. In Tabelle 13.4 werden die Eigenschaften zum Verschieben des Gesichts auf der Programmoberfläche aufgeführt und beschrieben. Steuerelement
Eigenschaft
Inhalt
Beschreibung
Schaltfläche
(Name)
btn_Abbrechen
Mit dieser Schaltfläche wird das Programm beendet.
DragIcon
BildfeldSteuerelemente
(Name) Picture
218
Wird während der Phase Drag ein Symbol über die Schaltfläche bewegt, ändert es sich in das Stop-Symbol, da es hier nicht abgelegt werden kann. pic_Muelleimer
Dies ist das Entsorgungselement, mit dem die Materialien verbrannt werden.
Sandini Bib
Steuerelement
Eigenschaft
Inhalt
Beschreibung
(Name)
pic_Fabrik
Dies ist das Entsorgungselement, mit dem alle Materialien entsorgt werden können.
pic_Brief
Dies ist das Symbol für Materialien, die verbrannt werden dürfen.
Picture
(Name) Picture
DragIcon
AbbildungsfeldSteuerelemente
Wenn das Symbol in die Entsorgung verschoben wird, verschließt sich der Briefumschlag.
DragMode
1 – Automatisch
Wird das Steuerelement mit der linken Maustaste selektiert, verändert sich der Mauskursor automatisch und stellt das Symbol dar, welches der Eigenschaft DragIcon zugewiesen ist.
(Name)
img_Computer
Das Symbol für die Materialien, die nur in der Fabrik entsorgt werden dürfen.
Picture
Tabelle 13.4: Die Steuerelement-Eigenschaften zum Entsorgungsprogramm
Der Programmcode Als erstes soll die Schaltfläche ABBRECHEN als Verbotszone gekennzeichnet werden, wenn während der Phase Ziehen der Mauszeiger darüberbewegt wird. Für diese Phase werden die beiden Übergangszustände Eintritt (STATUS = 0) und Austritt (STATUS = 1) unterschieden. Private Sub btn_Abbruch_DragOver(Source As Control, X As Single, Y As Single, State As Integer) If State = 0 Then btn_Abbruch.Picture = Source.DragIcon Source.DragIcon = btn_Abbruch.DragIcon Else If State = 1 Then Source.DragIcon = btn_Abbruch.Picture End If End If End Sub
Wird zum jetzigen Programmierzeitpunkt das Programm gestartet und der Mauscursor über die Schaltfläche bewegt, verändert sich dieser in ein Stopp-Signal, da hier „keine Ablage“ signalisiert werden soll. Wird das Symbol dennoch auf der Schaltfläche fallengelassen, ist diesem Objekt beim nächsten Ziehen nicht mehr das Symbol zugeordnet, welches in der Eigenschaft des Steuerelementes als DragIcon definiert wurde, sondern das Symbol Stop.
219
Sandini Bib
Dieses Phänomen ist sehr einfach zu erklären: In dem Ereignis DragOver der Schaltfläche ABBRECHEN wird dem zu ziehenden Steuerelement ein neues Symbol zugeordnet und nicht mehr auf den Ausgangszustand zurückgesetzt. Um nun zu vermeiden, daß nach einem falschen Ablegen eines Steuerelements die Symbole zum Verschieben nicht mehr stimmen, lassen sie sich mit der Funktion LoadPicture zu Beginn der Ziehen-Phase neu initialisieren. Bild = LoadPicture(Dateiname As String)
Parameter
Beschreibung
Dateiname
Der Dateiname kann einen Laufwerksbuchstaben und ein Verzeichnis zusätzlich zu der zu ladenden Grafikdatei enthalten. Der Name der Grafikdatei muß aber eindeutig sein.
Von Visual Basic werden die folgenden Grafikformate erkannt und unterstützt:
Bitmap-Dateien (*.BMP)
Symboldateien (*.ICO)
Dateien im RLE-Format (*.RLE1)
Dateien im Metafile-Format (*.WMF)
Dateien im erweiterten Metafile-Format (*.EMF)
Dateien im GIF-Format (*.GIF)
JPEG-Dateien (*.JPG)
Damit jedesmal, bevor das Drag-Symbol angezeigt wird, das richtige Symbol in der Eigenschaft DragIcon eingetragen ist, wird zuerst in dem Ereignis DragOver des zu verschiebenden Objekts das Symbol geladen. Private Sub img_Computer_DragOver(Source As Control, X As Single, Y As Single, State As Integer) img_Computer.DragIcon = img_Computer.Picture End Sub Private Sub pic_Brief_DragOver(Source As Control, X As Single, Y As Single, State As Integer) pic_Brief.DragIcon = LoadPicture(CurDir("d") & "\BILDER\MAIL01A.ICO") End Sub
1. RLE = Run-length-encoded
220
Sandini Bib
Da auf dem Symbol für die Fabrik alle Materialien entsorgt werden dürfen, wird als nächstes das Ereignis DragDrop der Bildschaltfläche PIC_FABRIK entwickelt. Um ein animiertes Bild zu erzeugen, ist es ausreichend, die beiden Symbole MISC01.ICO und MISC02.ICO abwechselnd für bestimmte Zeit in dem Steuerelement darzustellen. Geladen werden die Symbole ebenfalls mit der Funktion LoadPicture. Private Sub pic_Fabrik_DragDrop(Source As Control, X As Single, Y As Single) Dim i As Integer Dim j As Integer For i = 0 To 10 pic_Fabrik.Picture = LoadPicture(CurDir("d") & "\BILDER\MISC02.ICO") For j = 0 To 300 DoEvents Next j pic_Fabrik.Picture = LoadPicture(CurDir("d") & "\BILDER\MISC01.ICO") For j = 0 To 300 DoEvents Next j Next i End Sub
Da eine einfache Schleife fast keine Zeit benötigt, wenn sie durchlaufen wird, wurde den beiden Schleifen, die nach dem Wechseln des Symbols programmiert wurden, der Befehl DoEvents hinzugefügt. DoEvents ermöglicht die Aktualisierung der Anzeige und verbraucht somit einiges an Systemzeit. Bei dem Mülleimer ist die Animation etwas einfacher. Jedoch muß hier geprüft werden, um welches Objekt es sich bei dem abzulegenden Element handelt. Ist es ein erlaubtes Steuerelement, so wird die Animation gestartet; ist es kein erlaubtes Steuerelement, muß das Ziehen-Symbol in die nach unten zeigende Hand geändert werden. Private Sub pic_Muelleimer_DragDrop(Source As Control, X As Single, Y As Single) Dim i As Integer Dim Pfad As String If TypeOf Source Is PictureBox Then pic_Muelleimer.Picture = LoadPicture(CurDir("d") & "\BILDER\TRASH02B.ICO") For i = 0 To 3000 DoEvents
221
Sandini Bib
Next i pic_Muelleimer.Picture = LoadPicture(CurDir("d") & "\BILDER\TRASH02A.ICO") End If End Sub Private Sub pic_Muelleimer_DragOver(Source As Control, X As Single, Y As Single, State As Integer) If Not (TypeOf Source Is PictureBox) Then If State 1 Then Source.DragIcon = LoadPicture(CurDir("d") & "\BILDER\POINT03.ICO") Else Source.DragIcon = Source.Picture End If End If End Sub
Wird nun der verschlossene Briefumschlag auf den Mülleimer gelegt, sieht es aus, als lodere für kurze Zeit eine Flamme auf und der Brief wurde verbrannt.
13.3
Einführung in die Objektorientierung
Mit der Version 5.0 von Visual Basic wurden die Grundlagen für die Objektorientierung geschaffen. Hierfür stellt Visual Basic das sogenannte Klassenmodul bereit. Bevor ich aber im Detail auf dieses Klassenmodul eingehe, möchte ich auf die Objektorientierung im allgemeinen zu sprechen kommen. Das Hauptmerkmal der objektorientierten gegenüber der herkömmlichen Programmierung ist, daß ihre sogenannten Objekte gekapselt sind. D.h. auf die Daten und Funktionen, die beim Objektorientierten Programmieren als Methoden bezeichnet werden, kann von außen nicht zugegriffen werden, es sei denn, es wurde eine Schnittstelle definiert. Die gesamten Daten und Methoden liegen lokal zu einem Objekt. Soll eine Funktion mit diesem Objekt ausgeführt werden, so muß dazu eine Nachricht an das Objekt gesendet werden. Diese wird dann wiederum von dem Objekt, welches die Nachrichten empfängt, interpretiert. Im Grunde entspricht das Senden einer Nachricht einem Funktionsaufruf. Jedoch besteht noch ein wesentlicher Unterschied zur herkömmlichen Programmierung: Jedes Objekt entscheidet für sich, welche Methode beim Eintreffen einer Nachricht ausgewählt wird. Dies nennt man auch „Überladen von Funktion“. Während also in einer konventionellen Programmiersprache die
222
Sandini Bib
richtige Funktion auf eine Variable angesetzt werden muß, ist es bei der Objektorientierung wichtig, welche Nachricht das Objekt versteht. Der große Vorteil der objektorientierten Technik liegt des weiteren darin, daß jedes Objekt seine definierte Schnittstelle hat und über diese mit dem Objekt kommuniziert werden kann. Wie das Objekt im Kern arbeitet und welche Funktionen dieses Objekt dafür verwendet, ist für den Anwender des Objekts nicht wichtig. Somit kann eine interne Veränderung in diesem Objekt ohne Probleme durchgeführt werden, solange die Schnittstellen nicht verändert werden. Die Klassen sind die Prototypen der Objekte und legen deren Eigenschaften fest. Jedes Objekt muß genau einer Klasse angehören. Diese Objekte bezeichnet man auch als Instanzen. Als nächstes kann noch die Vererbung eingeführt werden, d.h. ähnliche Klassen können miteinander in Beziehung gesetzt werden. Die eine Klasse vererbt ihre Eigenschaften an eine andere. Durch die Klassenbildung ist die Entwicklung großer Softwareprojekte sehr stark vereinfacht worden. Denn zum einen wird es durch die hierarchische Anordnung ähnlicher Klassen möglich, die Gemeinsamkeiten in zentralen Oberklassen zusammenzufassen. Zum anderen ist durch die Vererbung sichergestellt, daß alle von einer gemeinsamen Basisklasse abgeleiteten Klassen automatisch über dieselben Eigenschaften verfügen. Außerdem kann eine Klassenhierarchie ohne Probleme um weitere Klassen ergänzt werden. Wie jedoch auch bei der herkömmlichen Programmierung, ist es wichtig, Struktur in die Datentypen zu bringen, um die Redundanz des Codes zu vermindern. Des weiteren ist eine gute Klassendefinition für den Verbundmechanismus wichtig. Bei einer schlechten Klassendefinition können auch die Vorteile der objektorientierten Programmierung nicht zum Tragen kommen. In diesem Abschnitt werden zunächst einmal einige Begriffe erklärt, die für die objektorientierte Programmierung wichtig sind. Da das Thema „Objektorientierung“ umfassend genug ist, um ein eigenes Buch zu füllen, soll es hier bei einer Darstellung der Grundlagen bleiben.
13.3.1
Was ist ein Objekt?
Unter Objekten versteht man im allgemeinen alle Größen, die durch einen Bezeichner benannt werden. Prinzipiell handelt es sich somit auch bei allen Variablen um Objekte, da sie durch einen Bezeichner benannt werden. Jedoch wird der Begriff eines Objektes in der objektorientierten Programmierung weiter eingeschränkt. Ein Objekt ist
!"#
223
Sandini Bib
hier ein Informationsträger, der einen zeitlich veränderbaren Zustand besitzt. Die Kommunikation mit einem Objekt erfolgt ausschließlich über Nachrichten. Es ist genau definiert, wie das Objekt auf bestimmte Nachrichten eingeht. Eine andere Kommunikationsart gibt es nicht. Mit den Nachrichten wird dann der Zustand des Objekts verändert.
13.3.2
Was sind Eigenschaften?
Mit den Eigenschaften wird dem Anwender eines Objekts suggeriert, daß die Klasse einen eigenen Wert hat, der über eine bestimmte Eigenschaft ausgelesen werden kann. In der Komponente selbst kann dieser Wert eine sehr komplexe Datenstruktur darstellen. Er kann nur über sehr aufwendige Prozesse berechnet oder verändert werden. Bei den Windows-Komponenten sind die Eigenschaften schon zur Entwurfszeit verfügbar. Mit ihnen können z.B. das Aussehen und das Verhalten eines Steuerelementes schon definiert werden, wenn das Programm noch entwickelt wird. Ein weiterer großer Vorteil von Eigenschaften ist, daß mit ihnen die Werte und Formate geprüft werden können, die dem Objekt zugewiesen werden sollen. Sie werden dem Objekt also schon bei seiner Erzeugung zugewiesen. Fehlern, die durch ungültige Eingaben verursacht werden können, wird schon beim Zuweisen eines Wertes vorgebeugt. Auch das Auslesen der Eigenschaften birgt einen Vorteil gegenüber einer öffentlichen Variablen. Der Wert, der aus einer Eigenschaft gelesen wird, besitzt immer Gültigkeit, da er schon beim Zuweisen auf Gültigkeit geprüft wurde. Eigenschaften werden in den Klassen folgendermaßen deklariert: property Get|Let|Set Prozedurname ([Param1 As Vartyp, ..., Paramn As Vartyp]) ... End Property
13.3.3
Was sind Ereignisse?
Ereignisse stellen die Verbindung zwischen einem Steuerelement und dem Programmcode des Entwicklers dar. In den Ereignissen wird definiert, welcher Programmcode ausgeführt werden soll, wenn eine bestimmte Benutzeraktion durchgeführt wird. Bei solchen Aktionen kann es sich z.B. um eine Bewegung mit der Maus, um das Betätigen eine Taste usw. handeln.
224
Sandini Bib
Ereignisse stellen somit die Verbindung zwischen den Komponentenentwicklern und den Komponentenanwendern dar.
13.3.4
Was sind Methoden?
Methoden sind Funktionen, mit denen Aktionen in bezug auf das Objekt ausgeführt werden oder die einen Wert zurückliefern, der nicht als eine Eigenschaft des Objekts angesehen werden kann. Außerdem werden Methoden verwendet, um verschiedene Eigenschaften durch einen einzigen Aufruf zu initialisieren oder abzufragen. Methoden sind wie Ereignisse nur zur Laufzeit verfügbar, da sie keinen eigenen Wert besitzen, sondern einen bestimmten Programmcode ausführen.
13.3.5
Was ist eine Klasse?
In der objektorientierten Programmierung werden mit Hilfe von Klassen eigene Datentypen definiert. Was ist nun eigentlich eine Klasse? Schlägt man im mathematischen Duden nach, findet man die folgende Definition:
Eine Klasse ist eine Kollektion von Objekten mit mindestens einem gemeinsamen Merkmal.
In der Programmierung dient der Begriff „Klasse“ zur schematischen Zusammenfassung von Strukturen und Objekten. Eine Klasse in Visual Basic 6.0 läßt sich durch die folgenden vier Grundregeln relativ gut beschreiben: 1. Eine Klasse ist eine Menge von Datenelementen, mit denen die
Daten der Klasse dargestellt werden. Dabei kann der Typ des Datenelements beliebig sein und die Anzahl null oder mehr betragen. 2. Mit einer Klasse werden Elementfunktionen zusammengefaßt. Sie
stellen die möglichen Operationen dar, die in bezug auf die Klasse ausgeführt werden können. Die Elementfunktionen sind die Schnittstelle der Klasse, und ihre Anzahl beträgt null oder mehr. 3. Die Elemente einer Klasse werden in verschiedene Zugriffsebenen
eingeteilt. Sie können privat, protected oder public sein. Im Normalfall werden die Objekte, die die Klasse darstellen, privat sein, und die Operationen, die in bezug auf die Klasse ausgeführt werden, werden public sein.
!"#
225
Sandini Bib
4. Jede Klasse kann als Typangabe verwendet werden und hat somit
eine Definitionsbezeichnung. Die Definition eines Objekts als eine bestimmte Klasse kann wie überall dort durchgeführt werden, wo auch standardmäßig definierte Typangaben vorkommen dürfen. Hat man z.B. eine Klasse clsKomplex erzeugt, so kann ihre Definition mit folgender Deklaration durchgeführt werden: dim objKomplex As new clsKomplex
Klassen, die einen privaten und einen frei zugänglichen Bereich haben, bezeichnet man als abstrakte Datentypen.
13.3.6
Erzeugen einer Klasse
Eine neue Klasse wird einem Projekt über das Menü PROJEKT|KLASSENMODUL hinzufügen hinzugefügt. In dem Dialog (Abbildung 13.8), der sich darauf hin öffnet, wird das Modul Klassenmodul gewählt.
Abbildung 13.8: Das Fenster Klassenmodul hinzufügen
Im Projektfenster wird nun eine neue Gruppe eingetragen, die Gruppe Klassenmodule. Hierrunter befindet sich die neue Klasse mit Namen Class1. Im Eigenschaftsfenster kann bei der Eigenschaft Name der Klassenname festgelegt werden. Bei der Namensvergabe sollte immer die Buchstabenkennung cls vor den Namen gestellt werden. Der Name der Beispielklasse, der für die weiteren Schritte verwendet wird, ist clsComplex.
226
Sandini Bib
13.3.7
Datenelemente
Die Datenelemente einer Klasse werden wie Variablen deklariert. Im folgenden wird das Beispiel einer Deklaration von Elementen in einer Klasse dargestellt. Option Explicit Public myReal As Integer Public myImaginaer As Integer
Die Datenelemente einer Klasse können von einem beliebigen Typ sein. Auch die Reihenfolge, in der die verschiedenen Datentypen deklariert werden, ist prinzipiell nicht von Bedeutung. Als Datentyp einer Klasse ist natürlich auch eine andere Klasse erlaubt. Im folgenden Beispiel verwendet die Klasse Complex die Klasse Koordinaten, wobei die Klasse erst durch eine Vorausdeklaration definiert werden muß. dim objXY as New clsKoordinaten class Complex
Methoden oder Elementfunktionen Damit mit den Datenelementen der Klasse bestimmte Operationen durchgeführt werden können, müssen bestimmte Nachrichten an das Objekt gesendet werden können. Die Übermittlung solcher Nachrichten an das Objekt übernehmen die Elementfunktionen. Diese Elementfunktionen entsprechen den Funktionen und den Prozeduren in den Basic-Modulen. Public Sub Init(newReal As Integer, newImaginaer As Integer) myReal = newReal myImaginaer = newImaginaer End Sub Public Sub Clear() Real = 0 Imaginaer = 0 End Sub Public Function Real() As Integer Real = myReal End Function Public Function Imaginaer() As Integer Imaginaer = myImaginaer End Function
!"#
227
Sandini Bib
Der Aufbau der Elementfunktions-Deklaration ist identisch mit den Standardfunktionen aus den Basic-Modulen. Eigenschaften Im Abschnitt „Methoden oder Elementfunktionen“ wurden Variablen als public deklariert, um den Zugriff auf die Daten der Klasse zu ermöglichen. Der Nachteil dieser Art von Parameterzugriff ist, daß keine Plausibilitätsprüfung der Daten durchgeführt wird. Deklariert man die beiden Klassenvariablen myReal und myImaginaer als PRIVATE, so hat man jetzt die Möglichkeit, den Zugriff auf diese Daten über zwei Funktionen zu realisieren, mit denen eine Prüfung der Daten möglich wäre. Die Daten sind aber Eigenschaften der Klasse und sollten somit auch nach außen als Eigenschaften dargestellt werden. Aus diesem Grund werden die beiden Eigenschaften myReal und myImaginaer der Klasse Complex eingeführt. Der Programmcode zum Lesen der Eigenschaften myReal und myImaginaer sieht wie folgt aus: Public Property Get Real() As Integer Real = myReal End Property Public Property Get Imaginaer() As Integer Imaginaer = myImaginaer End Property
Die Methoden zum Schreiben der Eigenschaften myReal und myImaginaer verwenden den Befehl Let. Der Programmcode sieht dann wie folgt aus: Public Property Let Real(newReal As Integer) myReal = newReal End Property Public Property Let Imaginaer(newImaginaer As Integer) myImaginaer = newImaginaer End Property
Natürlich sind die Methoden, die von der jeweiligen Eigenschaft aufgerufen werden, nicht sehr komplex. Aus diesem Grund wird noch die Eigenschaft Vektor eingeführt. Diese Eigenschaft berechnet den Wert des Vektors, der sich aus dem Imaginärteil und dem Realteil der komplexen Zahl bildet. Diese Funktion benötigt nur die Leseberechtigung.
228
Sandini Bib
Die Formel zur Berechnung der Vektorlänge (hierbei handelt es sich immer um eine positive Zahl) der komplexen Zahl ist: Vektor =
real 2 + imaginä r 2
Public Property Get Vektor() As Double Vektor = Sqr(myReal ^ 2 + myImaginaer ^ 2) End Property
Testen der Klasse Complex Um die Klasse clsComplex zu testen, wird eine neue Anwendung erzeugt. Dieser Anwendung wird dann die Datei, die den Programmcode der Klasse clsComplex enthält, hinzugefügt. Die Ausgabe des Testwerts wird in ein Beschriftungselement LABVEKTOR geschrieben, und die Eingabewerte werden in den Textelementen txtReal und txtImaginaer eingetragen. Der gesamte Programmcode zum Testen der Klasse clsComplex ist in dem folgenden Listing dargestellt. Option Explicit Private objZahl As New clsComplex Private Sub btnAbbrechen_Click() End End Sub Private Sub Form_Load() labVektor.Caption = objZahl.Vektor End Sub Private Sub txtImaginaer_Change() If Len(txtImaginaer.Text) > 0 Then objZahl.Imaginaer = CInt(txtImaginaer.Text) Else objZahl.Imaginaer = 0 End If labVektor.Caption = objZahl.Vektor End Sub Private Sub txtReal_Change() If Len(txtReal.Text) > 0 Then objZahl.Real = CInt(txtReal.Text) Else
!"#
229
Sandini Bib
objZahl.Real = 0 End If labVektor.Caption = objZahl.Vektor End Sub
Wir haben nun eine Klasse mit Eigenschaften und Methoden. Dennoch hat unsere Klasse ein Problem: Wenn die Eigenschaften der Klasse abgefragt werden, bevor die Klasse initialisiert wird, kann kein sinnvoller Wert zurückgeliefert werden. Um diesen Fehler zu vermeiden, muß eine Initialisierung vorgenommen werden, sobald die Klasse erzeugt wird. Der Konstruktor Bei dem Konstruktor handelt es sich prinzipiell um eine Methode mit einigen Einschränkungen. Der Konstruktor wird immer dann vom Compiler aufgerufen, wenn ein Klassenobjekt definiert oder Speicher für die Klasse reserviert wird. Diese Deklaration des Konstruktors unterliegt denselben Richtlinien wie die allgemeinen Methoden einer Klasse, mit dem Unterschied, daß kein Typ für einen Rückgabewert definiert werden darf: Der Name des Konstruktors ist schon festgelegt. Der Konstruktor ist ein Teil der erzeugten Klasse und wird erzeugt, indem im Kopf des Fensters für den Programmcode der Wert Class aus der linken DropDown-Liste und Initialize aus der rechten DropDown-Liste gewählt werden.
Abbildung 13.9: Erzeugen des Konstruktors
Im folgenden Programmteil ist der Konstruktor in die Klasse clsComplex eingeführt worden. Private Sub Class_Initialize() Real = 0 Imaginaer = 0 End Sub
In dem Programmcode, der dem Konstruktor zugeordnet wird, werden die lokalen Variablen myReal und myImaginär mit dem Wert 0 initialisiert. Bei dem Programmcode der Methode wird, wie schon bei der Deklaration, auf eine Definition des Rückgabewertes verzichtet.
230
Sandini Bib
Wird jetzt der Inhalt der Klasse clsComplex abgefragt, bevor ein Wert initialisiert wird, so liefern alle Eigenschaften dieses Objektes den Wert 0 zurück. Manchmal kommt es jedoch vor, daß die Klasse mit anderen Werten initialisiert werden soll; hierfür muß dann eine andere Methode bereitgestellt werden. Vorsicht Das Gegenstück zum Konstruktor ist der Destruktor. Beim Destruktor handelt es sich ebenfalls um eine Methode. Sie wird immer dann automatisch ausgeführt, wenn die Klasse aus dem Speicher entfernt wird. Dies passiert z.B., wenn die Referenz eines Objekts aus dem Bezugsrahmen fällt.
Der Destruktor
Der Name des Destruktors ist wie der Name des Konstruktors schon festgelegt. Er wird ebenfalls im Kopf des Fensters für den Programmcode ausgewählt.
Abbildung 13.10: Erzeugen des Destruktors
Für den Destruktor werden im allgemeinen keine Berechnungen mehr durchgeführt, da beim Auflösen des Objekts keine Aktionen mehr durchgeführt werden müssen, die den Datenbestand im Objekt selbst aktualisieren. Dies sollte alles vorher geschehen. Ein Destruktor dient einzig und allein dem Aufräumen des Objekts im Programmspeicher.
13.4
Das Arbeiten mit zwei Formularen
In Visual Basic ist es möglich, ein Programm zu entwickeln, welches mit mehreren Formularen arbeiten kann. Das einfachste Beispiel hierfür ist das Verwenden von Meldungsfenstern. Diese Formulare sind jedoch in ihrer Layoutgestaltung sehr begrenzt. Soll nun eine Anwendung mit mehreren Fenstern entwickelt werden, muß zuerst ein neues Fenster in das Projekt aufgenommen werden. Zum einen kann ein neues Formular über den Auswahlpunkt FORMULAR HINZUFÜGEN aus dem Visual Basic-Menü PROJEKT hinzugefügt werden, zum anderen kann mit der rechten Maustaste auf das Projektfenster geklickt werden. Aus dem dort bereitgestellten Kontextmenü werden HINZUFÜGEN und FORMULAR gewählt. In der hierarchischen Projektliste des Projektfensters erscheint nun ein neues Formular. Dieses For-
$%
231
Sandini Bib
mular kann wie alle anderen bearbeitet werden. Es lassen sich Steuerelemente aufbringen und die Eigenschaften verändern.
13.4.1
Laden und Anzeigen eines Formulars
Um aus dem Hauptformular – dem Formular, das beim Programmstart ausgeführt wird – ein weiteres Formular zu laden oder anzuzeigen, gibt es die Methoden Show und Load. Die Anweisung Load Mit der Methode Load werden Formulare in den Speicher geladen, jedoch noch nicht angezeigt. Wurde ein Formular in den Speicher geladen, können Daten an die Steuerelemente gesendet werden, ohne daß diese angezeigt werden. Load Name Parameter
Beschreibung
Name
Bei dem zu ladenden Objekt kann es sich um ein Formular, MDIFormular oder ein Element aus einem Steuerelementenfeld handeln.
Load braucht im allgemeinen nicht verwendet zu werden, denn jeder Verweis auf ein Formular lädt dieses automatisch, es sei denn, das Formular wird in einer der Anweisungen Set oder If...TypeOf verwendet. In manchen Applikationen ist es jedoch für das Programm sinnvoll, daß zuerst alle Formulare des Visual Basic-Projekts geladen und initialisiert und erst bei Bedarf sichtbar gemacht werden. Wird ein Objekt mit der Anweisung Load geladen, so werden zuerst alle Elemente und Eigenschaften neu initialisiert. Anschließend wird die Ereignisprozedur des Formulars Load ausgeführt. Die Methode Show Mit dieser Methode wird ein Formular angezeigt. Wurde das Formular noch nicht mit der Methode Load geladen, wird dies jetzt automatisch von Visual Basic vorgenommen.
232
Sandini Bib
Name.Show Stil, Umgebungsform
Parameter
Beschreibung
Name
Der Parameter Name gibt das MDI-Formular oder das Formular an, das angezeigt werden soll.
Stil
Dies ist ein optionaler Parameter vom Typ Ganzzahl, mit dem das Verhalten des Fensters bestimmt wird. Ist der Wert 0, so ist das Fenster gebunden (modal), d.h., es muß zuerst eine Operation abgeschlossen werden, bevor der Fokus wieder auf ein anderes Fenster gesetzt werden kann. Ist der Wert 1, so ist das Fenster ungebunden, d.h., der Fokus kann zwischen mehreren Fenstern wechseln.
Umgebungsform
Dies ist ein optionaler Parameter, mit dem definiert wird, welche Komponente dieses Unterformular besitzt. In Visual Basic-Standardformularen wird das Schlüsselwort Me verwendet.
Wird in einer Funktion mit dem Befehl Show ein gebundenes Formular angezeigt, so wird der Programmcode, der nach der Anweisung Show folgt, erst ausgeführt, wenn das gebundene Formular nicht mehr angezeigt wird. Beim Anzeigen eines ungebundenen Formulares wird die Funktion weiter abgearbeitet.
Abbildung 13.11: Abarbeitung einer Funktion bei ungebundener Fensteraktivierung
$%
233
Sandini Bib
Abbildung 13.12: Abarbeitung einer Funktion bei gebundener Fensteraktivierung
In Abbildung 13.11 wird dargestellt, wie eine Funktion beim Aufrufen eines nicht abhängigen Fensters als unabhängig abgearbeitet wird. Abbildung 13.12 dagegen zeigt, wie dies bei einem abhängigen Fenster abläuft. Ausblenden eines Fensters Um ein Fenster auszublenden, ohne es zu entladen, gibt es die Funktion Hide. Name.Hide
Parameter
Beschreibung
Name
Bei dem auszublendenden Objekt kann es sich um ein Formular oder um ein MDI-Formular handeln.
Wurde ein Fenster ausgeblendet, können vom Benutzer keine Aktionen mehr in bezug auf das Fenster ausgeführt werden. Das Visual Basic-Programm jedoch kann weiterhin Daten an die Steuerelemente senden bzw. von ihnen abfragen. Auch andere Applikationen, die mit der Anwendung über DDE kommunizieren, können auf das ausgeblendete Formular zugreifen. Wurde Hide aufgerufen, ohne das Fomular zuvor geladen zu haben, lädt die Funktion zwar das Formular, zeigt es aber nicht an. Die Methode Hide ist das Gegenstück zu der Methode Show.
234
Sandini Bib
Entladen eines Fensters Um ein Formular aus dem Speicher zu entfernen, gibt es unter Visual Basic die Anweisung Unload. Mit dieser Anweisung wird das Formular aus dem Speicher entfernt, und alle auf dem Formular gemachten Einstellungen gehen verloren. Unload Name
Parameter
Beschreibung
Name
Bei dem zu entladenden Objekt kann es sich um ein Formular, MDI-Formular oder ein Element aus einem Steuerelementenfeld handeln.
Wenn ein Formular aus dem Hauptspeicher entfernt wird, kann nicht mehr auf die Steuerelemente des Formulars zugegriffen werden. Diese Aktion ist zumeist dann nötig, wenn das Formular komplett neu initialisiert oder wenn der von dem Formular benötigte Hauptspeicher für andere Applikationen oder Module zur Verfügung gestellt werden muß. Wird die Funktion Unload ausgeführt, bevor das Formular mit Load oder Show geladen wird, hat dieser Befehl keinen Einfluß auf das Programm.
13.4.2
Beispiel zum Arbeiten mit zwei Formularen
Das folgende Beispielprogramm soll zum Bearbeiten von INI-Dateien dienen. In ein Fenster – das Editorfenster (Abbildung 13.13) – soll der Inhalt der Datei geladen werden, damit sie bearbeitet werden kann. Zu den Aufgaben eines solchen Editors gehören mindestens die folgenden Punkte:
DATEI
DATEI ÖFFNEN
DATEI SPEICHERN bzw. SPEICHERN UNTER
DATEI DRUCKEN
DATEI SCHLIESSEN
BEENDEN
$%
235
Sandini Bib
Abbildung 13.13: Das Editorfenster
In einem zweiten Fenster – dem Informationsfenster (Abbildung 13.14) –, das von dem Editorfenster abhängig ist, werden wichtige Informationen zur geladenen INI-Datei, wie z.B. die Abschnitt-Überschriften, ausgegeben.
Abbildung 13.14: Das Informationsfenster
Wenn das Informationsfenster von dem Editorfenster aufgerufen wird, kann im Editorfenster weitergearbeitet werden. Um die Steuerung des Zusatzfensters (Informationsfenster) aus dem Hauptfenster (Editorfenster) durchzuführen, muß das Menü des Hauptfensters um folgende Einträge erweitert werden:
236
OPTIONEN
Inhaltsverzeichnis
Aktualisieren
Sandini Bib
Der Menüpunkt AKTUALISIEREN wird benötigt, um die in dem Informationsfenster ausgegebenen Daten nach einer größeren Änderung, z.B. nach Entfernen eines Abschnitts aus der INI-Datei, wieder zu aktualisieren. Wird in dem Informationsfenster ein Abschnitt ausgewählt, so wird auch im Editor dieser Abschnitt gesucht und dargestellt. Das RTF-Steuerelement RichTextBox
Abbildung 13.15: Das RTF-Steuerelement „RichTextBox“
Im Abschnitt „Eine komplette Datei laden“ wurde schon einmal kurz auf das Textsteuerelement Microsoft Rich TextBox Control 5.0 eingegangen. In diesem Abschnitt wird es noch einmal verwendet, jedoch soll hier tiefer auf die Möglichkeiten, die dieses Steuerelement bietet, eingegangen werden. Mit Microsoft Rich TextBox Control 5.0 läßt sich der Text einer Datei nicht nur darstellen, sondern er kann in diesem Steuerelement sogar mit den folgenden Eigenschaften formatiert werden: SelBold
Schrift im markierten Bereich fett formatieren.
SelItalic
Schrift im markierten Bereich kursiv formatieren.
SelStrikethru
Schrift im markierten Bereich durchstreichen.
SelUnderline
Schrift im markierten Bereich unterstreichen.
SelFontName
Schriftart im markierten Bereich festlegen.
SelFontSize
Schriftgröße im markierten Bereich festlegen.
SelHangingIndent
Linken Einzug des Textes festlegen.
SelIndent
Rechten Textabstand festlegen.
SelRightIndent
Abstand für den hängenden Einzug festlegen.
SelCharOffset
Einen markierten Text hoch oder tief stellen.
Das RTF-Steuerelement unterstützt die Zwischenablage und auch die OLE-Einbettung. Es können somit auch über OLE eingebettete WinWord-Dateien in ein Dokument eingebunden werden, welches mit dem RTF-Steuerelement erstellt wurde.
$%
237
Sandini Bib
Um den Inhalt eines RTF-Text-Steuerelements zu drucken, sollte die Methode SelPrint verwendet werden. Das Fortschrittsleisten-Steuerelement ProgressBar
Abbildung 13.16: „ProgressBar“
Mit ProgressBar läßt sich der Fortschritt einer länger andauernden Operation anzeigen. Zuerst wird der Bereich definiert, der die gesamte Operation abdeckt, danach kann der Fortschritt aktualisiert werden, indem der Eigenschaft Value der jeweilige Fortschrittswert zugewiesen wird. Die Anzahl der rechteckigen Flächen, die den Fortschritt durch Ausfüllen des Steuerelements simulieren, läßt sich indirekt über die Größe des Steuerelements beeinflussen. Je breiter und höher das Steuerelement ist, um so mehr und um so höhere rechteckige Flächen gibt es. Es sollte bei der Verwendung des Steuerelements darauf geachtet werden, daß die Anzahl der dargestellten rechteckigen Flächen in einem guten Verhältnis zur zu überwachenden Operation steht. So ist es z.B. nicht sinnvoll, einen Prozeß mit 200 Schritten in einem Fortschrittsbalken mit zwei Flächen abzubilden. Der eigentliche Fortschritt ist dann nicht zu erkennen. Die Steuerelemente des Editorfensters Für die Menüleiste des Editorfensters muß folgendes Menü mit dem Menüeditor abgebildet werden: 1. DATEI
DATEI ÖFFNEN
men_dat_oeffnen
DATEI SPEICHERN
men_dat_speichern
DATEI SPEICHERN UNTER
men_dat_unter
DATEI DRUCKEN
men_dat_drucken
DATEI SCHLIESSEN
men_dat_schliessen
BEENDEN
men_dat_ende
2. OPTIONEN
238
men_Datei
men_optionen
INHALTSVERZEICHNIS
men_opt_Inhalt
AKTUALISIEREN
men_opt_Aktual
Sandini Bib
Steuerelement
Eigenschaft
Inhalt
Beschreibung
RTF-Steuerelement (RichTextBox)
(Name)
RTF_Editor
Dies ist das Steuerelement, in dem der Inhalt der INI-Datei angezeigt und bearbeitet wird.
ScrollBars
3 – rtfBoth
Wenn der Inhalt der Datei über die Grenzen des Steuerelements hinausgeht, werden die Bildlaufleisten eingeschaltet.
(Name)
cmd_Editor
Dieses Steuerelement wird für die Dialoge zum öffnen, Speichern und Drucken der INI-Datei benötigt.
Standarddialog-Steuerelement
Tabelle 13.5: Die Steuerelemente des Editorfensters
Die Steuerelemente des Informationsfensters Steuerelement
Eigenschaft
Inhalt
Beschreibung
Listenfeld Steuerelement
(Name)
lst_Editor
Dieses Steuerelement zeigt alle in der INI-Datei enthaltenen Abschnittüberschriften.
ScrollBars
3 – rtfBoth
Wenn der Inhalt der Datei über die Grenzen des Steuerelements hinausgeht, werden die Bildlaufleisten eingeschaltet.
(Name)
lab_Kapitel
Dieses Steuerelement enthält die Abschnittsüberschrift, die im Listenfeld selektiert ist. Hier werden auch die Abschnittsüberschriften dargestellt, die für das Listenfeld zu lang sind.
BorderStyle
1 – Fest Einfach
Dadurch wirkt das Steuerelement wie in die Oberfläche eingelassen.
(Name)
lab_AktZeilen
Hier wird ausgegeben, wieviele Zeilen zum aktuellen Abschnitt gehören.
BorderStyle
1 – Fest Einfach
Dadurch wirkt das Steuerelement wie in die Oberfläche eingelassen.
(Name)
Lab_Zeilen
Hier wird angegeben, wieviele Zeilen die INIDatei enthält.
BorderStyle
1 – Fest Einfach
Dadurch wirkt das Steuerelement wie in die Oberfläche eingelassen.
(Name)
lab_Ueberschr
Hiermit wird angegeben, wieviele Überschriften die INI-Datei enthält.
BorderStyle
1 – Fest Einfach
Dadurch wirkt das Steuerelement wie in die Oberfläche eingelassen.
(Name)
lab_besch_Zeilen
Dies ist das Beschriftungselement für den Text Zeilen gesamt:
lab_besch_ueber
Dies ist das Beschriftungselement für den Text Überschriften:
! " #
Beschriftungselemente
Tabelle 13.6: Die Steuerelemente des Informationsfensters
$%
239
Sandini Bib
13.4.3
Die Programmentwicklung
In diesem Abschnitt wird nun der Programmcode für die gewünschte Applikation entwickelt, wobei zu beachten ist, daß die Funktion Kapitel_suchen erst gegen Ende entwickelt wird. Dabei bleibt immer nur zu berücksichtigen, daß bei einem Programmtest die jeweilige Programmzeile auskommentiert werden muß.Alternativ kann die folgende Dummy-Funktion eingebaut werden, die dann nachträglich erweitert wird: Sub Kapitel_suchen() End Sub
Beenden des Programms Eine der Funktionen, die dem Anwender als erstes zur Verfügung stehen sollten, ist die zur Beendigung des Programms über das Menü. Hierzu dient die folgende Funktion: Private Sub men_dat_ende_Click() End End Sub
Geöffnete Datei schließen Mit dieser Funktion werden die Variablen, die alle Daten der geöffneten Datei enthalten, zurück gesetzt. Sub Datei_Schliessen() frm_Editor.Caption = frm_Editor.Tag Geoeffnete_Datei = "" RTF_Editor.Text = "" Call Kapitel_suchen End Sub
Das Öffnen der zu bearbeitenden Datei Als erstes soll die Funktion zum Laden der INI-Datei entwickelt werden, um als Grundlage für weitere Programmierarbeiten zu dienen. Geladen wird die Datei über den Menüpunkt DATEI | DATEI ÖFFNEN. Danach soll ein Dialog erscheinen, in dem die zu öffnende Datei ausgewählt werden kann. Damit deren Name auch anderen Funktionen zur Laufzeit zur Verfügung steht, wird eine globale Variable Geoeffnete_Datei eingeführt.
240
Sandini Bib
Private Sub men_Dat_oeffnen_Click() cmd_Editor.DialogTitle = "Datei öffnen" cmd_Editor.filename = "*.ini" cmd_Editor.ShowOpen On Error GoTo Fehler_men_dat_oeffnen_Click Geoeffnete_Datei = cmd_Editor.filename RTF_Editor.LoadFile (cmd_Editor.filename) Call FensterTitel(cmd_Editor.filename) Call Kapitel_suchen Exit Sub Fehler_men_dat_oeffnen_Click: Call Datei_Schliessen Exit Sub End Sub
Schließen einer Datei Nachdem eine Datei geöffnet wurde, muß es natürlich auch die Möglichkeit geben, diese wieder zu schließen, ohne das Programm zu verlassen. Private Sub men_dat_schliessen_Click() Call Datei_Schliessen End Sub
Speichern einer Datei Wurden an einer Datei Änderungen durchgeführt, die auch erhalten bleiben sollen, muß die Datei unter demselben Namen, unter dem sie geöffnet wurde, wieder gespeichert werden können. Für diese Aktion gibt es den Menüpunkt DATEI SPEICHERN. Private Sub men_dat_speichern_Click() If Len(Geoeffnete_Datei) > 0 Then 'Wenn ein Dateiname 'existiert RTF_Editor.SaveFile Geoeffnete_Datei, 1 End If End Sub
Um die vorgenommenen Änderungen in einer anderen Datei zu speichern – damit z.B. eine Sicherheitskopie von der zu ändernden Datei angelegt wird –, stellt das Programm die Option SPEICHERN UNTER zur Verfügung. Wird dieser Menüpunkt gewählt, so erscheint ebenfalls ein Dialog, mit dem das Verzeichnis gewechselt und ein neuer Dateiname vergeben werden kann.
$%
241
Sandini Bib
Private Sub men_Dat_unter_Click() Dim Datei As String cmd_Editor.DialogTitle = "Datei öffnen" cmd_Editor.filename = "*.ini" cmd_Editor.ShowSave Datei = cmd_Editor.filename If Len(trunc(Datei)) > 0 Then RTF_Editor.SaveFile Datei, 1 Call FensterTitel(cmd_Editor.filename) End If End Sub
Die aktive Datei drucken Um die aktive Datei an den Drucker zu senden, wird die Methode SelPrint des Rtf-Textelementes verwendet. Zuerst wird jedoch der Drukker über das Druckmenü des Standardsteuerelements cmd_Editor ausgewählt. Dabei wird beim Aufrufen des Druckmenüs berücksichtigt, ob nur ein Teil der Datei markiert wurde, also nicht die ganze Datei gedruckt werden soll, oder ob nichts markiert wurde, also die gesamte Datei gedruckt werden soll. Private Sub menDat_drucken_Click() If Len(RTF_Editor) > 0 Then cmd_Editor.Flags = cdlPDReturnDC + cdlPDNoPageNums If RTF_Editor.SelLength = 0 Then cmd_Editor.Flags = cmd_Editor.Flags + cdlPDAllPages Else cmd_Editor.Flags = cmd_Editor.Flags + cdlPDSelection End If cmd_Editor.ShowPrinter DoEvents Printer.Print "" RTF_Editor.SelPrint cmd_Editor.hDC End If End Sub
Das Fenster für die Inhaltsangaben aktivieren Um das Fenster für die Inhaltsangaben zu aktivieren, muß der folgende Programmcode in das Click-Ereignis des Menübefehls OPTIONEN | INHALTSVERZEICHNIS aufgenommen werden. Wurde das Formular zur Ausgabe der Dateiinformationen noch nicht geöffnet, so lädt die Methode Show das Fenster in den Hauptspeicher und zeigt dieses an. Zudem wird ein Haken zur Bestätigung vor das Menü INHALTSVERZEICHNIS gesetzt. Ist das Fenster geöffnet, wird duch Auswählen des
242
Sandini Bib
Menüs das Formular ausgeblendet und das Bestätigungszeichen vor dem Menü entfernt. Private Sub men_opt_Inhalt_Click() If men_opt_Inhalt.Checked = True Then men_opt_Inhalt.Checked = False men_opt_Aktual.Enabled = False frm_Inhalt.Hide Else men_opt_Inhalt.Checked = True men_opt_Aktual.Enabled = True frm_Inhalt.Show 0, Me Call Kapitel_suchen End If End Sub
Ermitteln der Informationen zu der geöffneten Datei Mit der zu Anfang dieses Abschnitts erwähnten Funktion Kapitel_suchen werden nun die benötigten Informationen, die in dem Formular frm_Inhalt angezeigt werden, ermittelt. Zuerst wird geprüft, ob die geladene Datei Informationen enthält. Danach wird zu jedem Abschnitt die Anzahl der zugehörigen Zeilen ermittelt. Ein Abschnitt in einer ini-Datei wird immer durch ein Wort eingeleitet, das in den eckigen Klammern „[„ und „]“ steht. Dieses gefundene Wort wird dann in das Listenelement auf dem Formular eingetragen. Da die Anzahl der Zeichen in der Datei bekannt ist – die Länge des Textes, der in der Eigenschaft Text vom Steuerelement RTF-Editor eingetragen wird –, kann der aktuelle Fortschritt der Operation in dem Fortschrittssteuerelement angezeigt werden. Sub Kapitel_suchen() Dim i As Integer Dim Kapitel As Boolean Dim Maximum As Integer Dim Titel As String Dim Zeilen As Integer Dim Zeichen As String Titel = "" Zeilen = 0 frm_Inhalt.Enabled = False frm_Editor.Enabled = False 'Alle Ausgabefelder neu initialisieren frm_Inhalt.lab_Zeilen.Caption = 0
$%
243
Sandini Bib
frm_Inhalt.lab_ueberschr.Caption = 0 frm_Inhalt.lab_Kapitel.Caption = "" frm_Inhalt.lab_AktZeilen.Caption = 0 frm_Inhalt.lst_Editor.Clear frm_Inhalt.pgb_Editor.Min = 0 Maximum = Len(RTF_Editor.Text) 'Wenn die INI-Datei keine Zeichen enthält oder die Angaben 'dazu nicht ermittelt werden sollen If Maximum < 1 Or men_opt_Inhalt.Checked = False Then frm_Inhalt.Enabled = True frm_Editor.Enabled = True Exit Sub End If 'Durchsuche den kompletten Inhalt frm_Inhalt.pgb_Editor.Max = Maximum For i = 1 To Maximum Zeichen = Mid(RTF_Editor.Text, i, 1) If Zeichen = "[" Then If Len(Titel) > 0 Then frm_Inhalt.lst_Editor.AddItem Titel & Chr(9) & _ Zeilen – 1 frm_Inhalt.lab_ueberschr.Caption = _ frm_Inhalt.lab_ueberschr.Caption + 1 End If Kapitel = True Titel = "" Zeilen = 0 Else If Zeichen = "]" Then Kapitel = False Else If Kapitel = True Then Titel = Titel & Zeichen Else If Zeichen = Chr(13) Then Zeilen = Zeilen + 1 frm_Inhalt.Lab_Zeilen.Caption = _ frm_Inhalt.Lab_Zeilen.Caption + 1 End If End If End If End If If i Mod 10 = 0 Then DoEvents frm_Inhalt.pgb_Editor.Value = i Next i frm_Inhalt.lst_Editor.AddItem Titel & Chr(9) & Zeilen
244
Sandini Bib
frm_Inhalt.Enabled = True frm_Editor.Enabled = True End Sub
Aktualisieren des Datei-Informationsfensters Um das Datei-Informationsfenster zu aktualisieren, muß nun lediglich die Funktion Kapitel_suchen aus dem Ereignis Click des Menüs aufgerufen werden. Private Sub men_opt_Aktual_Click() Call Kapitel_suchen End Sub
Diese Option ist jedoch nur verfügbar, wenn das Informationsfenster aktiv ist. Suchen des im Listenelement selektierten Abschnitts Um den aktuellen Abschnitt, der im Listenfeld lst_Editor selektiert wurde, zu finden, wird die Methode Find des Rtf-Textelements verwendet. Mit ihr springt das Programm direkt an die Kapitelüberschrift und markiert diese als aktiv. Des weiteren wird in den Beschriftungselementen nochmals die gesamte Abschnitt-Überschrift mit der Anzahl von Zeilen ausgegeben, die zu diesem Steuerelement gehören. Private Sub lst_Editor_Click() Dim i As Integer Dim Ergebnis As Long i = 1 lab_Kapitel.Caption = "" While Mid(lst_Editor.Text, i, 1) Chr(9) lab_Kapitel.Caption = lab_Kapitel.Caption & Mid(lst_Editor.Text, i, 1) i = i + 1 Wend Ergebnis = frm_Editor.RTF_Editor.Find("[" & lab_Kapitel.Caption & "]", 0, Len(frm_Editor.RTF_Editor.Text)) frm_Editor.SetFocus lab_AktZeilen.Caption = Right(lst_Editor.Text, Len(lst_Editor.Text) – i) End Sub
$%
245
Sandini Bib
Schließen des Informationsfensters Wenn das Informationsfenster nicht über das Editorfenstermenü OPTIONEN | INHALTSVERZEICHNIS geschlossen wird, muß der Bestätigungshaken vor diesem Menüeintrag trotzdem entfernt werden. Diese Aktion wird in dem Ereignis Form_Unload des Inhaltsverzeichnisfensters ausgeführt. Private Sub Form_Unload(Cancel As Integer) frm_Editor.men_opt_Inhalt.Checked = False End Sub
Rekursive Programmierung
13.5
Bei der Rekursion handelt es sich um eine Programmiertechnik, bei der sich eine Funktion immer wieder selbst aufruft, bis ein bestimmtes Abbruchkriterium erfüllt ist. Trifft das Abbruchkriterium nicht ein, wird die Funktion so oft aufgerufen, bis der Hauptspeicher gefüllt ist und die Fehlermeldung „Nicht genügend Stapelspeicher“ erscheint. Im folgenden Abschnitt wird die Arbeitsweise von rekursiven Funktionen anhand von Beispielen erklärt.
Einfache Rekursion
13.5.1
Eine einfache rekursive Funktion enthält nur einen einzigen Aufruf ihrer selbst.
X1
X2 0
X3 1
... 2
Xn n-1
Abbildung 13.17: Eine Liste mit n Zahlen
Um die Zahlen aus Abbildung 13.17 zu addieren, gibt es zwei Möglichkeiten. Die erste Möglichkeit besteht darin, eine Schleife zu programmieren, die über einen Index jedes Feld der Liste ausliest und alle Werte miteinander addiert. Der folgende Beispiel-Programmcode berechnet nach dieser Methode die Summe von n Zahlen. Function Addiere(Liste As Variant) As Integer Dim i As Integer Dim Ergebnis As Variant Ergebnis = 0 For i = 0 To UBound(Liste) Ergebnis = Ergebnis + Liste(i)
246
Sandini Bib
Next i Addiere = Ergebnis End Function
Die zweite Möglichkeit ist die Summenbildung über eine rekursive Funktion, die eine Liste – beginnend mit dem ersten Element – bis zum Ende durchläuft und alle Werte miteinander addiert, bis das letzte Listenelement gefunden wurde. Folgender Programmcode berechnet die Summe aller Zellen des Feldes rekursiv: Function Addiere(Liste As Variant, Index As Integer) As Integer Addiere = 0 If Index 1 Then Fakultaet = Fakultaet(Eingabe – 1) * Eingabe Else Fakultaet = 1 End If End Function
Wird im Texteingabefeld eine Zeichenkette eingegeben, die nicht von der Funktion Fakultät verarbeitet werden kann, so sollte eine Fehlermeldung auf dem Bildschirm ausgegeben werden. Private Sub btn_Ok_Click() Dim Meldung As String On Error GoTo Fehler_btn_Ok_Click lab_Ausgabe.Caption = Fakultaet(txt_Eingabe.Text) Exit Sub Fehler_btn_Ok_Click: Meldung = "Fehler Nr.:" & Err.Number & " im Program " & _ Err.Source & " aufgetreten" & Chr(10) & Chr(13) & _ "Fehlermeldung: " & Error(Err.Number) Call MsgBox(Meldung, 16, "Fehlermeldung", Err.HelpFile, _ Err.HelpContext) End Sub
Tritt in der Funktion BTN_OK_CLICK() ein Fehler auf, verzweigt das Programm in die Fehlerbehandlungsroutine. Dies ist bei der Eingabe einer nicht erlaubten Zeichenkette der Fall oder dann, wenn die Fakultät größer ist als die größte darstellbare Zahl von Visual Basic.
13.5.2
Mehrfache Rekursion
Die mehrfache Rekursion ist schwieriger zu verstehen als die einfache. Jedoch lassen sich einige Aufgaben sehr viel einfacher mit dieser Programmiertechnik beschreiben. Zur Verdeutlichung soll eine Funktion geschrieben werden, die die Fibonacci-Zahl zu einem Eingabewert berechnet. Die Zahl berechnet sich wie folgt:
248
Sandini Bib
Fibonacci(n) = Fibonacci(n–1) + Fibonacci(n–2) wobei gilt: Fibonacci(1) = 1 Fibonacci(2) = 1 Betrachtet man Fibonacci als Reihe, so erhält man folgende Zahlenfolge (bis 15): Index
1
2
3
4
5
6
7
8
9
1 0
1 1
1 2
1 3
1 4
1 5
Fibonacci
1
1
2
3
5
8
1 3
2 1
3 4
5 5
8 9
1 4 4
2 3 3
3 7 7
6 1 0
Tabelle 13.7: Fibonacci-Reihe bis 15
Um nun die Rekursion darzustellen, die nötig ist, um eine FibonacciZahl zu berechnen, bietet sich ein Baum für die Darstellung des rekursiven Abstiegs an (Abbildung 13.18). 13 7 8
5
3 2 1
1
3
1
3
5
2
4
1
2
5
6
1
1
2
3
1
2
1
1
3
1
3
4
1
2
2
2
1
1
1
2
4
1
3
5
2
1
1
3
1
2
2
2
Abbildung 13.18: Darstellung des rekursiven Abstiegs in einem Baum
In Abbildung 13.18 ist zu erkennen, daß sich jede Fibonacci-Zahl aus den beiden vorhergehenden Fibonacci-Zahlen errechnet. In dem folgenden Listing wird die Fibonacci-Zahl mit einer Schleife berechnet. Function Fibonacci(Eingabe Dim Ergebnis As Double Dim Merker As Double Dim Merker2 As Double Dim i As Integer
As Integer) As Double 'Aktuelle Fibonacci-Zahl 'Speichert letzte Fibonacci-Zahl 'Speichert vorletzte Fibonacci-Zahl
&#'
249
Sandini Bib
Ergebnis = 1 Merker = 1 For i = 2 To Eingabe Merker2 = Merker Merker = Ergebnis
'Initialisieren der Fibonacci-Zahlen 'von 1 und 2 – 1 'Zwischenspeichern der letzten Fibonacci-Zahl 'Zwischenspeichern der aktuellen Fibonacci-Zahl
Ergebnis = Merker2 + Ergebnis 'Berechnen der neuen 'Fibonacci-Zahl Next i Fibonacci = Ergebnis End Function
Diese Funktion läßt sich nun sehr stark durch Verwendung der mehrfachen Rekursion vereinfachen. Die Funktion zur Berechnung der Fibonacci-Zahl wird solange aufgerufen, bis der Initialwert 1 gefunden wurde, die Zahl also definiert ist und nicht berechnet werden muß. Dieser beschriebene Ablauf ist in der folgenden Funktion programmiert: Function Fibonacci(Eingabe As Integer) As Double If Eingabe < 3 Then Fibonacci = 1 Else Fibonacci = Fibonacci(Eingabe – 1) + Fibonacci(Eingabe – 2) End If End Function
Der Programmcode dieser Funktion ist um einiges kürzer und besser zu verstehen als der zuerst entwickelte. Jedoch gibt es auch einen Nachteil: Die Programmlaufzeit erhöht sich sehr stark. Zum Vergleich kann beiden Funktionen die Aufgabe gegeben werden, Fibonacci von 50 zu berechnen. Während die Methode mit der ForSchleife innerhalb kürzester Zeit zum Ergebnis führt, wartet man bei der rekursiven Berechnung recht lange darauf.
13.6
Die Registrierdatenbank
In den Versionen Windows 3.x und Windows NT 3.x wurden die Konfigurationseinstellungen von Programmen in INI-Dateien gespeichert. Dabei war die Datei WIN.INI die Hauptkonfigurationsdatei von Windows. In ihr wurden systembezogene Daten abgelegt. Für die anwendungsspezifischen Informationen besaßen die meisten Programme wiederum eigene INI-Dateien. Seit Windows 95 und Windows NT 4.0 werden die Konfigurationen in der Registrierdatenbank (engl. Registry) abgespeichert. Ob dies weit-
250
Sandini Bib
reichende Vor- oder Nachteile hat, ist dabei von keinerlei praktischem Interesse mehr. Inzwischen gehört es zum guten Ton, keine INI-Dateien mehr zu verwenden. In der Registrierdatenbank befinden sich nun alle Informationen über die Windows-Konfiguration, sowie die Daten der installierten Anwendungsprogramme. Welche Daten von einer Anwendung in die Registrierdatenbank geschrieben werden, hängt von der jeweiligen Applikation ab.
Abbildung 13.19: Der Registrierungseditor mit dem Eintrag von Visual Basic 6.0
Um Einträge der Registrierdatenbank anzuzeigen, stellen Windows 95 und Windows NT 4.0 einen Registrierungseditor zur Verfügung. Mit seiner Hilfe können Einträge in der Registrierdatenbank gesucht und modifiziert werden. Die Verwaltung der Registrierdatenbank wird wiederum intern auf mehrere Dateien verteilt. Zur Zeit handelt es sich dabei um die Dateien SYSTEM.DAT und USER.DAT, die jedoch für den Zugriff auf die Registrierdatenbank keine Rolle spielen. Der Aufbau der Registrierdatenbank ist hierarchisch und ähnelt darin dem Aufbau der Verzeichnisstruktur auf einem Datenträger.
13.6.1
Die Schlüssel der Registrierdatenbank
Die Registrierdatenbank besitzt sechs Hauptschlüssel, wobei drei von ihnen besondere Bedeutung zukommt. Die drei wichtigsten Schlüssel sind:
&#
251
Sandini Bib
HKey_Classes_Root: Hier werden alle wichtigen Informationen zu allen Windows-Klassen abgelegt. Darunter fallen die Verknüpfungen von Dateiendungen mit den Anwendungen, die OLE-Klassen und die Registrierung aller anderen Schnittstellen nach dem Component Object Model.
HKey_Current_User: Dieser Schlüssel beinhaltet spezielle Informationen für den aktuellen Benutzer. Im Prinzip gibt dieser Schlüssel nur einen Ast des Baumes HKey_Users wieder, in dem auch eventuell noch weitere Benutzerdaten gespeichert werden.
HKey_Lokal_Machine: Hier werden die Informationen gespeichert, die für die Arbeitsstation relevant sind und für alle Benutzer Gültigkeit besitzen.
Im folgenden werden die drei Hauptschlüssel, denen bei der Softwareentwicklung keine so hohe Bedeutung zukommt, abgehandelt.
HKey_Current_Config: Dieser Schlüssel stammt von dem Hauptschlüssel HKey_Lokal_Machine unter Windows 95 ab, wobei im Unterschlüssel die Nummer der zur Zeit verwendeten Hardwarekonfiguration enthalten ist. Dieser Schlüssel wird für Rechner verwendet, die zwischen zwei Hardwarekonfigurationen unterscheiden. Laptops unterscheiden z.B. zwischen eingedocktem und ausgedocktem Zustand.
HKey_User: In diesem Hauptschlüssel sind alle Profile der Anwender enthalten. Meldet sich ein Anwender am System an, wird das Profil des aktuellen Anwenders an den Schlüssel HKey_Current_User vererbt.
HKey_Dyn_Data: Dieser Schlüssel wird bei jedem Start des Betriebssystems neu erstellt. Alle im HKey_Dyn_Data enthaltenen Daten werden in den Arbeitsspeicher geladen.
Jeder dieser Schlüssel kann beliebig viele Unterschlüssel besitzen. In den INI-Dateien wurde eine Selektion nach Abschnitten durchgeführt. In der Registrierdatenbank erfolgt die Selektion immer durch die Angabe eines gesamten Eintragungspfades.
13.6.2
Der Zugriff auf die Registrierdatenbank
Zum einen stellt die Windows-API selbst verschiedene Funktionen bereit, um mit der Registrierdatenbank zu arbeiten. Die Handhabung dieser Funktionen ist jedoch sehr ermüdend und auch relativ kompliziert. Um den Zugriff auf die Registrierdatenbank zu vereinfachen, stellt Visual Basic eigene Funktionen zur Verfügung. Mit ihnen läßt sich der Zugriff auf die Registrierdatenbank sehr viel einfacher realisieren.
252
Sandini Bib
Eintrag speichern mit SaveSetting Um Schlüssel in der Registrierdatenbank zu erzeugen oder zu speichern, wird die Funktion SaveSetting zur Verfügung gestellt. SaveSetting AppName, Section, Key, Setting Parameter
Beschreibung
APPNAME
Dieser Parameter ist erforderlich und beschreibt den Namen des Projekts oder der Applikation, auf das bzw. die sich der Registrierungseintrag bezieht.
SECTION
Dieser Parameter ist erforderlich und beschreibt den Namen des Abschnitts in dem der Schlüssel gespeichert werden soll.
KEY
Dieser Parameter ist erforderlich. Er repräsentiert den Namen des Schlüssels, dessen Wert gespeichert werden soll.
SETTING
Dieser Parameter ist erforderlich und ist der Wert des Schlüssels, dessen Name mit dem Parameter Key gespeichert wurde.
Abbildung 13.20: Parameterliste zu SaveSetting
Eintrag lesen mit GetSetting Um einen mit SaveSetting gespeicherten Schlüssel wieder aus der Registrierdatenbank zu lesen, wird die Funktion GetSetting von Visual Basic zur Verfügung gestellt. Ihre Parameter sind ähnlich denen von SaveSetting. Result = GetSetting(AppName, Section, Key[ Default]) Parameter
Beschreibung
RESULT
RESULT ist der Ergebniswert, den die Funktion GetSetting zurückliefert.
APPNAME
Dieser Parameter ist erforderlich und beschreibt den Namen des Projekts oder der Applikation auf das bzw. die sich der Registrierungseintrag bezieht.
SECTION
Dieser Parameter ist erforderlich und beschreibt den Namen des Abschnitts in dem der Schlüssel gespeichert ist.
KEY
Dieser Parameter ist erforderlich. Er repräsentiert den Namen des Schlüssels, dessen Wert ermittelt werden soll.
[DEFAULT]
Dieser Parameter ist nicht erforderlich. Er wird verwendet, um der Funktion zu definieren welchen Wert sie an RESULT zurückliefern soll, wenn der Wert des Schlüssels oder der Schlüssel selbst nicht gefunden wurde.
Abbildung 13.21: Parameterliste zu GetSetting
&#
253
Sandini Bib
Eintrag löschen mit DeleteSetting Um einen bestimmten Abschnitt oder nur einen Schlüssel in der Registrierdatenbank zu löschen, wird die Funktion DeleteSetting verwendet. DeleteSetting(AppName, Section[, Key]) Parameter
Beschreibung
APPNAME
Dieser Parameter ist erforderlich und beschreibt den Namen des Projekts oder der Applikation, auf das bzw. die sich der Registrierungseintrag bezieht.
SECTION
Dieser Parameter ist erforderlich und beschreibt den Namen des Abschnitts der gelöscht werden soll oder in dem sich der zu löschende Schlüssel befindet.
[KEY]
Dieser Parameter ist nicht erforderlich. Wird er angegeben, so wird nur der eine Schlüssel aus der Registrierdatenbank entfernt. Wird er nicht angegeben, so werden alle Schlüssel entfernt, die sich unter dem Abschnitt befinden, der im Parameter Section definiert wurde.
Abbildung 13.22: Parameterliste zu GetSetting
Alle Einträge eines Abschnitts lesen Um alle Schlüssel eines bestimmten Abschnitts, die mit der Funktion SaveSetting erzeugt wurden, aus der Registrierdatenbank zu lesen, wird die Funktion GetAllSettings verwendet. Result = GetSetting(AppName, Section, Key[ Default]) Parameter
Beschreibung
RESULT
RESULT ist der Ergebniswert vom Typ Variant, der eine zweidimensionale Liste zurückliefert.
APPNAME
Dieser Parameter ist erforderlich und beschreibt den Namen des Projekts oder der Applikation auf das bzw. die sich der Registrierungseintrag bezieht.
SECTION
Dieser Parameter ist erforderlich und beschreibt den Namen des Abschnitts in dem die Schlüssel gespeichert sind, deren Werte zurückgeliefert werden sollen.
Abbildung 13.23: Parameterliste zu GetSetting
13.6.3
Das Arbeiten mit der Registrierdatenbank
Das Arbeiten mit der Registrierdatenbank wird in den folgenden vier Punkten relativ einfach zusammengefaßt:
254
Erzeugen einer neuen Instanz
Öffnen eines neuen Schlüssels
Sandini Bib
Lesen und Schreiben der Daten in dem Schlüssel
Schließen des bearbeiteten Schlüssels
Mit dem folgenden Programmcode soll das Auslesen eines bestimmten Werts aus der Registrierdatenbank demonstriert werden. Hierfür wird die Schaltfläche btnSchreiben benötigt, die einen Wert aus dem Eingabeelement TXTEINGABE in die Registrierdatenbank schreibt, und eine Schaltfläche BTNLESEN, die diesen Wert dann wieder aus der Registrierdatenbank liest und in dem Beschriftungselement labParam ausgibt. Im folgenden ist der Programmcode für das besprochene Beispiel abgebildet. Option Explicit Private Sub btnAbbrechen_Click() End End Sub Private Sub btnSchreiben_Click() Call SaveSetting("RegistrySchreiben", "Test", "Wert", _ txtEingabe.Text) End Sub Private Sub Command1_Click() labParam.Caption = GetSetting("RegistrySchreiben", "Test", _ "Wert", "Kein Wert gefunden") End Sub
&#
255
Sandini Bib
Sandini Bib
14
Tools
In diesem Kapitel werden einige nützliche Tools und Spiele entwikkelt, mit denen das Arbeiten unter Windows 95 vereinfacht wird oder die eine kurze Ablenkung bedeuten.
14.1
Verzeichnisgröße
Es kommt immer wieder vor, daß man wissen möchte, wieviel Festplattenkapazität ein Verzeichnis mit all seinen Unterverzeichnissen benötigt oder wie viele Unterverzeichnisse und Dateien dort enthalten sind. Das folgende Programmbeispiel soll diese Informationen ermitteln. Als Grundlage für dieses Programm wird ebenfalls das Programm Vorgabe benutzt. Im folgenden werden alle Informationen, die das Programm liefern soll, nochmals definiert:
Anzahl der Verzeichnisse
Anzahl der Dateien
benötigte Speicherkapazität
Diese Informationen sollen für die zwei Optionen gelten:
mit Unterverzeichnissen
ohne Unterverzeichnisse
14.1.1
Die Programmoberfläche
In diesem Abschnitt soll die Programmoberfläche entwickelt werden. Dazu werden alle benötigten Steuerelemente auf das Fenster aufgebracht und ihre Eigenschaften definiert. Um ein Verzeichnis auszuwählen, zu dem die Informationen ausgegeben werden sollen, werden die Steuerelemente Laufwerklistenfeld, Verzeichnislistenfeld und Dateilistenfeld benötigt.
257
Sandini Bib
Für die Ausgabe der Informationen werden sechs Beschriftungselemente in einem Rahmen-Steuerelement benötigt. Dieses RahmenSteuerelement wird dann auf einem Register mit den zwei Laschen mit Unterverzeichnis und ohne Unterverzeichnis aufgebracht. In Abbildung 14.1 wird das mögliche Aussehen des Programms dargestellt.
Abbildung 14.1: Die Oberfläche des Verzeichnisinformations-Programms
In Tabelle 14.1 werden die Steuerelemente und ihre Eigenschaften aufgeführt, die für die Realisierung benötigt werden. Steuerelement
Eigenschaft
Inhalt
Beschreibung
Laufwerklistenfeld
(Name)
drv_DirInhalt
Dies ist der Name des Laufwerklistenfeldes, mit dem es im Programmcode angesprochen wird.
Verzeichnislistenfeld
(Name)
dir_DirInhalt
Dies ist der Name des Verzeichnislistenfeldes, mit dem es im Programmcode angesprochen wird.
Dateilistenfeld
(Name)
fil_DirInhalt
Dies ist der Name des Dateilistenfeldes, mit dem es im Programmcode angesprochen wird.
Hidden
True
Im Dateilistenfeld sollen auch versteckte Dateien angezeigt werden.
Pattern
*.*
Es sollen alle Dateien, unabhängig von ihrem Namen, angezeigt werden.
258
Sandini Bib
Steuerelement
Eigenschaft
Inhalt
Beschreibung
ReadOnly
True
Im Dateilistenfeld sollen auch Dateien angezeigt werden, die schreibgeschützt sind.
System
True
Im Dateilistenfeld sollen auch Systemdateien angezeigt werden.
Rahmen-Steuerelement
(Name)
frm_Dir_Grösse
Der Name des Rahmen-Steuerelements, mit dem es im Programmcode angesprochen wird.
RegisterSteuerelement
(Name)
tab_Verzeichnis
Der Name des Register-Steuerelements, mit dem es im Programmcode angesprochen wird.
TabCount
2
Das Register-Steuerelement hat 2 Registerblätter.
TabCaption
mit Unterverzeichnissen
Der Beschriftungstext des ersten Registerblatts.
ohne Unterverzeichnisse
Beschriftungstext des zweiten Registerblatts.
TabsPerRow
2
Anzahl der Registerblätterlaschen, die in einer Zeile dargestellt werden.
(Name)
lab_Beschriftung(0-2)
Der Name des Beschriftungselements, mit dem es im Programmcode angesprochen wird.
Caption(0)
Benötigter Speicher
Beschriftungstext
Caption(1)
Anzahl Dateien
der Steuerelemente.
Caption(2)
Anzahl Verzeichnisse
(Name)
lab_Speicher
Beschriftungs-elemente
Name der Beschriftungselemente, mit denen sie im Programmcode angesprochen werden.
lab_Dateien lab_Verzeichnis Caption
Bei allen drei Steuerelementen wird keine Beschriftung eingegeben.
Tabelle 14.1: Die Steuerelemente des Verzeichnis-Informations-Programms
14.1.2
Der Programmcode zum VerzeichnisInformationsprogramm
Hier wird der eigentliche Programmcode für das Verzeichnis-Informations-Programm entwickelt. Dabei wird jede Funktion zuerst erklärt und dann Schritt für Schritt entwickelt.
259
Sandini Bib
Verzeichnis auswählen Um ein Verzeichnis auszuwählen, zu dem die Information angefordert wird, stehen die Steuerelemente Laufwerks- und Verzeichnislistenfeld zur Verfügung. Das Dateilistenfeld wird für das Auswählen des Verzeichnisses nicht benötigt, es dient in diesem Programm nur zum Anzeigen aller Dateien im aktuellen Verzeichnis. Als erstes wird der Programmcode, der dem Laufwerkslistenfeld zugeordnet ist, entwickelt. Wenn ein neues Laufwerk ausgewählt wird, muß dieses ebenfalls an das Verzeichnislistenfeld weitergegeben werden, da sich damit auch das Verzeichnis ändert. Achtung: In dem Laufwerkslistenfeld kann auch ein Disketten- oder CD-ROM-Laufwerk ausgewählt werden. Ist aber kein Datenträger eingelegt, kann diese Auswahl zum Absturz führen, also muß dieser Fehler mit einer Fehlerbehandlungsroutine abgefangen werden. Es gibt jedoch auch noch andere Möglichkeiten, warum auf ein Laufwerk nicht zugegriffen werden kann: Z.B. wenn es sich um ein Laufwerk in einem Netzwerk handelt, das zur Zeit nicht verfügbar ist. Tritt ein Fehler bei der Auswahl eines Laufwerks auf, muß das Programm automatisch wieder das Laufwerk einstellen, welches davor ausgewählt war. Private Sub drv_DirInhalt_Change() Dim Laufwerk As Variant 'Zwischenspeicher für das aktuelle Laufwerk On Error GoTo Fehler_drv_DirInhalt_Change ...'Ermittle das aktuelle Laufwerk Laufwerk = Left((dir_DirInhalt.Path), 3) 'Dem Verzeichnislistenfeld das neue Laufwerk mitteilen dir_DirInhalt.Path = drv_DirInhalt.Drive Exit Sub 'Es trat kein Fehler auf Fehler_drv_DirInhalt_Change: 'Es trat ein Fehler auf, also gib eine Fehlermeldung aus Call MsgBox("Fehler beim Laufwerkszugriff", 16, "Laufwerk", _ Err.HelpFile, Err.HelpContext) 'Wechsle wieder auf das zuvor aktive Laufwerk drv_DirInhalt.Drive = Laufwerk Exit Sub 'Funktion ohne Änderung beendet End Sub
Aktualisierung der Verzeichnisinformationen Nachdem das Laufwerk gewechselt wurde, wird auch das Verzeichnis im Verzeichnislistenfeld aktualisiert. Jetzt fehlt noch die Aktualisierung des Dateilistenfeldes. Diese Aktualisierung muß immer dann ausgeführt werden, wenn sich der Inhalt des Verzeichnisses ändert.
260
Sandini Bib
Nachdem ein Verzeichnis geändert wurde, muß auch der Inhalt der Beschriftungsfelder, die zur Darstellung der Verzeichnisinformation dienen, aktualisiert werden. Private Sub dir_DirInhalt_Change() On Error GoTo Fehler_dir_DirInhalt_Change 'Dem Dateilistenfeld das neue Laufwerk mitteilen Fil_DirInhalt.Path = dir_DirInhalt.Path 'Beschriftungsfelder neu initialisieren lab_Speicher.Tag = 0 Lab_Dateien.Caption = 0 lab_Verzeichnis.Caption = 0 'Abhängig vom selektierten Registerblatt die Verzeichnis'informationen ermitteln If tab_Verzeichnis.Tab = 0 Then Call Verzeichnissuchen(dir_DirInhalt.Path, True) Else Call Verzeichnissuchen(dir_DirInhalt.Path, False) End If Exit Sub 'Informationen erfolgreich ermittelt Fehler_dir_DirInhalt_Change: 'Wenn ein Fehler aufgetreten ist, lösche alle Beschriftungs'felder, da keine genauen Informationen mehr vorliegen lab_Speicher.Caption = "" Lab_Dateien.Caption = "" lab_Verzeichnis.Caption = "" 'Ausgeben einer Fehlermeldung an den Benutzer Call MsgBox("Fehler beim Verzeichnislesen", 16, _ "Verzeichnis", Err.HelpFile, Err.HelpContext) Exit Sub 'Funktion kann abgebrochen werden End Sub
Verzeichnis und Unterverzeichnisse durchsuchen Die Funktion Verzeichnissuchen(), die aus der Ereignisfunktion dir_DirInhalt_Change() aufgerufen wird, ermittelt die gewünschten Informationen und schreibt diese direkt in die Beschriftungsfelder. Durch das Aktualisieren der Beschriftungsfelder während der Ausführung erkennt der Benutzer, daß das Programm nicht blockiert ist, denn die Zeit, die benötigt wird, um ein Verzeichnis mit allen seinen Unterverzeichnissen zu durchsuchen, kann – bei komplexen Verzeichnissen – recht lang sein.
261
Sandini Bib
Beim Aufruf der Funktion soll definiert werden, ob nur das aktuelle Verzeichnis oder auch alle Unterverzeichnisse durchsucht werden sollen. Daraus ergibt sich folgende Funktionsdeklaration: Sub Verzeichnissuchen(Verzeichnis As String, Subdir As Boolean)
Parameter
Beschreibung
Verzeichnis
Dies ist das Verzeichnis, das nach Dateien und Unterverzeichnissen durchsucht werden soll.
Subdir
Ist der Parameter True, dann sollen auch die Unterverzeichnisse durchsucht werden. Ist er False, soll die Funktion nur das aktuelle Verzeichnis untersuchen.
Ermitteln des Verzeichnisinhaltes Für das Durchsuchen eines Verzeichnisses gibt es unter Visual Basic den Befehl DIR. Er liefert, abhängig von den Parametereinstellungen, alle Unterverzeichnisse und Dateien in einem Verzeichnis. Die Befehlssyntax ist wie folgt definiert: Ergebnis = Dir([Dateiname [, Attribute]])
Ergebnis
Dieser Parameter liefert einen Verzeichnis- oder Dateinamen zurück, der die definierten Kriterien Dateiname und Attribute erfüllt.
Dateiname
Der Dateiname ist optional und gibt an, nach welchen Dateien gesucht werden soll. Der Dateiname kann auch ein Laufwerk und ein Verzeichnis enthalten. Ebenfalls sind die Sonderzeichen * für mehrere Zeichen und ? für ein Zeichen erlaubt.
Attribute
Dieser Parameter definiert die Attribute der Dateien, die angezeigt werden sollen. Folgende Attribute sind definiert:
262
Konstante
Wert
Beschreibung
vbNormal
0
Normal.
vbHidden
2
versteckte Datei.
vbSystem
4
Systemdatei.
vbVolume
8
Laufwerksbuchstaben; alle anderen Attribute werden ignoriert.
vbDirectory
16
Verzeichnis oder Mappe.
Sandini Bib
Die gefundenen Verzeichniseinträge sind nicht sortiert. Um sie zu sortieren, können sie in eine Feldvariable eingelesen und dann sortiert werden. Wird mit der Funktion DIR kein Eintrag gefunden, so wird ein leerer String ("") zurückgeliefert.
Abbildung 14.2: Der Aufbau eines Verzeichnisbaums
Betrachtet man den Aufbau eines Verzeichnisbaums (Abbildung 14.2), so hat man zwei Möglichkeiten, alle Verzeichnisse zu durchlaufen: Entweder zuerst in die Tiefe – Tiefensuche (depth-first-search) – oder zuerst in die Breite – Breitensuche (breadth-first-search). Tiefensuche Die Tiefensuche arbeitet einen Suchbaum ab, indem zuerst alle Unterknoten des Baums durchsucht werden, bevor ein Nachbarknoten durchsucht wird. In Abbildung 14.3 wird ein Baum dargestellt, der nach dem Verfahren der Tiefensuche abgearbeitet wird. Die Nummern an jeder Kante geben die Reihenfolge an, in der die einzelnen Zweige des Baumes abgearbeitet werden.
Abbildung 14.3: Das Durchlaufen eines Suchbaums mit Tiefensuche
263
Sandini Bib
Breitensuche Die Breitensuche arbeitet einen Suchbaum ab, indem zuerst alle Knoten einer Ebene des Baums und danach die Unterknoten durchsucht werden. In Abbildung 14.4 wird ein Baum dargestellt, der nach dem Verfahren der Breitensuche abgearbeitet wird. Die Nummern an jedem Knoten geben an, in welcher Reihenfolge die einzelnen Blätter des Baums durchlaufen werden.
Abbildung 14.4: Das Durchlaufen eines Suchbaums mit Breitensuche
Das Programmbeispiel für das Durchsuchen des Verzeichnisbaums verwendet die Tiefensuche. Die Tiefensuche ist hervorragend geeignet, um rekursiv programmiert zu werden. Zuerst wird mit dem Befehl DIR geprüft, welche Unterverzeichnisse und Dateien sich in dem aktuellen Verzeichnis befinden. Gefundene Unterverzeichnisse werden in einer Feldvariablen gespeichert und gezählt. Die gefundenen Dateien werden ebenfalls gezählt und die Dateigrößen summiert. Ermitteln der Dateigröße Um in Visual Basic festzustellen, welche Größe eine Datei in Bytes hat, gibt es den Befehl FileLen. Die Befehlssyntax ist wie folgt definiert: Dateigroesse = FileLen(Dateiname)
264
Dateigroesse
Dieser Parameter gibt die Grösse einer Datei in Bytes an, bevor sie geöffnet wird. Um die Größe einer Datei zu ermitteln, die geöffnet wurde, muß der Befehl LOF verwendet werden.
Dateiname
Der Dateiname muß unbedingt angegeben werden, da er definiert, von welcher Datei die Größe ermittelt werden soll.
Sandini Bib
Die ermittelten Werte werden zu den schon gewonnenen Werten in den Beschriftungsfeldern addiert. Danach ruft sich die Funktion erneut für jedes gefundene Unterverzeichnis auf. In Abbildung 14.5 wird dargestellt, wie der Verzeichnisbaum aus Abbildung 14.2 abgearbeitet wird. Die Pfeile an den Ästen zeigen die Reihenfolge der Abarbeitung der einzelnen Blätter an.
Abbildung 14.5: Abarbeitung der Verzeichnisstruktur
Nachdem alle Werte in die Beschriftungsfelder eingetragen wurden, ruft sich die Funktion für jedes gefundene Unterverzeichnis auf, wenn der Aufrufparameter SubDir den Wert True hat. Sub Verzeichnissuchen(Verzeichnis As String, Subdir As Boolean) Dim Eintraege() As String 'Liste aller Unterverzeichnisse Dim i As Integer 'Indexvariable ChDrive Left(Verzeichnis, 1) 'Wechsle in das zu prüfende DRV ChDir Verzeichnis 'Wechsle in das zu prüfende DIR ReDim Preserve Eintraege(i + 1) 'Erweitere das Verzeichnisfeld 'für ein neu gefundenes DIR Eintraege(i) = Dir("*.*", 22) 'Prüfe auf alle Einträge im DIR Do While Eintraege(i) "" 'Solange ein Eintrag vorhanden 'Handelt es sich bei dem Eintrag um ein Verzeichnis? If GetAttr(Eintraege(i)) = vbDirectory Then 'Ist es ein für die Auswertung relevantes Verzeichnis? If Eintraege(i) "." And Eintraege(i) ".." Then 'Erhöhe die Anzahl der gefundenen Verzeichnisse lab_Verzeichnis = lab_Verzeichnis + 1 'Erweitere die Verzeichnisliste für weitere Einträge i = i + 1 ReDim Preserve Eintraege(i + 1) End If Else 'Wenn es kein Verzeichnis ist
265
Sandini Bib
'Erhöhe den Zähler für die Dateien um 1 Lab_Dateien.Caption = Lab_Dateien.Caption + 1 'und aktualisiere den benötigten Speicherzähler lab_Speicher.Tag = CStr(CDbl(lab_Speicher.Tag) + _ FileLen(Eintraege(i))) 'Für eine bessere Anzeige der benötigten 'Speicherkapazität wird die aktuelle Summe bei 'Überschreitung von 5000 Bytes umgerechnet in KB und 'bei der Überschreitung von 2000000 Bytes umgerechnet 'in MB If lab_Speicher.Tag > 2000000 Then lab_Speicher.Caption = _ CLng(lab_Speicher.Tag / 1048576) & " MB" Else If lab_Speicher.Tag > 5000 Then lab_Speicher.Caption = CLng(lab_Speicher.Tag / 1024) & " KB" Else lab_Speicher.Caption = lab_Speicher.Tag & " Byte" End If End If End If DoEvents Eintraege(i) = Dir 'Weiteren Verzeichniseintrag ermitteln Loop If Subdir = False Then 'Wenn nur das aktuelle Verzeichnis Exit Sub 'durchsucht werden soll, verlasse End If 'die Funktion 'Analysiere die Unterverzeichnisse For i = 0 To UBound(Eintraege) – 2 If Right(Verzeichnis, 1) = "\" Then 'Wenn ein "\" den 'Verzeichnisnamen abschließt Call Verzeichnissuchen(Verzeichnis & Eintraege(i), True) Else 'sonst schließe das 'Verzeichnis mit "\" ab. Call Verzeichnissuchen(Verzeichnis & "\" & _ Eintraege(i), True) End If Next i End Sub
Es ist z.B. möglich, daß über ein Netzwerk ein anderer Anwender Daten in ein Verzeichnis kopiert oder darin löscht. Daher muß das Ereignis Click der Schaltfläche die Funktion zur Aktualisierung der gesamten Informationen (Anzahl Unterverzeichnisse, Anzahl Dateien und Speicherbedarf) des Verzeichnisses aufrufen.
266
Sandini Bib
Private Sub btn_Ok_Click() Call dir_DirInhalt_Change End Sub
Wie auch beim Betätigen der Schaltfläche OK müssen alle Daten durch Wechseln des aktiven Registerblattes aktualisiert werden. Bei dem einen Registerblatt ist für den Anwender nur das aktuelle Verzeichnis wichtig, beim anderen Registerblatt der gesamte Verzeichnisbaum. Private Sub tab_Verzeichnis_Click(PreviousTab As Integer) Call dir_DirInhalt_Change End Sub
Beim ersten Programmstart wird jedoch auffallen, daß in den Steuerelementen
Laufwerklistenfeld
Verzeichnislistenfeld
ein Laufwerk mit Verzeichnis ausgewählt ist, aber in den Beschriftungs-Steuerelementen keine Daten über das Verzeichnis ausgegeben werden. Der Grund dafür ist, daß beim Programmstart nicht das Ereignis Change des Verzeichnislistenfelds eintrifft. Aus diesem Grund muß die Funktion dir_DirInhalt_Change noch im Ereignis Load vom Formular aufgerufen werden. Private Sub Form_Load() Call dir_DirInhalt_Change End Sub
14.2
Berechnungen mit dem Zufallsgenerator
Das folgende Programm soll ein Beispiel dafür sein, daß mit dem Computer Probleme gelöst werden können, deren Lösungsweg nicht einmal dem Programmierer bekannt ist. Die Aufgabe ist, zwei Gleichungen mit zwei Unbekannten zu lösen. I.
a = bx * cy
II.
d = ex * f y
Gleichung 14.1: Gleichungssystem mit zwei Gleichungen und zwei Unbekannten
Die Auflösung dieses Gleichungssystems wird einigen Lesern bestimmt nicht leicht fallen. Dennoch soll ein Programm zur Lösung dieser Gleichungen geschrieben werden. Da der Lösungsweg nicht bekannt ist, bedient man sich des Zufallsgenerators.
267
Sandini Bib
14.2.1
Die Programmoberfläche
Für eine übersichtliche Darstellung sollten die beiden Formeln so auf der Oberfläche angeordnet sein, daß zum einen die Eingabe der Konstanten sinngemäß geschieht und zum anderen die Formeln als solche vom Anwender verstanden werden können. Als Grundgerüst dient, wie schon in den vorherigen Beispielen, das Visual Basic-Projekt Vorgabe. Darauf werden sechs Texteingabeelemente für die Konstanteneingabe a, b, c, d, e, f und weitere zehn Beschriftungsfelder aufgebracht. In Abbildung 14.6 wird das mögliche Aussehen der Programmoberfläche dargestellt.
Abbildung 14.6: Die Programmoberfläche für das Gleichungssystem
In Tabelle 14.2 wird jedes Steuerelement, welches zusätzlich auf das Vorgabe-Formular aufgebracht werden muß, beschrieben. Steuerelement
Eigenschaft
Inhalt
Beschreibung
TexteingabeElemente
(Name)
txt_Konstante(0-5)
Der Name der Texteingabeelemente, mit denen sie im Programmcode angesprochen werden.
In der Eigenschaft Font ist die Schriftgröße auf 14 geändert worden, um einen optischen Größeneffekt gegenüber den hochgestellten Zahlen zu erhalten. BeschriftungsElemente
(Name)
lab_Beschriftung(0-4)
Der Name der Beschriftungselemente, die nur zur Visualisierung auf dem Formular aufgebracht werden. Es handelt sich dabei um die Steuerelemente: Fehler und je zweimal =, +
lab_x(0-1) lab_y(0-1)
268
In diesen Beschriftungselementen wird der zuletzt berechnete Wert für die Variablen X und Y angezeigt.
Sandini Bib
Steuerelement
Eigenschaft
Inhalt
Beschreibung
lab_Fehler
In diesem Beschriftungselement wird der momentane Fehler ausgegeben, den das Gleichungssystem zur Zeit noch enthält. Wird eine Lösung gefunden, so sollte dieser Wert sehr klein sein.
Tabelle 14.2: Die Steuerelemente zum Lösen des Gleichungssystems
14.2.2
Der Zufallsgenerator
Wie bereits erwähnt, wird für die Lösungsfindung der Zufallsgenerator verwendet. In Visual Basic heißt der Befehl, der eine zufällige Zahl erzeugt, Rnd. Um den Zufallsgenerator zu initialisieren, steht der Befehl Randomize zur Verfügung. Die Syntax dieser Befehle ist wie folgt definiert: Randomize [Initialwert]
Parameter
Beschreibung
Initialwert
Mit diesem Parameter wird die Ursprungszahl des Zufallsgenerators bestimmt. Wird dieser Parameter nicht angegeben, dann wird automatisch ein Wert aus der Systemzeit generiert.
Zufallszahl = Rnd[(Nummer)]
Parameter
Beschreibung
Zufallszahl
Dies ist die Zahl, die vom Zufallsgenerator erzeugt wurde.
Nummer
Die Nummer ist ein optionaler Parameter und muß nicht angegeben werden. Wird er verwendet, so hat er folgende Funktion:
Nummer
kleiner als 0
Liefert immer die gleiche Zahl als Ergebnis zurück. Der Zufallsgenerator ist „unterbrochen“.
gleich 0
Liefert die Zahl als Ergebnis zurück, die am häufigsten generiert wurde.
größer als 0
Liefert die nächste Zufallszahl zurück.
nicht angegeben
Genauso wie größer als 0.
Die Zufallszahl, die erzeugt wird, ist immer kleiner als eins oder größer/gleich null. Um also eine Zufallszahl in einem bestimmten Be-
269
Sandini Bib
reich zu erzeugen, muß die ermittelte Zahl an den neuen Bereich und den neuen Zahlentyp angepaßt werden. Das folgende Beispiel erzeugt ganzzahlige Zufallszahlen im Bereich von –10 bis + 20: U_Grenze = –10 O_Grenze = 20 Ergebnis = cint(rnd * (O_Grenze – U_Grenze)) + U_Grenze
14.2.3
Der Algorithmus zum Gleichungssystem
Das Programm sucht die Lösung durch Annäherung, d.h. die Variablen werden mit einem Zufallswert initialisiert. Mit diesen Zufallswerten berechnet nun das Programm beide Gleichungen des Gleichungssystems. Der dabei ermittelte Fehler wird in einer Variablen zwischengespeichert. Nun wird zuerst eine Gleichungsvariable mit dem Zufallsgenerator verändert und der neue Fehler des Gleichungssystems ermittelt. Ist dieser Fehler kleiner als der im Zwischenspeicher, so wird der neue Wert in der Gleichungsvariablen behalten. Ist der Fehler größer, behält die Gleichungsvariable ihren alten Wert. Das gleiche wird nun mit der zweiten Gleichungsvariablen gemacht. Wie stark sich eine Gleichungsvariable durch den Zufallsgenerator verändert, wird nun auch noch abhängig vom aktuellen Fehler gemacht. Ist der Fehler sehr groß, werden die Gleichungsvariablen stärker verändert. Geht der Fehler gegen null, wird die Veränderung ebenfalls geringer, um gezielter die besten Werte für die Gleichungsvariablen zu ermitteln. Dieser Algorithmus soll im folgenden entwickelt werden. Eingabewerte prüfen Als erstes muß geprüft werden, ob die vom Benutzer einzugebenden Gleichungskonstanten auch alle korrekt eingegeben wurden. Hierzu müssen alle Texteingabefelder auf ihre Gültigkeit überprüft werden. Ist ein nicht erlaubter Wert eingegeben worden, gibt die Funktion eine Meldung an den Benutzer aus und liefert den Wahrheitswert False an die aufrufende Funktion zurück. Function Alle_Werte_OK() Dim i As Integer Dim Test As Double On Error GoTo Fehler_Alle_Werte_OK For i = 0 To 5 Test = txt_Konstante(i) * 1
270
Sandini Bib
Next i Alle_Werte_OK = True Exit Function Fehler_Alle_Werte_OK: Call MsgBox("Falsche Konstante eingegeben", 16, _ "Fehlereingabe", Err.HelpFile, Err.HelpContext) Alle_Werte_OK = False Exit Function End Function
Initialisierung Nachdem alle Gleichungskonstanten als gültig erkannt wurden, müssen die beiden Unbekannten des Gleichungssystems initialisiert werden. Da die beiden Variablen in jeweils zwei Beschriftungsfeldern ausgegeben werden, müssen dort die Werte, die mit dem Zufallsgenerator erzeugt werden, zugewiesen werden. Es darf jedoch nicht vergessen werden, daß vor dem ersten Benutzen des Zufallsgenerators dieser ebenfalls initialisiert werden muß. Sub Init_Var() lab_x(0).Caption lab_x(1).Caption lab_y(0).Caption lab_y(1).Caption End Sub
= = = =
Rnd lab_x(0) Rnd lab_y(0)
Ermitteln des Gleichungsfehlers Um den Gesamtfehler des Gleichungssystems zu ermitteln, ist zu berücksichtigen, daß der Gesamtfehler immer einen positiven Wert haben sollte. Dies läßt sich realisieren, indem mit dem Betrag1 des Fehlers gerechnet wird. Hierfür gibt es unter Visual Basic den Befehl ABS. Effektiver ist es jedoch, wenn das Quadrat des Fehlers berechnet wird. Das Quadrat einer Zahl ergibt, wie der Betrag, immer eine positive Zahl. Zudem handelt es sich bei dem Fehler um eine quadratische Abweichung, und er fällt somit bei Berücksichtigung sehr viel stärker ins Gewicht. Zum besseren Verständnis wird die Funktion zur Fehlerberechnung (Gleichung 14.2) nochmals mit den verwendeten Bezeichnungen aus Gleichung 14.1 beschrieben.
1. Der Betrag einer Zahl ist der positive Eigenwert dieser Zahl.
271
Sandini Bib
Fehler = (a - (bx * cy)2 + (d - (ex * f y)2 Gleichung 14.2: Berechnung der quadratischen Abweichung
Function Fehlerberechnung() Dim Ergebnis As Double On Error Resume Next Ergebnis = (txt_Konstante(0).Text – (txt_Konstante(1).Text ^ _ lab_x(0).Caption) * (txt_Konstante(2).Text ^ _ lab_y(0).Caption)) ^ 2 Ergebnis = Ergebnis + (txt_Konstante(3).Text – _ (txt_Konstante(4).Text ^ lab_x(0).Caption) * _ (txt_Konstante(5).Text ^ lab_y(0).Caption)) ^ 2 lab_Fehler.Caption = Ergebnis Fehlerberechnung = Ergebnis End Function
Ändern einer Gleichungsvariablen Diese Funktion verändert den Wert einer Gleichungsvariablen mit dem Zufallsgenerator. Dabei wird der aktuelle Fehler des Gleichungssystems berücksichtigt. Ist der Fehler groß, kann die Variable auch stärker verändert werden, um schneller ein besseres Ergebnis zu erzeugen. Ist der Fehler nur noch gering, kann eine größere Veränderung der Gleichungsvariablen dazu führen, daß der Fehler nicht mehr verbessert wird. Das System könnte dann keine Lösung mehr finden. Damit die Zahlen, die erzeugt werden, nicht zu groß werden können und somit einen Programmfehler erzeugen, sollten sie auf ein Maximum begrenzt werden. Wird dieses Maximum dennoch überschritten, da die Zahlen per Zufallsgenerator ermittelt werden, ist zu empfehlen, daß diese Variable komplett neu initialisiert wird, da diese Berechnung das Ergebnis mit großer Wahrscheinlichkeit nicht mehr finden kann. Sub Aendere_Var(Variable As Integer) Dim Ergebnis As Double Ergebnis = Rnd * lab_Fehler.Caption / 10 If Rnd > 0.5 Then Ergebnis = Ergebnis * –1 Select Case Variable Case 1: If Abs(lab_x(0).Caption + Ergebnis) < 100 Then lab_x(0).Caption = lab_x(0).Caption + Ergebnis Else lab_x(0).Caption = Rnd End If
272
Sandini Bib
Case 2: If Abs(lab_y(0).Caption + Ergebnis) < 100 Then lab_y(0).Caption = lab_y(0).Caption + Ergebnis Else lab_y(0).Caption = Rnd End If End Select End Sub
Durchführen der Berechnung Die nun folgende Funktion steuert den Ablauf der bisher erstellten Funktionen nach dem im Abschnitt „Der Algorithmus zum Gleichungssystem“ beschriebenen Algorithmus. Zuerst wird geprüft, ob alle Werte, die vom Benutzer eingegeben werden müssen, auch gültig sind. Danach werden die zu berechnenden Variablen x und y mit Zufallszahlen initialisiert. Nachdem geprüft wurde, wie groß die Abweichung der beiden rechten Seiten gegenüber den geforderten Ergebnissen der linken Seiten ist, wird entweder nach besseren Werten für x und y gesucht oder die Berechnung beendet. In dieser Schleife (der Fehler der Berechnung ist zu groß) wird zuerst die Variable x verändert. Verbessert sich das Ergebnis des Gleichungssystems, wird der neue Wert übernommen, ansonsten wird der alte Wert beibehalten. Danach wird die Variable y verändert; hierfür wird ebenfalls der neue Fehler ermittelt. Die Forderung, daß der Fehler mit den neuen Variablenwerten geringer sein muß als mit den alten Werten, verhindert eine Verschlechterung des Gesamtergebnisses. Sub Berechnen() Dim Fehler As Double Dim neuer_Fehler As Double On Error GoTo Fehler_Berechnen 'Prüfen, ob alle Eingabewerte erlaubt sind If Not Alle_Werte_OK Then Exit Sub 'Initialisiere die Variablen mit dem Zufallsgenerator Call Init_Var 'Berechne die aktuelle Abweichung vom Ergebnis Fehler = Fehlerberechnung Do While Fehler > 0.001 'Solange der Fehler nicht im 'gewünschten Toleranzbereich liegt Call Aendere_Var(1) 'ändere den Wert von x neuer_Fehler = Fehlerberechnung If Fehler > neuer_Fehler Then 'Wenn Rechenfehler kleiner wurde
273
Sandini Bib
lab_x(1).Caption = lab_x(0).Caption 'übernehme den neuen 'Wert für x, Fehler = neuer_Fehler Else 'sonst behalte das alte x lab_x(0).Caption = lab_x(1).Caption End If Call Aendere_Var(2) 'Ändere den Wert von y neuer_Fehler = Fehlerberechnung If Fehler > neuer_Fehler Then 'Wenn Rechenfehler kleiner wurde, lab_y(1).Caption = lab_y(0).Caption 'übernehme den neuen 'Wert für y, Fehler = neuer_Fehler Else 'sonst behalte das alte y lab_y(0).Caption = lab_y(1).Caption End If DoEvents Loop 'Ende der Schleife Toleranzbereich Exit Sub Fehler_Berechnen: 'Wenn ein Fehler aufgetreten ist, Exit Sub 'breche die Berechnung ab End Sub
Starten der Berechnung Nach der Eingabe aller Vorgabewerte kann die Berechnung vom Anwender durch Betätigen der Schaltfäche OK gestartet werden. Private Sub btn_Ok_Click() Call Berechnen End Sub
Änderung eines Wertes Da der Benutzer während des Programmablaufes die Gleichungskonstanten ändern kann, sollte die Berechnung bei einer Änderung abgebrochen und die Ausgabe auf der Programmoberfläche aktualisiert werden. Private Sub txt_Konstante_Change(Index As Integer) Dim i As Integer For i = 0 To 1 lab_x(i) = "X" lab_y(i) = "Y" Next i End Sub
274
Sandini Bib
14.2.4
Auflösung des Gleichungssystems
Für die mathematisch interessierten Leser, die nicht genug Zeit oder Geduld haben, um das Gleichungssystem aufzulösen, soll hier der Lösungsweg aufgezeigt werden. Gleichungssystem: I. II.
a = bx *cy d = ex * f y
Logarithmieren: I. II.
log b a = log b (b x * c y ) log f d = log f ( e x * f y )
II.
log b a = x + log b (c y ) log f d = log f ( e x ) + y
I.
x = log b a − log b (c y )
I.
x=
ln a − ln(c y ) ln b
I.
x=
1 (ln a − y ln c) ln b
II.
y = log f d − log f ( e x )
II.
ln d − ln(e x ) y= ln f
II.
y=
I.
1 (ln d − x ln e) ln f
Substitution:
k= I. II.
ln a ln c = ln d = ln e m n l= ln f ln f ln b ln b
x = k − ly y = m − nx
275
Sandini Bib
I in II eingesetzt
y = m − n( k − ly ) y = m + nly − nk y (1 − nl ) = m − nk
y=
m − nk 1 − nl
Resubstitution und Lösung:
ln d ln a ln e − ln f ln b ln f y= ln c ln e 1− ln b ln f
ln d ln a ln e − ln f ln b ln f 1 ln a − ln c x= ln c ln e ln b 1− ln b ln f
14.2.5
y=
ln b ln d − ln a * ln e ln b ln f − ln c * ln e
x=
1 ln b ln d − ln a * ln e ln c ln a − ln b ln b ln f − ln c * ln e
Zusammenfassung
Diese Art der Problemlösung wird in der Informatik auch für sehr komplexe Aufgaben eingesetzt. Natürlich sind die dafür verwendeten Algorithmen und Datenstrukturen etwas komplexer als in diesem Beispiel, jedoch ist die Arbeitsweise sehr ähnlich. Der Fachbegriff für diese Algorithmen lautet Genetische Algorithmen und Evolutionsstrategien. Der Vorteil dieser Algorithmen besteht darin, daß immer ein Ergebnis gefunden wird. Der Nachteil: Es ist meistens nicht das optimalste Ergebnis.
276
Sandini Bib
14.3
Das Spiel MasterMind
Mit dem folgenden Spiel soll die Programmierung von Drag and Drop, dem Ziehen und Fallenlassen, geübt werden. Drag and Drop bedeutet im einzelnen, daß ein Element auf der Benutzeroberfläche mit der linken Maustaste angewählt werden kann; während die Maustaste gedrückt bleibt, ändert sich der Mauszeiger in ein anderes Symbol. Dieses Symbol kann auf der Benutzeroberfläche verschoben werden. Duch Loslassen der Maustaste wird dieses Symbol „fallengelassen“. Ein Beispiel für Drag and Drop findet man z.B. im WindowsExplorer: Hier werden Dateien in andere Verzeichnisse verschoben und kopiert, indem sie zuerst angeklickt und dann mit gedrückter Maustaste über einem anderen Ordner fallengelassen werden.
14.3.1
Die Spielregeln von MasterMind
Ziel des Spieles ist es, vier Farben, die vom Computer per Zufall ermittelt werden, zu erraten. Nach acht Schritten muß die Lösung gefunden sein; ist sie es nicht, hat man verloren. Ist ein Schritt abgeschlossen, so wertet der Computer diesen aus. Hat der Spieler eine richtige Farbe auf dem falschen Platz gesetzt, wird dies mit einem weißen Feld bewertet. Ist die Farbe am richtigen Platz, wird dies mit einem schwarzen Feld angezeigt. Jede Farbe kann mehrmals vorkommen, wobei die „leere Farbe“ auch eine gültige Farbe ist.
14.3.2
Die Programmoberfläche
Als Grundlage für die Programmoberfäche wird wieder das altbewährte Visual Basic-Projekt Vorgabe von der Diskette eingesetzt. Danach wird die Oberfläche in vier Bereiche eingeteilt: Der Auswahlbereich: Der Bereich, der vorgibt, aus welchen Farben der Computer sein Zufallsmuster zusammenstellen kann. Es ist auch der Bereich, aus dem der Spieler seine Farben auswählt. Der Lösungsbereich: In diesem Bereich wird das vom Computer vorgegebene Muster angezeigt, wenn das Spiel beendet ist, wenn also das Muster gefunden wurde oder keine Eingabemöglichkeiten mehr bestehen. Der Eingabebereich: Im Eingabebereich gibt der Spieler sein Muster vor. Dieser Bereich besteht aus acht Feldern, wobei jedes Feld exakt so aussieht wie das Lösungsfeld.
277
Sandini Bib
Der Auswertungsbereich: Im Auswertungsbereich wird nach Abschluß eines Spielzuges ausgegeben, wie viele Farben gefunden wurden und wie viele davon die richtige Position haben. In Abbildung 14.7 ist eine mögliche Anordnung der Steuerelemente auf der Programmoberfläche abgebildet.
Abbildung 14.7: Die Programmoberfläche des Spiels MasterMind
Die Programmoberfläche besteht in diesem konkreten Fall aus folgenden Steuerelementen Steuerelement
Eigenschaft
Inhalt
Beschreibung
RahmenSteuerelement
(Name)
frm_Eingabe(0-7)
Hier finden sich alle Rahmensteuerelemente, die die Eingabeflächen für das Farbmuster des Spielers enthalten. Jedes Rahmensteuerelement enthält ebenfalls 4 Eingabefelder.
frm_Ergebnis(0-7)
Hier finden sich alle Rahmensteuerelemente, die die Ausgabeflächen enthalten, mit denen der Computer die Anzahl der gefundenen Farben anzeigt. Jedes Rahmensteuerelement enthält 4 Ausgabefelder.
frm_Loesung
In diesem Steuerelement wird das Zufallsmuster des Computers dargestellt.
278
Sandini Bib
Steuerelement
Bilderschaltflächen
Eigenschaft
Inhalt
Beschreibung
frm_Vorgabe
In diesem Steuerelement sind alle Farben dargestellt, aus denen das Zufallsmuster generiert werden kann.
(Name)
pic_Farben(0-7)
Diese Steuerelemente sind im RahmenSteuerelement frm_Vorgabe untergebracht und enthalten die zur Auswahl stehenden Farben.
DragMode
1-Automatisch
Wird ein Steuerelement mit der linken Maustaste selektiert, verändert sich der Mauskursor automatisch und stellt das Symbol dar, welches der Eigenschaft DragIcon zugewiesen ist.
DragIcon
(Symbole)
Symbol, das der Mauskursor im Drag Drop-Modus darstellen soll (Die DRAG*.ICO-Dateien von der Diskette).
Picture
(Bild)
Bild, das das Steuerelement darstellen soll, also jeweils eine der acht darzustellenden Farben (Die FARBE.ICO-Dateien von der Diskette).
(Name)
pic_Loesung(0-3)
Dies enthält die vom System mittels Zufallsgenerator ausgewählten Farben.
pic_Eingabe(0-29)
Hier definiert der Spieler seine Farbeingaben. Auf jedem frm_Eingabe sind vier pic_Eingabe-Steuerelemente aufgebracht, mit dem Index von links nach rechts steigend.
pic_Ergebnis(0-29)
Hier gibt der Computer die Information an den Spieler aus, wieviele Farben gefunden wurden. Auf jedem frm_Ergebnis sind vier pic_Ergebnis-Steuerelemente aufgebracht.
Tabelle 14.3: Die Steuerelemente des Spieles MasterMind
14.3.3
Der Programmcode zu MasterMind
In diesem Abschnitt wird der Programmcode für das Spiel entwickelt und bei jeder Funktion – bevor sie entwickelt wird – auf ihre Aufgabe und Arbeitsweise eingegangen. Der Programmstart Wird das Programm gestartet, müssen zunächst einige Initialisierungen vorgenommen werden. Zum einen sollen die Felder, die das Ergebnis des Spielzuges ausgeben, nicht sichtbar sein. Zum anderen dürfen die Felder zur Eingabe nicht verfügbar sein, da der Computer noch kein Lösungsmuster ermittelt hat. Die Felder, in denen der
279
Sandini Bib
Computer sein Zufallsmuster ausgibt, müssen ebenfalls auf „nicht sichtbar“ gesetzt werden. Beim Starten des Programmes sollte auch der Zufallsgenerator mit Randomize neu initialisiert werden, damit eine Wiederholung des alten Spieles verhindert wird. Private Sub Form_Load() Dim i As Integer Randomize 'Zufallsgenerator initialisieren 'Die Verfügbarkeit der Steuerelemente definieren lab_Loesung.Visible = False frm_Loesung.Enabled = False For i = 0 To 7 frm_Ergebnis(i).Visible = False frm_Ergebnis(i).Enabled = False frm_Eingabe(i).Enabled = False Next i End Sub
Das Spiel beginnen Wird das Spiel begonnen, so müssen alle Ergebnisse und LösungsfeldSteuerelemente auf „leer“ zurückgesetzt werden. Denn wenn schon ein Spiel stattgefunden hat, sind den Steuerelementen noch die alten Farben zugewiesen. Um ein Bildfeld-Steuerelement zu löschen, ist es am einfachsten, wenn der Eigenschaft Picture „nichts“ zugewiesen wird. Dies geschieht mit dem Befehl Nothing. Sub Felder_loeschen() Dim i As Integer For i = 0 To 3 + 4 * 7 pic_Eingabe(i).Picture = Nothing pic_Ergebnis(i).Picture = Nothing Next i End Sub
Das Zufallsmuster Nach dem Zurücksetzen aller Bildfeld-Steuerelemente wird vom Computer das Zufallsmuster aus den möglichen Farben bestimmt. Für diesen Zweck wird die folgende Funktion benötigt. Sie bestimmt vier Zufallszahlen und rechnet sie in den möglichen Wertebereich um. In diesem Spiel gibt es neun Farben, also sind die Zahlen 0 bis 8 gültig.
280
Sandini Bib
Sub Ermittle_Zufallsmuster() Dim i As Integer For i = 0 To 3 pic_Loesung(i).Picture = pic_Farben(CInt(Rnd * 8)).Picture Next i End Sub
Farbauswahl des Spielers durch Drag and Drop Wurden den Steuerelementen die Eigenschaften aus Tabelle 14.3 zugewiesen, verändert sich beim Anklicken eines Farbensteuerelements der Mauscursor in das Symbol, welches der Eigenschaft DragIcon zugewiesen wurde. Dies kann nun zwar über die Oberfläche bewegt, jedoch nirgendwo abgelegt werden. Um nun ein Bild aus den Farbensteuerelementen per Drag and Drop in die Eingabebilder zu übernehmen, muß in der Ereignisfunktion DragDrop der Eingabebilder das Bild des Quellsteuerelements zugewiesen werden. Private Sub pic_Eingabe_DragDrop(Index As Integer, Source As Control, X As Single, Y As Single) pic_Eingabe(Index).Picture = Source.Picture End Sub
Spielzug auswerten Nachdem ein Spielzug abgeschlossen wurde, muß vom Computer ausgewertet werden, wie viele Farben richtig geraten wurden, aber an der falschen Position (weißes Bildfeld) und wie viele an der richtigen Position (schwarzes Bildfeld) sind. Um zu vermeiden, daß ein Farbfeld zweimal bewertet wird, erhält die Eigenschaft Tag des Bildfeldsteuerelementes den Zustand True, wenn sie einmal identifiziert wurden. Die Eigenschaft Tag signalisiert somit, ob ein Lösungsbildelement schon mit einem Eingabebildelement verknüpft wurde. Um zu vermeiden, daß eine Farbe, die sich an der richtigen Position befindet, nicht als solche angezeigt wird, weil zuvor ein anderes Farbfeld mit der gleichen Farbe dieses Element schon als benutzt gekennzeichnet hat, werden zuerst die Farben geprüft, die an der richtigen Position stehen. Danach wird überprüft, ob die Farben, deren Benutzersignal noch False ist, in dem Vorgabemuster überhaupt vorhanden sind. Die Funktion liefert True zurück, wenn alle Farben gefunden wurden und an der richtigen Position sind. Sonst ist der Rückgabewert False. Function Auswertung(Nummer As Integer) Dim i As Integer Dim j As Integer Dim Ergebnis(4) As Integer
281
Sandini Bib
Dim gefunden As Integer 'Prüfe, ob eine richtige Farbe am richtigen Ort ist For i = 0 To 3 If pic_Loesung(i).Picture = _ pic_Eingabe(i + 4 * Nummer).Picture Then pic_Eingabe(i + 4 * Nummer).Tag = True pic_Loesung(i).Tag = True Ergebnis(gefunden) = 2 gefunden = gefunden + 1 Else pic_Eingabe(i + 4 * Nummer).Tag = False pic_Loesung(i).Tag = False End If Next i 'Prüfe, ob eine richtige Farbe vorhanden ist, 'jedoch auf einer falschen Position ist For i = 0 To 3 For j = 0 To 3 If pic_Eingabe(i + 4 * Nummer).Tag = False And _ pic_Loesung(j).Tag = False Then If pic_Loesung(j) = pic_Eingabe(i + 4 * Nummer) Then pic_Eingabe(i + 4 * Nummer).Tag = True Ergebnis(gefunden) = 1 gefunden = gefunden + 1 End If End If Next j Next i 'Eintragen der gefundenen Übereinstimmungen in die 'Auswertungsbilder For i = 0 To 3 If Ergebnis(i) = 2 Then pic_Ergebnis(i + 4 * Nummer).Picture = _ pic_Farben(0).Picture Else If Ergebnis(i) = 1 Then pic_Ergebnis(i + 4 * Nummer).Picture = _ pic_Farben(8).Picture End If End If Next i Auswertung = Ist_Gewonnen(Nummer) End Function
282
Sandini Bib
Mit der Funktion Ist_Gewonnen wird geprüft, ob alle Ergebnisbildfelder des aktuellen Spielzuges identisch mit dem Farbmuster sind, das als Volltreffer definiert wurde. Function Ist_Gewonnen(Nummer As Integer) As Boolean Dim i As Integer Ist_Gewonnen = True For i = 0 To 3 If pic_Ergebnis(i + 4 * Nummer).Picture _ pic_Farben(0).Picture Then Ist_Gewonnen = False End If Next i End Function
Ausgabe des Spielendes Wird das Spiel beendet – zum einen durch Finden des Vorgabemusters, zum anderen, weil die Anzahl der möglichen Spielzüge nicht ausgereicht hat –, muß ein Meldungstext auf dem Bildschirm ausgegeben werden. Sub Meldungstext_Ausgeben(Gewonnen As Boolean) If Gewonnen = True Then Call MsgBox("Herzlichen Glückwunsch", vbInformation, _ "Gewonnen") Else Call MsgBox("Sie haben leider verloren", vbExclamation, _ "Verloren") End If End Sub
Die Spielsteuerung Alle bisher entwickelten Funktionen müssen nun sinnvoll gesteuert werden. Es muß definiert werden, auf welchen Eingabesteuerelementen der Spieler seine Farben definieren (fallenlassen) darf und wann der Computer den Spielzug auswerten soll. Private Sub btn_Ok_Click() Static Aktiv As Integer Static Beschriftung As String Dim Gewonnen As Boolean If btn_Ok.Caption "Aus&werten" Then Beschriftung = btn_Ok.Caption btn_Ok.Caption = "Aus&werten" Aktiv = 0
283
Sandini Bib
frm_Eingabe(Aktiv).Enabled = True frm_Eingabe(Aktiv).BorderStyle = 0 pic_Loesung(0).Visible = False pic_Loesung(1).Visible = False pic_Loesung(2).Visible = False pic_Loesung(3).Visible = False Call Ermittle_Zufallsmuster Call Felder_loeschen Else frm_Eingabe(Aktiv).Enabled = False frm_Eingabe(Aktiv).BorderStyle = 1 frm_Ergebnis(Aktiv).Visible = True Gewonnen = Auswertung(Aktiv) If Aktiv > 6 Or Gewonnen = True Then btn_Ok.Caption = Beschriftung pic_Loesung(0).Visible = True pic_Loesung(1).Visible = True pic_Loesung(2).Visible = True pic_Loesung(3).Visible = True Call Meldungstext_Ausgeben(Gewonnen) Else frm_Ergebnis(Aktiv).Visible = True Aktiv = Aktiv + 1 frm_Eingabe(Aktiv).Enabled = True frm_Eingabe(Aktiv).BorderStyle = 0 End If End If End Sub
Die Variable Aktiv bestimmt den aktuellen Spielzug. Zuerst wird geprüft, ob die Beschriftung der Schaltfläche mit dem Text identisch ist, der bestimmt, ob es sich um einen weiteren Spielzug oder einen Neuanfang des Spieles handelt. Handelt es sich bei der Beschriftung nicht um den Text Aus&werten, sondern um einen anderen, wird das Spiel begonnen. Die Variable Aktiv wird initialisiert und der Beschriftungstext der Schaltfläche auf Aus&werten geändert. Bei jedem Spielzug, bei dem die Beschriftungsschaltfläche Aus&werten heißt, wird der Spielzugzähler Aktiv um eins erhöht und die Eingabe vom Spieler ausgewertet. Damit der Spieler seine gewählte Farbe nicht auf allen Eingabebildfeldern mittels Drag and Drop ablegen kann, wurden zu Beginn des Spiels alle Eingaberahmen auf „nicht verfügbar“ gesetzt. Aus diesem Grund muß jetzt vor jedem Spielzug dasjenige EingaberahmenElement auf „verfügbar“ geschaltet werden, auf dem die nächsten Eingaben gemacht werden. Beim Abschließen eines Spielzugs muß
284
Sandini Bib
das Eingaberahmen-Steuerelement dann wieder gesperrt und das zugehörige Ergebnisrahmen-Steuerelement angezeigt werden. Zum Schluß wünsche ich noch viel Spaß beim Spielen!
285
Sandini Bib
Sandini Bib
15
Der Installationsassistent
Um ein mit Visual Basic 6.0 geschriebenes Programm an andere Anwender weiterzugeben, wird der Entwicklungsumgebung ein Installationsassistent zur Verfügung gestellt. In der neuen Version von Visual Basic heißt dieser Assistent nun Verpackungs- und WeitergabeAssistent; da dieser Name aber zu lang ist, werde ich bei Installationsassistent bleiben. Mit Hilfe dieses Assistenten lassen sich Installations- oder Setup-Programme für selbstgeschriebene Anwendungen herstellen.
Eine Applikation zum Erstellen von Installationsdisketten
Abbildung 15.1: Der Installationsassistent
287
Sandini Bib
Starten des Installationsassistenten
15.1 Aufrufen der Applikation aus der Windowsoberfläche
Der Installationsassistent (siehe Abbildung 15.1) wird über das folgende Menü aufgerufen: Start | | | |
Programme Microsoft Visual Basic 6.0 Microsoft Visual Basic 6.0 Tools Verpackungs- und Weitergabe-Assistent
Das nun erscheinende Fenster erklärt die Aufgabe des Installationsassistenten. Damit das Fenster nicht bei jedem neuen Aufruf des Assistenten gestartet wird, kann es über das Kontrollkästchen Diesen Bildschirm künftig übergehen deaktiviert werden. Mit der Schaltfläche WEITER kann nun der nächste Schritt erfolgen.
15.2
Das Erstellen von Installationsdisketten
In den folgenden Schritten wird für das Programm Stack-Taschenrechner ein Installationsprogramm zur Weitergabe erstellt.
15.2.1 Das Projekt, für daß das Installationsprogramm erstellt werden soll, auswählen
Festlegen des Programmes (Projekts)
Durch Betätigen der Schaltfläche DURCHSUCHEN wird das Projekt, für das das Installationsprogramm erzeugt werden soll, festgelegt. Existiert das Projekt noch nicht, kann es auch über das Selektieren des Kontrollkästchens erzeugt werden. In diesem Beispiel existiert das Programm bereits. Es befindet sich auf der dem Buch beiliegenden Diskette im Verzeichnis \Rechner.
15.2.2
Die Optionen des Installationsassistenten
Verpacken Mit der Schaltfläche VERPACKEN erstellt der Installationsassistent aus einem Visual Basic 6.0-Projekt ein Installationsprogramm, mit dem die Software professionell weitergegeben werden kann. Hierfür werden die benötigten Dateien analysiert und in ein weiteres Verzeichnis gepackt. Ist das Kontrollkästchen Abhängigkeitsdatei generieren aktiv, wird mit dem Installationsprogramm eine Datei erzeugt, die alle Abhängigkeiten des Projekts enthält. Diese Datei wird in dem gleichen Verzeichnis abgelegt, in dem sich auch das Projekt befindet.
288
Sandini Bib
Verteilen Durch Betätigen der Schaltfläche VERTEILEN, kann das Programm zum Herunterladen im Internet oder Intranet bereitgestellt werden. Diese Option gilt jedoch nur für Visual Basic-Projekte vom Typ
ActiveX-Steuerelemente,
ActiveX-EXE,
ActiveX-DLL
In der Visual Basic-Version 6.0 Learning Edition ist diese Option nicht verfügbar. Skripts verwalten Mit der Schaltfläche SKRIPTS VERWALTEN lassen sich die Verpackungsund Weitergabeskripts verwalten. Sie können hier benannt, kopiert und gelöscht werden. Für das Installationsprogramm des Taschenrechners müssen die Option INSTALLATIONSPROGRAMM ERSTELLEN und das Kontrollkästchen Abhängigkeitsdatei generieren aktiviert sein.
15.2.3
Generieren der Installationsdatei
Um ein Setup-Programm für den Rechner zu erzeugen, wird die Schaltfläche VERPACKEN betätigt. Wenn die aktuelle EXE-Datei älter ist als eine Komponente des Visual Basic Projekts, werden Sie in einem Zwischenschritt gefragt, ob die ausführbare Datei neu übersetzt werden soll. Mit Ja wird sofort eine neue EXE-Datei erzeugt, mit NEIN die alte Datei in das Setup integriert. Danach werden weitere Abhängigkeiten geprüft. Im nächsten Auswahlfenster (Abbildung 15.2) wird festgelegt, ob nur die Abhängigkeitsdatei für die Installation oder aber ein Setup-Programm erzeugt werden soll. Für die Weitergabe des Programmes Rechner wird die Option Standardmäßiges Setup-Paket verwendet.
289
Sandini Bib
Abbildung 15.2: Festlegen der Verteilungsart
15.2.4 Das Verzeichnis bestimmen, in dem das Installationsprogramm abgelegt werden soll
Das Zielverzeichnis bestimmen
Im folgenden Menü muß nun das Verzeichnis gewählt werden, in dem das Installationsprogramm abgelegt werden soll. Sollte das Verzeichnis noch nicht existieren, kann es jetzt noch über einen Dateimanager erzeugt werden. Existiert das Verzeichnis schon, kann es durch Festlegen des Laufwerks und Zielverzeichnisses ausgewählt werden. Mit der Schaltfläche WEITER Gelangt man in das nächste Auswahlfenster.
15.2.5 Wenn ActiveX-ServerKomponenten dem Installationsprogramm hinzugefügt werden müssen.
290
Das Festlegen von zusätzlichen Treibern
In dem Fenster Paket- und Weitergabe-Assistent – DAO-Treiber (Abbildung 15.3) können nun die Schnittstellentreiber für den Datenzugriff ausgewählt werden. Sollte die Applikation, zu der das Installationsprogramm erstellt wird, weitere Komponenten wie z.B. Treiber für den Datenbankzugriff, benötigen, die nicht in der Liste aufgeführt sind, können diese aus der Liste Verfügbare Treiber selektiert und dem Projekt hinzugefügt werden.
Sandini Bib
Abbildung 15.3: DAO-Treiber
Mit der Schaltfläche WEITER kann zum nächsten Auswahlfenster gewechselt werden, da in diesem Projekt keine Treiber für den Datenbankzugriff verwendet werden.
15.2.6
CAB-Optionen
In diesem Auswahlfenster wird die Verteilungsart festgelegt, indem die Größe der einzelnen Pakete entweder begrenzt, oder die gesamte Installation als ein Paket gespeichert wird. Verteilungsart
Beschreibung
mehrere CAB-Dateien
Alle benötigten Installationsdateien werden in mehrere Pakete aufgesplittet, deren Größe eine bestimmte Diskettenkapazität nicht überschreitet. Die Größe eines Pakets wird in der Auswahlbox festgelegt. Hier sind die gängigsten Diskettengrößen aufgelistet. Diese Methode empfiehlt sich für die Softwareverteilung auf einzelne Rechner sowie beim Vertrieb dieser Software, sofern die Anzahl der Disketten nicht zu groß ist.
einzelne CAB-Datei
Alle benötigten Installationsdateien werden mit der Datei SETUP.EXE in ein Verzeichnis kopiert, von dem aus die Installation durchgeführt werden kann. Diese Methode empfiehlt sich für die Softwareverteilung in einem Netzwerk oder wenn das Programm auf eine CD-ROM gebrannt werden kann.
291
Sandini Bib
Für das Erzeugen der Taschenrechner-Installationsroutine soll die Option Einzelne CAB-Datei aktiviert werden. Durch erneutes Betätigen der Schaltfläche WEITER wird zum nächsten Auswahlfenster gewechselt.
15.2.7
Festlegen des Installationstitels
In diesem Dialog wird der Name der Applikation festgelegt, der beim Installieren der Software angezeigt wird. Im allgemeinen erscheint er links oben im Installationsfenstertitel.
15.2.8
Festlegen der Menüeinträge
Nach erneutem Betätigen der Taste WEITER können nun im Dialog Paket- und Weitergabe-Assistent – Startmenüelemente (Abbildung 15.4) der oder die Einträge festgelegt werden, die automatisch im Start-Menü installiert werden sollen.
Abbildung 15.4: Start-Menü
Jedem Knoten (bei dem es sich hier um ein Menü handelt) können weitere Menüs oder Programme zugeordnet werden, die dann bei der Installation in das Start-Menü eingetragen werden. Die Blätter bilden die aufzurufenden Dateien. Ihnen kann kein weiterer Knoten oder Menüeintrag zugeordnet werden. Knoten werden mit der Schaltfläche NEUE GRUPPE und aufzurufende Dateien mit der Schaltfläche NEUES ELEMENT angelegt.
292
Sandini Bib
Mit der Schaltfläche EIGENSCHAFTEN... können die Eigenschaften des jeweiligen Elements festgelegt werden. Bei Knoten bestimmt man, ob es sich um ein Standardmenüeintrag oder um ein privates Menü handelt. Im Falle der Menüeinträge werden der Name der zu startenden Applikation, der Pfad, in der sich die ausführbare Datei befindet, und der Text, der im Menü erscheinen soll festgelegt. Um einen Gruppeneintrag zu löschen, wird die Schaltfläche ENTFERNEN bereitgestellt. Nachdem das Bearbeiten der Programmgruppe abgeschlossen ist, geht es mit WEITER zum nächsten Fenster.
15.2.9
Installationsorte der Dateien
In dem Fenster Installationsorte (Abbildung 15.5) werden alle Dateien angezeigt, die für die Installation der weiterzugebenden Applikation benötigt werden. Hierbei werden der Name und der Ort der zu kopierenden Quelldatei aufgelistet. In einer weiteren Spalte wird angegeben, wohin die Datei bei der Installation kopiert wird. Um das Zielverzeichnis der Datei zu ändern, muß das neue Zielverzeichnis aus dem Listenelement ausgewählt werden, welches beim Selektieren der dritten Spalte aufgeklappt wird.
Abbildung 15.5: Installationsorte der Dateien festlegen
Im nächsten Installationsschritt können die Dateien festgelegt werden, die auch von anderen Anwendungen verwendet werden können. Diese Dateien werden erst dann deinstalliert, wenn alle Programme deinstalliert wurden, die auch diese Dateien verwenden. Um das Installationsprogramm für den Rechner zu erzeugen, muß die Datei nicht selektiert werden.
293
Sandini Bib
15.2.10 Skriptdatei
In diesem Schritt wird der Name für die Skriptdatei festgelegt. Beim erneuten Erzeugen der Installationssoftware für den Rechner kann dann diese Datei verwendet werden, die automatisch alle Einstellungen übernimmt. Man spart sich somit den Arbeitsaufwand, immer wieder alle Optionen durchzugehen. Im Falle des Projektes Rechner sind die Einstellungen nicht so individuell und komplex, bei großen Applikationen kann es aber sehr aufwendig sein, alle Einstellungen zu reproduzieren. Nach Betätigen der Taste FERTIGSTELLEN werden folgende Verarbeitungsschritte durchgeführt: Verarbeitung von
erforderlichen Visual Basic-Laufzeitdateien,
Objekten und Verweisen,
erforderlichen Projektdateien,
Abhängigkeitsinformationen.
Dieser Prozeß kann einige Zeit in Anspruch nehmen. Dies hängt ganz von der Projektgröße und der Computerleistung ab. Es kann auch vorkommen, daß einige benötigte Dateien vom System nicht gefunden werden. In diesem Fall muß die benötigte Datei z. B. mit Hilfe eines Dateimanagers gesucht werden. Ist die gesuchte Datei gefunden, kann das Verzeichnis der Datei dem Installationsassistenten angegeben werden. Nach erfolgreicher Beendigung erscheint dann der Abschlußbericht. 15.2.11 Verpackungsbericht
Nachdem das Erzeugen der Installationssoftware beendet ist, wird ein Abschlußbericht eingeblendet. Er gibt an, wie viele Dateien erzeugt und in welchem Verzeichnis sie abgelegt wurden. Im Falle des Auftretens von Fehlern werden diese ebenfalls hier aufgeführt. Wenn eine Datei in der Applikation, für die die Installationssoftware erzeugt wurde, geändert wird, muß eine neue Installationssoftware erzeugt werden. Hierfür generiert der Installationsassistent eine BATDatei. Der Name der Datei und das Verzeichnis, in dem sie gespeichert wurde, werden ebenfalls im Verpackungsbericht angezeigt.
294
Sandini Bib
16
Das Erstellen eines Hilfesystems
In einem vorhergehenden Abschnitt wurde bei der Eigenschaft HelpContext erwähnt, daß der Komponenten ein Hilfetext zugeordnet werden kann. In modernen Applikationen ist es selbstverständlich, daß der Anwender immer Hilfe zum gerade aktuellen Bildschirm bekommt, wenn er die Taste (F1) betätigt. Aus diesem Grund soll in diesem Abschnitt mit dem Generieren einer Hilfedatei begonnen werden, die dann in das Programm Verzeichnisgröße eingeführt wird. Für das Generieren einer solchen Datei werden zwei zusätzliche Programme benötigt. Zum einen eine Textverarbeitung, mit der Dokumente im Rich Text Format (*.rtf) gespeichert werden können, zum anderen ein Hilfecompiler. Der Hilfecompiler wird ebenfalls auf der Visual Basic 6.0-CD-ROM ausgeliefert. Es befindet sich im folgenden Verzeichnis: :\Common\Tools\VB\HCW\
Da es sich bei dem Hilfecompiler um Freeware handelt, kann die neueste Version auch kostenlos aus dem Internet heruntergeladen werden. Die Adresse lautet: ftp://ftp.microsoft.com/Softlib/MSLFILES/hcwsetup.EXE
Für die Textverarbeitung WinWord 97 habe ich auf der Diskette eine Vorlagendatei gespeichert, die beim Formatieren dieser Hilfedateien Unterstützung bietet. Die Datei HILFEDATEI.DOT befindet sich auf der Diskette im Verzeichnis HILFE\WINWORD. Kopieren Sie diese Datei in das Autostart-Verzeichnis Ihres Office-Pakets, z.B. nach : C:\PROGRAMME\OFFICE97\OFFICE\STARTUP. Ab jetzt steht Ihnen unter WinWord eine neue Menüleiste zur Verfügung, mit der sich relativ leicht ein Hilfetext formatieren läßt.
295
Sandini Bib
16.1
Was ist kontextsensitive Hilfe?
Eine kontextsensitive Hilfe bietet auf Anfrage Informationen zu dem Programmteil, mit dem sich der Anwender gerade befaßt. Der Anwender bekommt also mit dieser Art von Hilfesystem automatisch dasjenige Kapitel der Hilfe angezeigt, das für den aktuellen Programmabschnitt benötigt wird. Ab Windows 95 und Windows NT 4.0 gehören die kontextsensitiven Hilfen zum standardmäßigen Umfang eines jeden Programms.
16.2
Grundlegende Begriffe für das Erstellen einer Hilfedatei
Bevor mit dem Erzeugen einer Hilfedatei begonnen werden kann, müssen einige Grundbegriffe erklärt werden. Thema. Die Hilfetexte gliedern sich in zahlreiche Themen, die aus einer zusammenhängenden Texteinheit bestehen. Jede Texteinheit wird von dem Hilfeprogramm als eine komplette Textseite verwendet. Dabei können diese Hilfeseiten beliebig lang sein. Inhaltsverzeichnis. Die Inhaltsverzeichnisse stellen in der Form, in der sie hier erzeugt werden können, unter Windows 95 und Windows NT eine Neuerung dar. Das Inhaltsverzeichnis entspricht prinzipiell dem Inhaltsverzeichnis eines Buches, jedoch handelt es sich hierbei um inhaltlich geordnete Querverweise zu den wichtigsten Themen. Die Themenbereiche der verfügen über Unterpunkte, die auf- und zugeklappt werden können, damit die Liste übersichtlicher bleibt. Schlüsselwort. Jedem Hilfethema können ein oder mehrere Schlüsselwörter zugeordnet werden. Um ein Hilfethema schneller auffinden zu können, kann mit der INDEX-Schaltfläche des Hilfeprogramms eine alphabetische Liste aller Schlüsselwörter angezeigt werden. Titel. Die Titel sind nur für die Volltextsuche von Bedeutung. Sie werden im unteren Fenster des Dialogblattes SUCHEN vom Hilfeprogramm angezeigt. Querverweise. Damit in den Hilfetexten kreuz und quer durch die Themen gesprungen werden kann, gibt es sogenannte Querverweise. Sie werden grün und unterstrichen dargestellt.
296
Sandini Bib
Identifikationsname. Das Ziel eines jeden Querverweises ist der sogenannte Identifikationsname des Themas. Er wird nur intern verwendet und kann auch nirgendwo angezeigt werden. Der Identifikationsname besteht aus einer Zeichenkette ohne Leerzeichen und in einigen Hilfesystemen auch ohne Sonderzeichen. Sequenznummern. Die Sequenznummern werden verwendet, um dem Hilfeprogramm mitzuteilen, welche Themen in welcher Reihenfolge angezeigt werden sollen, damit im Hilfeprogramm vorwärts und rückwärts geblättert werden kann. Kontextnummern. Damit von einem Steuerelement aus der richtige Hilfetext aufgerufen werden kann, werden in einzelnen Hilfethemen Kontextnummern vergeben. Bei einer solchen Nummer handelt es sich um eine Zahl vom Typ longint. In den Steuerelementen wird die Kontextnummer, die den Hilfetext für das aktuelle Steuerelement enthält, in der Eigenschaft HelpContext angegeben. Begriffserklärung. Fachausdrücke, die ohne eine Referenzierung erklärt werden sollen, können als Begriffserklärung definiert werden. Der Begriff wird im Hilfetext dann in grüner Schrift dargestellt. Wenn der Benutzer den Begriff anklickt, erscheint die Erklärung des Begriffs in einer kleinen rechteckigen Sprechblase. Überschriftenbereich. Um einen Bereich des Hilfetexts als Bereich festzulegen, der bei langen Hilfetexten nicht nach oben aus dem sichtbaren Bereich des Hilfefensters verschoben werden kann, muß dieser Text mit dem Attribut Absätze nicht trennen gekennzeichnet sein und am Anfang des Themas stehen. Der Überschriftenbereich läßt sich auch farblich abheben. Diese Einstellung läßt sich jedoch nicht in der Textverarbeitung definieren, sondern im Hilfecompiler über die Schaltfläche WINDOWS.
16.3
Der Hilfecompiler HCW
Die Version 4.x des Hilfecompilers benötigt als Betriebssystem mindestens Windows 95, Windows NT 4.0 oder eine neuere Version. In diesem Buch wird nur das Notwendigste behandelt, um eine Hilfedatei erstellen zu können, da eine ausführliche Behandlung des Themas den Umfang dieses Buches sprengen würde. Die folgenden Dateitypen werden vom Hilfecompiler erkannt und für das Erzeugen einer Hilfedatei benötigt:
297
Sandini Bib
*.rtf
Textdatei im Rich Text-Format
*.bmp
Grafikdatei im Bitmap-Format
*.wmf
Grafikdatei im Windows-Metadatei-Format
*.shg
Hypergrafikdatei
*.hpj
Projektdatei des Hilfecompilers
*.hlp
Hilfedatei von Windows (wird vom Hilfecompiler erzeugt)
*.ph
Temporäre Datei, die vom Hilfecompiler erzeugt wird
*.cnt
Inhaltsverzeichnis einer Hilfedatei (wird vom Hilfecompiler erzeugt)
16.3.1
Die Installation des HelpCompilers
Installiert wird der Hilfecompiler, indem das Programm SETUP aus dem Verzeichnis :\COMMON\TOOLS\VB\HCW\ aufgerufen wird. Wurde die Datei HCWSETUP.EXE aus dem Internet geladen, kann der Hilfecompilers installiert werden, indem diese Datei ausgeführt wird. Als erstes wird die Datei in dem aktuellen Verzeichnis entpackt, danach erscheint die Lizenzvereinbarung. Über die Schaltflächen OK und NEXT wechseln Sie in das Fenster, in dem das Zielverzeichnis, in das der Hilfecompilers installiert werden soll, ausgewählt wird. Bei der Software, die auf der Visual Basic CDROM mitgeliefert wird, hat sich jedoch ein kleiner Fehler eingeschlichen. Der Compiler läßt sich nur in Verzeichnissen installieren, die schon auf dem Rechner vorhanden sind. Er kann keine neuen Verzeichnisse anlegen. Um den Compiler also in ein eigenes Verzeichnis zu installieren, muß zunächst mit Hilfe des Explorers das neue Zielverzeichnis angelegt werden. Bei der Frage nach der Installationsart sollte Typical selektiert werden. Zum einen wird der benötigte Speicherplatz hierbei sehr gering gehalten, zum anderen werden dann auch alle benötigten Komponenten installiert.
298
Sandini Bib
Abbildung 16.1: Installationsarten des HelpCompilers
Im nächsten Fenster werden die Komponenten angezeigt, die bei der Installation des Hilfecompilers berücksichtigt werden. Wenn genügend freier Speicher auf der Festplatte vorhanden ist, können alle Optionen installiert werden. Im allgemeinen empfehle ich diese Installationsart. Jetzt wird der eigentliche Installationsvorgang gestartet, indem die gepackten Dateien des Hilfecompilers in das Zielverzeichnis kopiert werden. Wenn die Installation abgeschlossen ist, erscheint die folgende Meldung: Setup has finished installing Help Workshop. Der gesamte Help Workshop mit dem Hilfecompiler ist nun installiert und kann ohne Neustart des Computers verwendet werden. Aufgerufen wird der Hilfecompiler über den Menüpunkt HELP WORKSHOP des Menüs MICROSOFT HELP WORKSHOP. Nach dem Aufrufen des Hilfecompilers wird ein leeres Programmfenster mit einem Tip angezeigt. Ich empfehle, diese Tips regelmäßig zu lesen, da sie immer wieder gute Lösungshinweise für Probleme geben, auf die man beim Erstellen einer Hilfedatei treffen kann.
299
Sandini Bib
Abbildung 16.2: Der Startbildschirm des HelpCompilers (Version 4.x)
16.4
Die Formatierungen des Hilfetexts
Damit der Compiler die erzeugte Datei versteht, also weiß, bei welchen Textteilen es sich um Titel, Verweise oder Themenidentifikationen handelt, werden bestimmte Fußnoten verwendet. In diesem Abschnitt werden die verschiedenen Fußnoten und ihre Bedeutung vorgestellt und erklärt.
300
Zeichen
Bedeutung
Erklärung
#
Identifikationsname
Identifikationsnamen dienen als Zieladresse für Verweise und Begriffserklärungen. Sie dürfen keine Leerzeichen enthalten, jedoch dürfen die Zeichen „.“ (Punkt) und „_“ (Unterstrich) verwendet werden. Auf die Groß- und Kleinschreibung braucht keine Rücksicht genommen zu werden.
$
Titelangabe
Eine Titelangabe ist nicht unbedingt erforderlich, jedoch darf jedem Thema nur ein Titel zugewiesen werden. In der Titelangabe dürfen Sonderzeichen sowie Leerzeichen verwendet werden.
K
Schlüsselwörter
Zu einem Thema dürfen mehrere Schlüsselwörter vergeben werden, die durch ein Semikolon zu trennen sind. Das Schlüsselwort selbst kann ebenfalls aus mehreren Wörtern bestehen.
Sandini Bib
Zeichen
Bedeutung
Erklärung
+
Sequenznummern
Damit zwischen bestimmten Themen durch Vorwärts- und Rückwärtsblättern hin- und hergesprungen werden kann, müssen diese Themen zunächst über einen Sequenznamen zusammengefaßt werden. Der Sequenzname selbst darf keine Leerzeichen enthalten. Eine Sequenznummer, mit der die Reihenfolge der Themen beim Vorwärts- und Rückwärtsblettern definiert wird, wird an den Sequenznamen angehängt und von diesen durch einen Doppelpunkt getrennt. Bei der Vergabe der Sequenznummern ist darauf zu achten, daß genug Zahlen für spätere Erweiterungen freigelassen werden. Eine vollständige Sequenznummer sieht z.B. wie folgt aus: Dateiverarbeitung:0040
Tabelle 16.1: Die verschiedenen Sonderzeichen in der Hilfedatei
16.5
Erstellen einer Hilfedatei
Die Hauptschwierigkeit des Erstellens einer kontextabhängigen Hilfe besteht darin, den Hilfetext zu erstellen. Es kommt nicht selten vor, daß die Entwickler eines Programmes das Erstellen der Texte einer Hilfedatei an Fremdfirmen vergeben. Firmen oder Entwickler, die nicht über das dazu nötige Budget Verfügung, haben zwei Möglichkeiten: 1. selbst das Dokument zu erstellen oder 2. keine Hilfe zu erzeugen.
Die zweite Möglichkeit sollte nicht in Frage kommen, da es bei den heutigen Betriebssystemen und Programmen schon zum Standard gehört, Software nicht ohne Hilfedatei auszuliefern. In einem ersten Schritt muß also der Hilfetext mit einer Textverarbeitung erstellt werden. Dabei ist darauf zu achten, daß jedes Thema von einem anderen über einen harten Seitenumbruch getrennt wird. Auch Grafiken sollten noch nicht eingebunden werden. Das Einbinden der Grafiken wird in einem späteren Abschnitt getrennt behandelt. Wird eine Hilfedatei für ein Programm erzeugt, müssen einige Vereinbarungen zwischen dem Ersteller und dem Anwender der Hilfedatei (in diesem Fall handelt es sich dabei um den Entwickler des Programmes) getroffen werden. Die Schnittstelle zwischen dem Programm, das die Hilfedatei verwendet, und der Hilfedatei selbst bilden die Kontextnummern. Sie definieren die Zieladresse, zu der in der Hilfedatei verzweigt werden soll, wenn die Hilfe von einem Steuerelement aus aufgerufen werden soll.
301
Sandini Bib
Wie Sie sehen, ist das Erstellen einer Hilfedatei mit Querverweisen und Indexeinträgen nicht ganz einfach, da bei der Formatierung einer Hilfedatei sehr viele Konventionen berücksichtigt werden müssen.
16.6
Schreiben der Hilfedatei
Das eigentliche Schreiben der Hilfedatei erspare ich Ihnen, denn das Grundkonzept des Hilfetexts ist in der Datei VERZEICHNIS.TXT abgelegt. Dieser Text muß in eine Textverarbeitung geladen werden, damit er nach den gegebenen Regeln formatiert werden kann.
16.6.1
Einführen eines Titels in die Hilfedatei
Zunächst werden die Titel formatiert, z.B über die Vorgabe von. Schriftart Arial und Schriftgröße 18, und nach jedem Abschnitt wird ein harter Seitenumbruch eingeführt. Dann wird jedem Titel mit der Fußnote „$“ ein interner Titel gegeben. Dieser Titel ist nicht unbedingt notwendig, sollte aber wegen der Vollständigkeit immer mitgeführt werden.
16.6.2
Erzeugen von Querverweisen
Als nächstes werden die Namen vergeben, die als Ziel für die Verweise gelten. Hierfür wird die Fußnote „#“ verwendet. Ein Verweis in dem Dokument wird nun wie folgt eingeführt: Schreiben Sie an die Stelle, an welcher der Verweis im Dokument stehen soll, den Namen des Ziels, der mit der Fußnote „#“ definiert wurde. Es darf sich kein Leerzeichen zwischen dem Text, der als Verweis dient, und dem Namen des Ziels befinden. Jetzt wird der Text, der im Dokument als Verweis verwendet wird, doppelt unterstrichen. Dem Namen des Ziels wird das Zeichenattribut versteckt zugewiesen. In der Hilfedatei wird die Schrift des Textes von dem restlichen Text durch
die Darstellung des Verweises in einer anderen Schriftfarbe und
durch das Attribut unterstreichen
abgehoben. In Abbildung 16.3 wird das Inhaltsverzeichnis zu einer Hilfedatei im Textverarbeitungsprogramm gezeigt. Alle Themen wurden nacheinander aufgelistet und mit den Verweisen auf das jeweilige Hilfethema versehen.
302
Sandini Bib
Abbildung 16.3: Das Inhaltsverzeichnis zu einem Hilfetext
Wird in der fertigen Hilfedatei mit der linken Maustaste auf diesen Verweis geklickt, wird automatisch der Text angezeigt, in dem das Ziel des Verweises definiert wurde.
16.6.3
Erzeugen von Begriffserklärungen
Begriffserklärungen werden dort verwendet, wo ein bestimmter Begriff kurz erläutert werden soll, damit der Hilfetext für den Anwender auch dann verständlich ist, wenn er eine neue Begriffsbezeichnung enthält. Wenn der Anwender die Erklärung zu dem Begriff benötigt, klickt er ihn mit der linken Maustaste an, und die Erklärung wird in einer viereckigen Sprechblase angezeigt.
Abbildung 16.4: Begriffserklärung im Hilfetext
303
Sandini Bib
Der Text, der in der Sprechblase enthalten ist, wird ebenso erzeugt wie zuvor der Zieltext zu den Verweisen. Hinter dem Begriff, dem die Sprechblase zugeordnet werden soll, wird der Name des Zieles, der mit der Fußnote „#“ definiert wurde, geschrieben. Auch hier darf sich wieder kein Leerzeichen zwischen dem Begriff und dem Namen des Verweises befinden. Der gesamte Ausdruck muß wie folgt formatiert sein:
er zu erklärende Begriff wird unterstrichen
der Name, der das Ziel definiert, wird mit dem Attribut versteckt versehen
In der Hilfedatei wird der Begriff über einen unterbrochenen Unterstrich und über eine andere Schriftfarbe vom übrigen Text hervorgehoben.
16.6.4
Erzeugen von Hilfesequenzen
Um zwischen ähnlichen Hilfethemen mit den Schaltflächen > wechseln zu können, werden sogenannte Sequenzen eingeführt. Das Fußnotenzeichen für Sequenzen ist das „+“. In der Fußnote wird der Name der Sequenz vergeben, gefolgt von der Numerierung, mit der die Reihenfolge der Hilfethemen festgelegt wird. In dem Beispielhilfetext sollen die Themen zum Formatieren der Schriftart in eine Sequenz eingebunden werden. Der Name der Sequenz ist Formatierung. Die Sequenznummer beginnt mit der Nummer 010 und wird in Zehnerschritten erhöht. Die Numerierung erfolgt in Zehnerschritten, damit jederzeit ein neues Thema in die bestehende Sequenz eingefügt werden kann. Formatierung:010
16.6.5
Einbinden von Grafiken
Um den Hilfetext etwas aufzulockern, können auch Grafiken in die Hilfedatei eingebunden werden. Es heißt nicht umsonst: Ein Bild sagt mehr als tausend Worte. Bei den Grafiken, die in die Datei integriert werden können, werden die Formate Bitmap und Metafile unterstützt. Es gibt jedoch ein Problem bei der Wahl der Grafikart, da die Hilfedatei auf den unterschiedlichsten Computern funktionieren muß. Dabei ist es egal, ob es sich bei dem Computer um ein Notebook mit Schwarzweißdisplay
304
Sandini Bib
und einer Auflösung von 640*480 Bildpunkten, oder um einen Grafikcomputer mit einem 21-Zoll-Bildschirm und einer Auflösung von 1600*1200 Bildpunkten handelt. Die geringsten Probleme werden von Bitmaps mit einer 16-Bit-Farbtiefe verursacht. Das Einbinden der Grafiken erfolgt eigentlich erst im Hilfecompiler. In der Textverarbeitung wird nur ein Eintrag in geschwungenen Klammern gemacht, um den Ort, an dem die Grafik positioniert wird, zu kennzeichnen. Für die Darstellung der Bilder im Text stehen Kommandos zur Verfügung, die in der Tabelle 16.2 kurz erklärt werden. Kommando
Beschreibung
bmc
Hier wird die Bitmap-Grafik als ein einzelnes Zeichen im Text behandelt. Dies ermöglicht, daß eine Grafik an einer beliebigen Stelle im fließenden Text eingefügt werden kann.
bml
Die Grafik wird linksbündig im Hilfetext ausgerichtet.
bmr
Die Grafik wird rechtsbündig im Hilfetext ausgerichtet.
Tabelle 16.2: Kommandos für Bilder in der Hilfedatei
Wird z.B. eine Grafikdatei mit dem Namen MENUE.BMP in die Hilfedatei eingebunden, kann sie mit den drei genannten Befehlen wie folgt in den Text eingefügt werden: {bmc Menue.bmp} {bml Menue.bmp} {bmr Menue.bmp}
Achtung! Es wird immer nur der Dateiname und niemals der Pfad angegeben, selbst wenn die Datei nicht in dem Verzeichnis liegt, in dem sich die Projektdatei und der Hilfetext befinden. Da diese Datei erst vom Compiler in die Hilfedatei eingebunden wird, wird auch erst in der Projektdatei der Name des Verzeichnisses angegeben, in dem sich die Grafikdatei befindet.
305
Sandini Bib
Abbildung 16.5: Ausschnitt einer Hilfedatei mit der Angabe von Bildern
16.7
Erzeugen einer ersten Hilfe mit dem Help Workshop
Nachdem der Hilfecompiler aufgerufen wurde, erscheint ein leeres Fenster (Abbildung 16.2), in dem ein neues Projekt erzeugt werden kann. Zuerst muß das neue Hilfeprojekt über das Menü FILE | NEW angelegt werden. In dem Fenster in Abbildung 16.6 kann zwischen zwei unterschiedlichen Projektarten gewählt werden.
Abbildung 16.6: Projektauswahl: Hilfedatei oder Inhaltsverzeichnis
Wenn sie an dieser Stelle das Erzeugen eines neuen Hilfeprojekts abbrechen möchten, wird Ihnen das nicht gelingen. Microsoft hat vergessen, der Schaltfläche CANCEL Funktionalität zu hinterlegen.
306
Sandini Bib
Bei der Auswahl Help Project handelt es sich um das Projekt, mit dem die eigentliche Hilfedatei erzeugt wird. Wird die Auswahl Help Contents gewählt, kann ein Inhaltsverzeichnis zu der Hilfedatei generiert werden. Zuerst wird jedoch der Menüpunkt Help Project benötigt. Auf die Auswahl Help Contents gehe ich im Abschnitt „Erstellen des Hilfeindexes“ nochmals genauer ein. Nachdem die Projektart Help Project ausgewählt wurde, müssen das Verzeichnis und der Name der Projektdatei festgelegt werden. Anschließend wird die Projektdatei im Help Workshop angezeigt. Diese Datei steuert die gesamte Generierung der Hilfedatei. Hier werden alle Text- und Grafikdateien, die in der Hilfedatei verwendet werden, aufgelistet. Auch können hier einige Steueroptionen für die Hilfedatei eingestellt werden. Wenn die Generierung der Hilfedatei ohne Fehler abgeschlossen werden konnte, erhält die erzeugte Datei den gleichen Namen, unter dem auch das Projekt gespeichert wurde, jedoch mit der Endung *.hlp.
16.7.1
Einbinden der RTF-Textdatei
Als erstes muß für die Übersetzung der Textdatei in die Hilfedatei die Datei, die übersetzt werden soll, in das Projekt eingebunden werden. Dies geschieht über die Schaltfläche FILES des Help Workshops. Es wird der Dialog TOPIC FILES geöffnet, mit dem die einzubindenden Dateien verwaltet werden.
Abbildung 16.7: Der Dialog Topic Files des Help Workshops
307
Sandini Bib
Über die Schaltfläche ADD können neue Dateien hinzugefügt werden, wenn der Hilfetext auf mehrere RTF-Dateien verteilt wurde. Mit der Taste REMOVE können einzelne Dateien wieder aus dem Hilfeprojekt entfernt werden. Nach dem Bestätigen mit der Taste OK werden die Dateien, die sich im Listenfenster befinden, in das Projekt übernommen. Hierfür wird der eigene Optionsschalter [Files] in der Projektdatei erzeugt.
16.7.2
Einbinden der Grafikdateien
Das Einbinden der Grafikdateien erfolgt auf die gleiche Weise wie das Einbinden der Textdateien, jedoch über die Schaltfläche BITMAP.
Abbildung 16.8: Der Dialog zum Einbinden von Bitmap-Grafiken in den Help Workshop
Mit diesem Dialog werden jetzt die Verzeichnisse festgelegt, in denen nach den Grafiken gesucht werden soll, die in der RTF-Datei angegeben wurden. Hinzugefügt werden die Verzeichnisse mit der Schaltfläche ADD, gelöscht werden sie mit der Schaltfläche REMOVE. Nach dem Bestätigen der Vorgaben mit der Taste OK wird für die Bildverzeichnisse ein neuer Eintrag unter dem Optionsschalter [Options] erzeugt.
16.7.3
Eigenschaften des Hilfefensters
Um die Eigenschaften des Hilfefensters zu verändern, gibt es den Optionsschalter WINDOWS. Wird er ausgewählt, erscheint jedoch zuerst ein Dialog, in dem das Fenster ausgewählt wird, das für die Hilfe konfiguriert werden soll (Abbildung 16.9).
308
Sandini Bib
Abbildung 16.9: Der Dialog Create a window des Help Workshops
Für das Hilfeprojekt des Tool Verzeichnisgröße wird der Fenstertyp Procedure gewählt, und in der Eigenschaft Create a window named wird der Name des zu erzeugenden Fensters eingegeben. Da die Hilfe für das Tool verwendet werden soll, wird der Name Verzeichnisstruktur vergeben. Nach dem Bestätigen der Eingabe mit der Taste OK wird der nächste Dialog (Abbildung 16.10) angezeigt, mit dem die eigentlichen Einstellungen für das Fenster durchgeführt werden.
Abbildung 16.10: Der Dialog Windows Properties des Help Workshops
Da in unserer Hilfedatei auch Sequenznummern vergeben wurden, müssen die Schaltflächen zum Durchblättern der einzelnen Sequenzen eingeschaltet werden. Diese Option wird auf dem Registerblatt BUTTONS des Dialoges WINDOWS PROPERTIES vorgenommen. Damit die Schaltflächen in der Hilfe aktiviert sind, muß die Option Browse aktiviert werden.
309
Sandini Bib
Damit die Hilfedatei jetzt in dem Tool Verzeichnisanalyse verwendet werden kann, müssen noch die ID-Nummern zu jedem Hilfethema vergeben werden, damit jedem Steuerelement ein eigenes Hilfethema zugeordnet werden kann. 16.7.4
Hinzufügen der HelpContext-ID in dem Hilfeprojekt
Damit die ID-Nummern auch ohne Probleme verwendet werden können, muß jede ID gut dokumentiert werden. Zuerst sollten der Hilfetext ausgedruckt und danach die ID-Nummern im Text ergänzt werden. Erst wenn diese Dokumentation erfolgt ist, sollten die ID-Nummern in den Text eingefügt werden. Diese Vorgehensweise gewährleistet eine saubere Programmdokumentation und ermöglicht jedem Programmierer, der sich neu in die Applikation hineindenken muß, eine schnelle Einarbeitung. Die Definition jeder ID im Hilfeprojekt erfolgt über die Schaltfläche MAP im Hilfecompiler. Mit der Schaltfläche ADD wird ein neuer Dialog geöffnet, mit dem eine neue ID erzeugt wird.
Abbildung 16.11: Der Dialog zum Definieren der ID-Nummern der Hilfedatei
In dem Textfeld Topic ID wird der Themenverweis festgelegt, in dem Eingabefeld Mapped numeric value wird die dazugehörige Hilfenummer eingegeben. Bei der verwendeten ID muß es sich um eine vorzeichenlose ganze Zahl handeln. Es sind keine Kommazahlen erlaubt. Deshalb sollte bei der Vergabe dieser IDs immer genug Raum für Zahlen für weitere Themen freigelassen werden. Im allgemeinen wird auch hier eine Zehnerschrittweite verwendet. In der Zeile Comment kann dann noch eine Beschreibung zu der erzeugten Hilfe-ID eingegeben werden. Wenn alle Themen über eine Nummer referenziert werden können, ist die Hilfedatei fertig. In dem Fenster des Hilfecompilers sollten jetzt prinzipiell die Informationen enthalten sein, wie sie in Abbildung 16.12 zu sehen sind.
310
Sandini Bib
Abbildung 16.12: Der Inhalt des Projektfensters mit allen Hilfedefinitionen
Um eine Hilfedatei zu erzeugen, die in ein Programm eingebunden werden kann, muß über die Schaltfläche SAVE AND COMPILE das gesamte Projekt in eine reguläre Hilfedatei übersetzt werden.
Abbildung 16.13: Die Ausgabe des Hilfecompilers nach erfolgreicher Übersetzung
311
Sandini Bib
Nach dem Übersetzungsvorgang gibt der Compiler aus, wo er die erzeugte Datei abgelegt und welche Besonderheiten sie hat. Es wird die Anzahl der Titel, Sprünge, Schlüsselwörter und der eingebundenen Grafiken aufgeführt. Sollten bei der Übersetzung Fehler aufgetreten sein, so werden diese hier ebenfalls beschrieben.
16.7.5
Das Einbinden der Hilfedatei in ein Visual BasicProjekt
Nach der erfolgreichen Übersetzung unseres Hilfeprojekts muß die Hilfedatei noch in das bestehende Projekt eingebunden werden. Hierfür greifen wir auf das Beispielprogramm Verzeichnisanalyse zurück. Als erstes muß in den Projekteinstellungen (PROJEKT | OPTIONEN) auf dem Registerblatt Anwendung die neu erzeugte Hilfedatei in das Feld Hilfedatei eingetragen werden. Danach wird zu jedem Steuerelement in der Eigenschaft HelpContext die ID der Hilfedatei eingetragen, die das zugehörige Hilfethema referenziert. Nach erneutem kompilieren des Projektes steht dem Anwender nun eine kontextsensitive Hilfe zur Verfügung, die durch das Betätigen der Taste (F1) aufgerufen wird und eine kurze Beschreibung zu dem jeweiligen Programmteil liefert.
16.8
Erstellen des Hilfeindexes
Das Erzeugen eines Hilfeindexes für die Datei VERZEICHNIS.HLP ist relativ einfach. Hierfür wird zunächst über das Menü FILE | NEW eine neue Datei vom Typ Help Contents erzeugt. Die Grundlage für die Indexeinträge bilden wieder die IDs, die in der Hilfedatei erzeugt wurden. Zuerst wird jedoch im Eingabefeld Default filename der Name der Hilfedatei eingetragen, zu welcher der Index erzeugt wird. Der Index kann natürlich auch für mehrere Hilfedateien erzeugt werden. Dann sollte hier die Hilfedatei eingetragen werden, auf welche die meisten Referenzierungen verweisen. In dem Eingabefeld DEFAULT TITLE wird der Titel eingetragen, der im Indexfenster in der Titelleiste angezeigt werden soll. Diese Eingaben können auch in einem speziellen Dialog gemacht werden, der über die Schaltfläche EDIT aufgerufen wird.
312
Sandini Bib
16.8.1
Hinzufügen von Indexeinträgen
Mit den Schaltflächen ADD ABOVE und ADD BELOW können neue Indexeinträge erzeugt werden. Mit der Schaltfläche ADD ABOVE wird der neue Indexeintrag vor, mit der Schaltfläche ADD BELOW nach dem aktuell selektierten Eintrag eingefügt. Wird ein neuer Eintrag über eine dieser beiden Schaltflächen hinzugefügt, wird der Dialog EDIT CONTENTS TAB ENTRY geöffnet, in dem die Angaben über den neuen Eintrag festgelegt werden.
Abbildung 16.14: Der Dialog zum Einfügen und Bearbeiten von Indexeinträgen
Es können vier verschiedene Arten von Einträgen gewählt werden.
Heading: Bei diesem Eintrag handelt es sich um eine Überschrift, der wiederum verschiedene Einträge zugeordnet werden können. Bei den untergeordneten Einträgen kann es sich dann ebenfalls um Überschriften handeln. Somit läßt sich mit Hilfe der Überschriften eine beliebige Tiefe im Index erzeugen.
Topic: Hierbei handelt es sich um die einzelnen Einträge, die auf die bestimmten Themen in der Hilfedatei zeigen.
Include: Hiermit können schon existierende Indexdateien in die aktuelle Indexdatei aufgenommen werden.
Nachdem die Art des Indexeintrags festgelegt wurde, müssen noch die Angaben zu den Indexeinträgen vervollständigt werden. Handelt es sich bei dem hinzugefügten Indexeintrag um eine Überschrift (Heading), muß nur der eigentliche Titel des Eintrags ergänzt werden. Handelt es sich um einen Themeneintrag (Topic) muß die Beschreibung Title, unter der das Thema im Index aufgeführt wird, ergänzt werden. Im Feld TOPIC ID muß der Themenverweis angegeben werden, der das Thema in der Hilfedatei identifiziert. Die beiden anderen Felder Help file und Window type müssen nicht zwingend ergänzt werden. Das Feld Help file wird dann benötigt, wenn das Thema, auf das
313
Sandini Bib
der Eintrag verweist, in einer anderen Datei als der, die in der Hilfedatei als Default-Datei definiert wurde. Um einen anderen Index einzubinden, muß im Feld Include File der Dateiname der einzubindenden Indexdatei eingegeben werden.
16.8.2
Das Bearbeiten von Indexeinträgen
Um die verschiedenen Indexeinträge zu modifizieren, stehen vier weitere Schaltflächen zur Verfügung. Mit der Schaltfläche REMOVE können bestehende Indexeinträge gelöscht werden. Damit ein Indexeintrag im Dialog EDIT CONTENTS TAB ENTRY (Abbildung 16.14) bearbeitet werden kann, kann der Dialog entweder über die Schaltfläche EDIT oder mit einem Doppelklick auf den zu bearbeitenden Eintrag geöffnet werden. Über die beiden Schaltflächen MOVE RIGHT und MOVE LEFT kann die Position eines Eintrags in der Baumhierarchie verändert werden. Mit der Schaltfläche MOVE LEFT wird der Eintrag eine Ebene nach oben, mit der Schaltfläche MOVE RIGHT eine Ebene nach unten verschoben. In Abbildung 16.15 ist die Baumstruktur der Indexeinträge für das Projekt Verzeichnisanalyse abgebildet.
Abbildung 16.15: Die Baumstruktur des Hilfeindexes zu MyWord
Beachten Sie, daß beim Vergeben des Index- und des Hilfedateinamens beide Dateien immer denselben Namen tragen und im selben
314
Sandini Bib
Verzeichnis abgelegt sein müssen. Ansonsten wird die Indexdatei nicht von der Hilfedatei gefunden.
315
Sandini Bib
Sandini Bib
17
Datenbankanbindung
In diesem Abschnitt möchte ich auf die Grundlagen der Datenbankanbindung eingehen. Hierbei werden nur die einfachsten Methoden beschrieben, da dieses Gebiet äußerst umfangreich ist. Wer sich eingehender mit der Programmierung und Visual Basic 6.0 und dem Zugriff auf Datenbanken beschäftigen möchte, dem empfehle ich das Buch „Visual Basic 6.0“ so wie Michael Kofler. Auch werde ich nicht weiter auf die Grundlagen der Datenbanken eingehen, da dieses komplexe Gebiet den Rahmen des Buches eindeutig sprengen würde. Als Grundlage für die Beispielprogramme verwenden wir eine einfache Datenbank zur Musikverwaltung. Diese Datenbank wurde mit der Datenbank Access 97 erstellt. In Abbildung 17.1 ist das Datenmodell, mit dem die Musikverwaltung arbeitet, abgebildet.
Das zugrundeliegende Datenmodell
Abbildung 17.1: Relation zur Verwaltung der Musikdaten
Ich möchte nur kurz auf das Datenmodell eingehen. In der Tabelle Interpreten werden alle Interpreten und Gruppen verwaltet. Die Titel der CDs, Musikkassetten usw. werden in der Tabelle Titel erfaßt. Die Titelanzahl eines Interpreten kann zwischen null und n liegen. In der Tabelle Tonträger wird festgelegt, welche Tonträger erlaubt sind, und in der Tabelle Musikstücke werden alle Lieder erfaßt, die auf den Tonträgern der Tabelle Titel aufgezeichnet sind. Um die einzelnen Titel
317
Sandini Bib
der Musikstücke auch nach Musikrichtung qualifizieren zu können, wird die Tabelle Musikrichtung verwendet.
17.1 Die Standard Query Language
Standardabfragesprache
Damit eine Applikation mit einer Datenbank kommunizieren kann, wird eine Standardabfragesprache (Standard Query Language, kurz SQL) verwendet. Diese Sprache ist weitgehend unabhängig vom verwendeten Datenbanksystem. In diesem Abschnitt möchte ich kurz auf die wichtigsten SQL-Befehle eingehen. Hierbei muß ich noch erwähnen, daß die Abfragesprache SQL selber ein so komplexes Thema ist, daß damit Stoff für ein eigenes Buch geliefert wird. Damit die Abfragen, die in diesem Buch verwendet werden, von Ihnen nachvollzogen werden können, habe ich den „Dialekt“ von Access 97 verwendet.
17.2 Das Datenbanktool von Visual Basic 6.0
Erlernen von SQL
Mit dem Erlernen der Abfragesprache SQL ist es wie mit dem Erlernen der meisten Programmiersprachen: Am besten experimentiert man mit ihnen. Die Beispiele in diesem Abschnitt basieren auf der Datenbank MUSIKVERWALTUNG (siehe das Verzeichnis DATENBANK auf der Diskette, die dem Buch beigefügt ist). Um die Beispiele mit Visual Basic selbst nachvollziehen zu können, starten Sie über das Menü ADD-INS|VISUAL DATA MANAGER... das Programm VisData. Nach dem Start erhalten Sie eine leeres Programmfenster. Um mit dem Programm arbeiten zu können, muß zuerst die Verbindung zu einer Datenbank hergestellt werden. Dies geschieht über das Menü DATEI|DATENBANK ÖFFNEN. Hier haben Sie die Möglichkeit, auf die verschiedensten Datenbanktypen zuzugreifen. Um eine Verbindung mit der Musikverwaltung herzustellen, wählen Sie aus dem Menü MICROSOFT ACCESS... die zu öffnende Datei.
318
Sandini Bib
Abbildung 17.2: Das Programm VisData
Jetzt werden zwei weitere Fenster geöffnet. In dem Fenster Datenbankfenster werden alle Tabellen, die sich in der Datenbank befinden, angezeigt.
Abbildung 17.3: Das Datenbankfenster von VisData
Jede Tabelle hat wiederum drei Untertitel. Im ersten werden alle Felder der Tabelle aufgeführt, im zweiten werden alle Indexe und im dritten die Eigenschaften der Felder und der Tabelle dargestellt. Das Fenster SQL-Anweisung (Abbildung 17.4) dient dem Testen von SQL-Anweisungen. Hier können sie eingegeben werden.
319
Sandini Bib
Abbildung 17.4: Das Fenster SQL-Anweisung
Nach dem Betätigen der Schaltfläche AUSFÜHREN wird die aktuelle SQL-Anweisung an die Datenbank gesendet. Zuerst wird jedoch noch in einem weiteren Dialog nachgefragt, ob es sich um eine SQLPassThrough-Abfrage handelt. Beantworten Sie diese Frage mit NEIN. Diese Frage wird bei jeder Abfrage gestellt, was mit der Zeit recht lästig werden kann. Ist die Ausführung erfolgreich gewesen, so erscheint ein weiteres Fenster (Abbildung 17.5) mit dem Ergebnis der ausgeführten Abfrage. Datensatzansicht
Abbildung 17.5: Ergebnisfenster 1 des ViaData
In dem Fenster, daß das Ergebnis der Abfrage darstellt, wird jeder Datensatz einzeln angezeigt. Diese Art der Darstellung ist im allgemeinen nicht sehr geeignet für das Überprüfen von Abfragen, da man die Datensätze nur schlecht miteinander vergleichen kann. Um das Ergebnis der Abfrage besser überprüfen zu können, ist es von Vorteil, die Datensätze tabellarisch darzustellen. Hierfür muß mit der Schaltfläche das Ergebnislayout umgestellt werden. Durch Betätigen dieser Schaltfläche wird das Steuerelement Grid für die Darstellung des SQL-Ergebnisses verwendet (Abbildung 17.6).
320
Sandini Bib
Tabellenansicht
Abbildung 17.6: Ergebnisfenster 2 des VisData
Für die Einführung in das Arbeiten mit dem VisData-Fenster wurden schon einige Befehle der SQL-Syntax verwendet. Im nächsten Abschnitt werden diese Befehle genauer behandelt.
17.2.1
Die Abfragesprache
Die Abfragen dienen in erster Linie dazu, die Informationen, die sich ungeordnet in der Datenbank befinden, nach verschiedenen Kriterien auszuwählen und in Listen zusammenzufassen. Das Ergebnis einer solchen Abfrage ist eine Tabelle, die im Hauptspeicher behalten wird. Solche Tabellen nennt man auch Sichten (englisch Views). Mit einem weiteren Abfragentyp, den sogenannten Aktionsabfragen, kann die Datenbank manipuliert werden. Es können z.B. Datensätze eingefügt, verändert oder gelöscht werden. Diese Art der Abfragen wird aber erst gegen Ende dieses Abschnitts behandelt.
Aktionsabfragen
In der folgenden Übersicht werden die wichtigsten SQL-Anweisungen zum Formulieren einfacher Abfragen behandelt. Die einzelnen Parameter sind in der Reihenfolge, in der sie auch in der SQL-Anweisung vorkommen. Um eine bessere Übersichtlichkeit zu erreichen, werden die SQL-Anweisungen in Großbuchstaben geschrieben. Grundsätzlich ist es aber egal, ob eine Anweisung in Groß- oder Kleinbuchstaben geschrieben wird. Parameter Diese Anweisung ermöglicht es, eine SQL-Abfrage mit allgemeinen Parametern zu formulieren, die erst unmittelbar vor dem Ausführen der Anweisung angegeben werden müssen. Durch diesen Befehl lassen sich SQL-Abfragen allgemeingültig definieren. Er wird hauptsächlich dann verwendet, wenn SQL-Abfragen nicht dynamisch, d.h. nach Bedarf, erzeugt werden, sondern wenn es sich um vorkompilierte Abfragen in der Datenbank handelt. Aber Achtung: Parameter ist eine Jet-spezifische Erweiterung des SQL-Sprachumfangs.
321
Sandini Bib
Select Mit Select werden die Daten aus der Datenbank gelesen. Hierfür werden die Felder, durch Kommata getrennt, aufgezählt. Mit der Anweisung From werden dann die Tabellen angegeben, in denen sich die Felder befinden. Wie die Felder, so werden auch die Tabellen durch Kommata voneinander getrennt. Wenn ein Feld in mehreren Tabellen vorkommt, muß dieses spezifiziert werden, indem der Tabellenname, durch einen Punkt getrennt, vor den Feldnamen gestellt wird. Um aus einer Tabelle alle Felder zu laden, kann das Zeichen * verwendet werden. Distinct und Distinctrow Mit diesen Befehlen kann verhindert werden, daß mehrere Datensätze mit exakt dem gleichen Inhalt angezeigt werden. Sie fassen gleiche Datensätze zusammen. As Dieser Befehl wird verwendet, um Felder oder Tabellen umzubenennen. Durch den Einsatz von As können auch mehrere Felder zu einem neuen zusammengefaßt werden. Beispiel: Interpret & " " & Titel AS Name
From Mit dieser Anweisung werden die Tabellen festgelegt, in denen sich die Felder befinden, die mit der SQL-Anweisung bearbeitet werden sollen. Where In dem Bereich Where werden die Kriterien angegeben, nach denen die Daten aus der Datenbank selektiert werden. Um alle Datensätze einer Tabelle laden zu können, muß die Where-Klausel nicht angegeben werden. Um komplexe Ausdrücke aufbauen zu können, werden weitere Funktionen und Vergleichsoperatoren (Tabelle 17.1) zur Verfügung gestellt.
322
Sandini Bib
Funktion
Beschreibung
NOT
Logische Verneinung.
AND
Logisches UND.
OR
Logisches ODER.
BETWEEN
Prüft, ob der Feldinhalt in einem vorgegebenen Intervall liegt.
=; < ; >; ; =
Vergleichsoperatoren (gleich, kleiner, größer, ungleich, kleiner gleich, größer gleich).
EXISTS
Prüft, ob eine Ergebnistabelle, wenn z.B. eine Unterabfrage verwendet wird, mindestens einen Datensatz enthält.
IN
Prüft, ob ein Feldwert einen Wert enthält, der in einer vorgegebenen Datenmenge enthalten ist. Diese Datenmenge kann z.B. von einer Unterabfrage erzeugt worden sein.
LIKE
Vergleicht alphanumerische Zeichenketten mit vorgegebenen Mustern.
IS NULL
Prüft, ob der Feldwert eines Datensatzes den Wert NULL (nicht 0) enthält.
Tabelle 17.1: Funktionen und Vergleichsoperatoren der WHERE-Klausel
Group by Um Datensätze mit gleichem Feldinhalt zusammenzufassen, wird die Klausel Group by verwendet. Alle Felder, auf die diese Klausel angewendet werden soll, werden mit Kommata getrennt als Liste aufgeführt. Having Mit Having können nochmals Datensätze selektiert werden. Having enthält die Bedingungen für Einträge, die zuvor mit der Klausel Group by gruppiert wurden. In den Abfragen kann Having eine Alternative zu Where darstellen. Order by Mit der Klausel Order by wird angegeben, nach welchen Feldern das Ergebnis sortiert werden soll. Um eine Liste aufwärts zu sortieren, kann das Kommando ASC nachgestellt werden. Zum Abwärtssortieren wird das Kommando DESC verwendet.
323
Sandini Bib
Es existieren noch einige weitere Funktionen, jedoch werde ich hier auf sie nicht eingehen. Für die Abfragen, die in diesem Buch benötigt werden, sind die behandelten Funktionen vollkommen ausreichend.
17.3
Arbeiten mit den SQL-Kommandos
In diesem Abschnitt werden einige Beispiele zum Umgang mit den SQL-Kommandos vorgestellt, um das Arbeiten mit dieser Abfragesprache zu verdeutlichen.
17.3.1 Die ersten SQL-Abfrage
Abfrage aus einer Tabelle
Die einfachste Datenbankabfrage besteht nur aus den Anweisungen Select und From. Mit ihr lassen sich alle Felder (Spalten) einer oder mehrerer Tabellen aus der Datenbank auslesen. Mit dem folgenden Statement werden alle Felder mit den gesamten Datensätzen (Zeilen) der Tabelle Musikstücke aus der Datenbank gelesen. SELECT * FROM Musikstücke
Abbildung 17.7: Ergebnis der einfachen SQL-Abfrage
Um das Ergebnis der Datenbankabfrage auf bestimmte Felder zu beschränken, werden diejenigen Felder, die in dem Ergebnis enthalten sein sollen, hinter dem Select-Statement angegeben. Die Feldnamen werden dabei durch Kommata voneinander getrennt.
324
Sandini Bib
SELECT Nummer, Titel FROM Musikstücke
Bisher wurden immer alle Datensätze aus einer Tabelle gelesen. Um das Ergebnis auf bestimmte Datensätze zu beschränken, wird die Where-Klausel eingeführt.
Datensatzkriterien einführen
SELECT Nummer, Titel FROM Musikstücke WHERE TT = 1
Abbildung 17.8: Abfrage mit eingeschränkten Datensätzen
Durch das Einführen der Where-Klausel wird das Ergebnis der Abfrage eingeschränkt. In diesem konkreten Fall war die Bedingung, daß nur die Datensätze des Albums angezeigt werden, bei denen im Feld TT der Wert 1 enthalten ist. Das Ergebnis ist ein Ausschnitt aus dem gesamten Datenbestand und noch unsortiert. Um die Titel in aufsteigender Reihenfolge zu sortieren, wird die Klausel Order by mit dem Kommando ASC eingeführt.
Sortieren nach bestimmten Feldern
SELECT Nummer, Titel FROM Musikstücke WHERE TT = 1 ORDER BY Nummer ASC
Abbildung 17.9: Ergebnis der sortierten, eingeschränkten SQL-Abfrage
325
Sandini Bib
Es ist nicht zwingend notwendig, daß das Kommando ASC angegeben werden muß. Wird kein Parameter angegeben, wird die Liste immer aufwärts sortiert. Mit der folgenden Anweisung wird die Liste absteigend sortiert: SELECT Nummer, Titel FROM Musikstücke WHERE TT = 1 ORDER BY Nummer DESC
17.3.2
Abfragen über mehrere Tabellen
Alle bisher gemachten Abfragen beschränken sich immer nur auf eine Tabelle. Im allgemeinen reicht dies jedoch nicht aus, da man für eine informative Abfrage Daten aus verschiedenen Tabellen benötigt, um diese gegenüberstellen zu können. Um z.B. feststellen zu können, auf welchem Album welches Lied enthalten ist, müssen die beiden Tabellen Titel und Musikstücke miteinander verknüpft werden. Dies geschieht in der Where-Klausel. SELECT Titel.Titel, Nummer, Musikstücke.Titel FROM Musikstücke, Titel WHERE TT = Titel.ID
Abbildung 17.10: Das Ergebnis der verknüpften Abfrage
326
Sandini Bib
Bei diesem SQL-Statement muß auch darauf geachtet werden, daß die Tabellennamen eindeutig sind. Das Feld Titel kommt jeweils in der Tabelle Titel und Musikstücke vor. Aus diesem Grund muß der Tabellenname, getrennt mit einem Punkt, vor den Feldnamen gesetzt werden, um das jeweilige eindeutig zu identifizieren. Vor das Feld Nummer muß der Tabellenname nicht gesetzt werden, da dieses Feld nur in der Tabelle Musikrichtung vorkommt. Die From-Klausel mußte um den zweiten Tabellennamen erweitert werden, der getrennt durch ein Komma, an den ersten Tabellennamen angehängt wird. In der Where-Klausel wurde festgelegt, nach welchen Kriterien die beiden Tabellen miteinander verbunden werden. Da das Feld TT der Tabelle Musikrichtung die gleiche Bedeutung wie das Feld Id der Tabelle Titel hat, werden die Inhalte dieser beiden Tabellen durch den Operator „=“ miteinander verknüpft. Wie schon in einem Beispiel zuvor, sind die Daten unsortiert. Auch hier kann jetzt mit der Klausel Order by eine Sortierung durchgeführt werden. Die Datensätze sollen aber, anders als im ersten Beispiel, nach mehreren Kriterien sortiert werden. Hierfür müssen beide Felder, durch ein Komma getrennt, hinter der Klausel angegeben werden. Das Feld, welches als erstes aufgeführt wird, wird auch als erstes Kriterium verwendet. Ergibt das erste Kriterium z.B. zwei Datensätze, deren Reihenfolge nicht eindeutig ist, so werden diese nach dem Feld der zweiten Bedingung ausgewertet. Das folgende Statement sortiert die Datensätze zuerst nach dem Namen des Datenträgers und danach die Reihenfolge der Lieder. SELECT Titel.Titel, Nummer, Musikstücke.Titel FROM Musikstücke, Titel WHERE TT = Titel.ID ORDER BY Titel.Titel, Nummer
Vertauschen Sie einmal die beiden Feldnamen der Klausel Order by, um zu beobachten, wie sich das Ergebnis verändert.
327
Sandini Bib
Abbildung 17.11: Sortierte Ausgabe der verknüpften Tabellen
Durch Erweitern der Where-Klausel kann das Ergebnis weiter eingeschränkt werden. Um das Ergebnis auf nur ein Album zu beschränken, muß eine zweite Bedingung eingeführt werden. Die zweite Bedingung wird jetzt nicht durch ein Komma von der ersten getrennt, sondern über den logischen Operator AND mit der ersten verknüpft. SELECT Titel.Titel, Nummer, Musikstücke.Titel FROM Musikstücke, Titel WHERE TT = Titel.ID AND Titel.ID = 2 ORDER BY Titel.Titel, Nummer
In dem zweiten Teil der Where-Klausel wird bestimmt, daß es sich um das Album mit der Id = 2 handeln muß.
17.3.3
Berechnungen mit SQL-Abfragen
Bei den bisherigen SQL-Anweisungen handelte es sich um reine Datenabfragen. Es lassen sich aber auch sogenannte Aggregatfunktionen einsetzen, mit denen Berechnungen aufgrund der Datenfelder durchgeführt werden können. Zu den wichtigsten Funktionen gehören:
328
Sandini Bib
MIN
Wichtige Aggregats-
MAX
funktionen
COUNT
AVG
Diese Funktionen sind natürlich nur sinnvoll, wenn Sie auf mehrere Datensätze angewendet werden, die mit der Klausel Group by zusammengefaßt wurden. Um die Funktionsweise der Aggregatfunktionen besser zu verstehen, soll eine SQL-Anweisung geschrieben werden, mit der sich ermitteln läßt, wie viele Lieder sich auf welchem Album befinden. SELECT Titel.Titel, COUNT(Musikstücke.Titel) FROM Musikstücke, Titel WHERE TT = Titel.ID GROUP BY Titel.TITEL ORDER BY Titel.Titel
Abbildung 17.12: Ergebnis der SQL-Abfrage mit Aggregatfunktion
Am Ergebnis dieser Abfrage fällt auf, daß der Name der ersten Spalte beibehalten wurde, jedoch ist der Name der zweiten Spalte ein vom System gewählter. Bei dieser simplen Abfrage fällt es natürlich nicht schwer herauszufinden, um welchen Wert es sich bei dieser Spalte handeln könnte. Bei komplexen Abfragen, mit mehreren Aggregatfunktionen wird es schwierig, die vom System vergebenen Spaltennamen richtig zuzuordnen. Aus diesem Grund kann ein Feldname mit AS umbenannt werden. Bei der nun folgenden Anweisung handelt es sich um die gleiche Anweisung wie zuvor, mit dem Unterschied, daß der Name des zweiten Feldes der Ergebnistabelle von uns festgelegt wird. SELECT Titel.Titel, COUNT(Musikstücke.Titel) AS Anzahl FROM Musikstücke, Titel WHERE TT = Titel.ID GROUP BY Titel.Titel ORDER BY Titel.Titel
329
Sandini Bib
Durch Verwenden der eckigen Klammern „[]“ bei den Zielnamen können auch komplexere Namen, wie z.B. [Anzahl Lieder auf einem Album]
vergeben werden.
17.3.4
Abfragen zum Manipulieren des Datenbestandes
Mit den bisherigen Abfragen wurden aus den existierenden Tabellen bestimmte Datensätze gelesen, ohne den Datenbestand dadurch zu verändern. Es existieren jedoch auch Abfragen, mit denen der Datenbestand manipuliert werden kann. Folgende Datenbestandsänderungen können durchgeführt werden:
Einfügeabfrage Einfügen neuer Zeilen in eine Tabelle
Aktualisierungsabfrage Ändern von Werten in Zellen einer Tabelle
Löschabfrage Löschen von Tabellenzeilen
Für jede dieser Abfragen steht wiederum ein eigenes SQL-Kommando zur Verfügung. Einfügen von Datensätzen (Insert) Für das Einfügen von Tabellenzeilen steht die Anweisung Insert zur Verfügung. Der Aufbau dieser Anweisung lautet wie folgt: INSERT INTO Tabellenname [(Spaltei [, Spaltej ...])] quelle
Die Elemente in den eckigen Klammern sind nicht zwingend notwendig. Diese Parameter sind die Namen der Spalten, in die die angegebenen Daten eingefügt werden sollen. Sie werden als Zielspalten bezeichnet. Werden keine Zielspalten angegeben, so wird davon ausgegangen, daß in jede Spalte der Tabelle Werte eingefügt werden. Durch ihre Aufzählung wird bestimmt, in welche Spalten und in welcher Reihenfolge die Daten in die Tabelle eingefügt werden. Sind keine Spalten angegeben, wird die Reihenfolge von der Tabellendefinition übernommen.
330
Sandini Bib
INSERT INTO Titel (Interpret, Tontraeger, Titel) VALUES(3, 1, "Neuer Satz")
Mit dieser Anweisung wird ein neues Album in die Tabelle Titel eingefügt. Da es sich bei den Namen des Albums um eine Zeichenkette handelt, wird diese in Hochkommatas angegeben. Es können auch Datensätze eingefügt werden, die über Abfragen aus einer beliebigen Tabelle selektiert worden sind. Hierfür wird dann der Bereich Values durch eine Select-Anweisung ersetzt. INSERT INTO Titel (Interpret, Tontraeger, Titel) SELECT Interpret, Tontraeger, Titel FROM Titel WHERE Titel.Id = 2
Diese Abfrage macht für den Datenbestand keinen großen Sinn, jedoch zeigt sie sehr schön den Aufbau einer Insert-Abfrage, die mit dem Ergebnis einer Select-Abfrage gefüllt wird. Löschen von Datensätzen (Delete) Die Löschabfrage ist vom Aufbau her der Select-Abfrage ähnlich. Da sie aber immer Auswirkung auf die gesamte Datenzeile einer Tabelle hat, werden keine bestimmten Felder hinter der Anweisung aufgeführt Statt dessen folgt gleich die Anweisung From, die den Namen der Tabelle angibt, von der die Datensätze gelöscht werden sollen. Um nicht alle Datensätze der Tabelle zu löschen, müssen, wie auch bei der Select-Anweisung, die Kriterien für die zu löschenden Datensätze mit der Klausel Where festgelegt werden. Mit der folgenden Anweisung wird der zuletzt erzeugte Datensatz wieder gelöscht. Achten Sie aber darauf, daß dieser Wert der Id aus der Where-Klausel in Ihrer Datenbank ein anderer sein kann, als der in der unteren Anweisung verwendete. Bitte wählen Sie hier den Wert, den das System für Ihren letzten Eintrag gewählt hat.
331
Sandini Bib
DELETE FROM Titel WHERE Id = 7
Ändern von Feldern (Update) Mit der Anweisung Update werden Daten in der Tabelle verändert. Im Gegensatz zu den beiden zuvor behandelten Anweisungen Insert und Delete, die immer eine gesamte Zeile ansprechen, können mit der Anweisung Update bestimmte Spalten einer Zeile verändert werden. Um z.B. den Titel des Albums mit dem Wert Id = 3 zu verändern, wird die folgende Anweisung verwendet: UPDATE Titel SET Titel = „Neuer Titel“ WHERE Id = 3
An dieser Stelle möchte ich noch einmal darauf hinweisen, daß die SQL-Sprache weitaus komplexer ist, als in diesem Buch beschrieben. Dies ist wirklich nur ein minimaler Ausschnitt dessen, was diese Sprache leistet. Falls Sie sich verstärkt mit SQL beschäftigen müssen, dann empfehle ich Ihnen das Buch: SQL - Der Standard von Chris J. Date und Hugh Darwen ISBN: 3-8273-1345-7 (Verlag Addison-Wesley)
17.4
Datenbankprogrammierung
In diesem Abschnitt soll behandelt werden, wie man von einem Visual Basic-Programm auf die Datenbank Musikverwaltung zugreifen kann. Wie schon im Abschnitt „Arbeiten mit den SQL-Kommandos“ erwähnt, kann dieses Buch nur eine sehr kleine Auswahl über die Möglichkeiten darstellen, die es für einen Datenbankzugriff gibt. Ich werde hier auf nur zwei Möglichkeiten eingehen, wobei beide die DAO-Bibliothek verwenden. Es existieren jedoch weitaus mehr Schnittstellen (z.B. ODBC, ...). Bei der Auswahl der verschiedenen Möglichkeiten für den Datenbankzugriff kann man davon ausgehen: Je geringer der Aufwand zum Programmieren ist, um so unflexibler ist die Möglichkeit, das Programm (in bezug auf Geschwindigkeit, Ressourcenverbrauch, Anzahl der Verbindungen, ...) zu optimieren.
332
Sandini Bib
17.4.1
DAO-Bibliothek
Bei der DAO-Bibliothek handelt es sich um eine Sammlung von Objekten, Methoden und Eigenschaften, die den Zugriff auf die JET-Datenbank ermöglicht. Der Vorteil von diesem Objektmodell besteht darin, daß es nicht nur unter Visual Basic zur Verfügung steht, sondern daß auch alle anderen Office-Komponenten dieses Modell unterstützen. Die DAO-Bibliothek kann auf zwei unterschiedliche Arten eingesetzt werden. Zum einen kann sie mit datengebundenen Steuerelementen und zum anderen auch isoliert verwendet werden. Im zweiten Fall muß man sich selber um die Anzeige und die Datenänderung kümmern. Dies ermöglicht zwar eine exaktere Kontrolle der Daten, ist aber deutlich aufwendiger zu realisieren. Die DAO-Bibliothek ist in erster Linie für den Zugriff auf JET-Datenbanken optimiert und eignet sich daher auch besonders gut für den Zugriff auf Access-Datenbanken.
17.4.2
Datengebundene Steuerelemente
Das Steuerelement Data
Abbildung 17.13: Das Steuerelement Data
In Visual Basic sind die meisten Steuerelemente in der Lage, die Inhalte einer Datenbank darzustellen. Hierfür muß mit dem Steuerelement Data eine Verbindung zur Datenbank erzeugt werden. Zuvor sollte das Element jedoch einen Namen erhalten. Als Kennung für dieses Steuerelement gelten die Buchstaben dbs, woraus sich der Name dbsAlbum ergibt. Um die Verbindung zu einer Datenbank herzustellen, müssen zwei grundsätzliche Eigenschaften des Steuerelementes eingestellt werden. Zum einen ist es die Eigenschaft Connect. Damit wird schon eine Liste von Datenbanken bereitgestellt, auf die mit Visual Basic direkt zugegriffen werden kann. Diese Eigenschaft kann editiert werden, um die Liste der Datenbanken nach eigenen Wünschen zu erweitern. Für den Zugriff auf eine Access-Datenbank muß hier also der Eintrag Access ausgewählt werden.
333
Sandini Bib
Mit der zweiten wichtigen Eigenschaft DatabaseName wird der Name der Datenbank festgelegt. Wenn Sie mit der Maus auf die Schaltfläche klicken, die beim Aktivieren der Eigenschaft angezeigt wird, erscheint der Dialog (Abbildung 17.14) zum Auswählen einer Datenbankdatei.
Abbildung 17.14: Dialog zum Auswählen der Datei, die die Datenbank enthält.
Die Verbindung zur Datenbank ist somit hergestellt. Es ist jedoch nicht klar, welche Daten der Datenbank dieses Steuerelement repräsentiert. In der Eigenschaft RecordSource kann eine Tabelle aus der Datenbank ausgewählt oder ein SQL-Statement eingegeben werden. Im zweiten Fall erscheint dann der Inhalt des Steuerelementes Data für die anderen Steuerelemente, die das Steuerelement Data verwenden, als eine eigene Tabelle. Als Beispiel wird hier das folgende SQL-Statement eingegeben: SELECT Titel FROM Titel
Darstellen eines Feldes Als nächstes wird ein Textelement auf das Formular aufgebracht. Das Textelement erhält den Namen txtAlbum. Jetzt muß eine Verbindung zwischen dem Textelement und dem Datenelement hergestellt werden. Hierfür wird in der Eigenschaft DataSource der Name des DatenSteuerelementes eingetragen, das die Daten enthält, die mit dem Textelement dargestellt werden sollen. In diesem Beispiel handelt es sich um das Datenelement dbsAlbum. In der Eigenschaft DataField kann ein Feld ausgewählt werden, das in der „Tabelle“ des Daten-Steuerelementes vorkommt. Das Steuerelement dbsAlbum enthält das Feld Titel.
334
Sandini Bib
Wird das Programm jetzt gestartet, so erscheint in dem Textelement der Titel des Albums des ersten Datensatzes. Mit Hilfe der Bildlaufleisten des Daten-Steuerelementes kann in der Tabelle vorwärts und rückwärts geblättert und somit jeder Titel angezeigt werden. Es ist sogar noch mehr möglich. Da in das Textelement auch Eingaben gemacht werden dürfen, können die angezeigten Daten auch modifiziert werden. Jede Veränderung wird dann auch in der Datenbank gespeichert. Durch das Verwenden von mehreren Steuerelementen können somit ganze Datensätze angezeigt und verändert werden.
Modifizieren von Inhalten
Anzeigen von ganzen Listen Wenn aber nicht nur einzelnen Datensätzen gearbeitet werden soll, sondern ganze Listen angezeigt und verändert werden sollen, dann reichen die Standardsteuerelemente nicht mehr aus. Um den Programmieraufwand jedoch auch hierfür so gering wie möglich zu halten, werden drei weitere Steuerelemente zur Verfügung gestellt:
DBList
DBCombo
DBGrid
Für das folgende Beispiel kann das soeben erzeugte Projekt kopiert und das Steuerelement txtAlbum gelöscht werden. Danach muß die neue Komponente DBList hinzugefügt werden. Dies geschieht über das Menü PROJEKT |KOMPONENTEN. Danach muß der Eintrag MICROSOFT DATA BOUND LIST CONTROLS 6.0 ausgewählt werden. Jetzt kann das Element DBList auf dem Formular positioniert werden. Das Steuerelement erhält den Namen lstAlbum. Die Eigenschaften, die schon bei dem Textelement verwendet wurden, stehen hier ebenfalls zur Verfügung, jedoch werden sie für diese Beispiele nicht benötigt. Für die Funktionalität, für die die Steuerelemente verwendet werden, wird die Eigenschaft RowSource verwendet. Hier wird wieder das Steuerelement dbsAlbum ausgewählt. In der Eigenschaft ListField wird die Spalte ausgewählt, die in dem Listenelement dargestellt werden soll. In Abbildung 17.15 ist das Ergebnis des Beispielprogramms dargestellt.
335
Sandini Bib
Abbildung 17.15: Ergebnis des Beispielprogramms mit der ListBox
Listboxen werden im allgemeinen dort verwendet, wo der Inhalt von Tabellen oder Abfragen dargestellt, aber nicht verändert werden soll. Um nun Daten auch modifizieren zu können, wird das Steuerelement DBGrid verwendet. Hier lassen sich vollständige Tabellen anzeigen. Das Steuerelement DBGrid wird ebenfalls über das Menü PROJEKT|KOMPONENTEN. Danach muß der Eintrag MICROSOFT DATA BOUND GRID CONTROL ausgewählt werden. Auch für dieses Beispiel kann wieder das erste Beispielprogramm ohne Textelement verwendet werden. Da es sich aber bei dem Grid um ein Steuerelement handelt, mit dem gleichzeitig
mehrere Spalten und
mehrere Zeilen
dargestellt werden können, wird das SQL-Statement verändert. Das soll einige Felder aller Datensätze aus der Tabelle MUSIKSTÜCKE LADEN. SELECT TT, Nummer, Titel, Musikrichtung FROM Musikstücke ORDER BY TT, Nummer
Bei dem Grid muß jetzt nur eine Eigenschaft angepaßt werden, da die zweite Eigenschaft bei den bisher behandelten Steuerelementen immer eine Beschränkung auf die darzustellende Spalte war. Bei der Eigenschaft, die festgelegt werden muß, handelt es sich um DataSoure. Hier wird wieder das Datenelement dbsAlbum ausgewählt. Wenn das Programm jetzt gestartet wird, werden alle Datensätze und alle im Select-Statement angegebenen Felder dargestellt (Abbildung 17.16).
336
Sandini Bib
Abbildung 17.16: Ergebnis des Select-Statements in einem DBGrid
Es können nun zwar Datensätze verändert werden, aber es können keine hinzugefügt oder gelöscht werden. Das Steuerelement erlaubt diese Aktionen jedoch. Um auch die Möglichkeit zu haben, einen Datensatz zu löschen oder anzuhängen, müssen die beiden Eigenschaften
AllowAddNew und
AllowDelete
jeweils auf den Wert True gesetzt werden. Durch das Ändern der Eigenschaft AllowAddNew auf den Wert True wird eine weitere Zeile an die Liste im Grid angehängt. Sie enthält keine Daten, denn sie dient zur Neuerfassung von Daten. Um einen weiteren Datensatz in der Tabelle einzugeben, setzen Sie die Einfügemarke auf das Feld TT des leeren Datensatzes. Geben Sie jetzt den Wert 3 ein. In dem Moment, in dem der Feldwert akzeptiert wurde, wird ein neuer leerer Datensatz angehängt. Es wurde also ein neuer Titel erfaßt. Um das Beispiel abzuschließen, füllen Sie die restlichen Spalten mit den folgenden Werten: Numer = 6 Titel = "Mein neu erfasster Titel" Musikrichtung = 2
Die Eingabe eines neuen Datensatzes ist nun abgeschlossen. Wenn das Programm jetzt beendet und danach neu gestartet wird, ist der neu erfaßte Datensatz im Datenbestand integriert und wird an der richtigen Position angezeigt.
337
Sandini Bib
Datensatzanzeige aktualisieren
Um nach dem Erfassen eines Datensatzes nicht jedesmal das Programm beenden zu müssen, wird ein weiteres Steuerelement benötigt: eine Schaltfläche. Wird sie betätigt, dann wird eine Methode des Datenelementes dbsAlbum ausgeführt, um den Inhalt des Grids zu aktualisieren. Die folgenden Eigenschaften werden bei der Schaltfläche festgelegt: Name = btnRefresh Caption = "Refresh"
Die Methode zum Aktualisieren der Daten lautet Refresh. Der folgende Programmcode führt die Aktualisierung des Grids durch. Private Sub btnRefresh_Click() dbsAlbum.Refresh End Sub
Nach Betätigen der Schaltfläche BTNREFRESH wird nun der Inhalt der Abfrage neu ermittelt und im Grid angezeigt. Um einen Datensatz zu löschen, müssen alle Felder einer Zeile selektiert werden. Durch Betätigen der Taste (Entf) wird der Datensatz aus der Tabelle und aus der Anzeige entfernt. Hier muß keine Aktualisierung der Datenbankabfrage durchgeführt werden, da sich die Sortierreihenfolge nicht verändert hat. Nachteile der gebundenen Steuerelemente So, wie die Daten bisher angezeigt wurden, sind sie für einen Anwender nicht sehr übersichtlich. Aus diesem Grund soll das SQL-Statement so erweitert werden, daß der Inhalt der Feldern die nur Zahlen enthalten, mit sprechenden Texten ersetzt wird. Das folgende Statement erzeugt den neuen Datenbestand: SELECT Titel.Titel, Nummer, Musikstücke.Titel As Lied, Stil FROM Titel, Musikstücke, Musikrichtung WHERE Titel.Id = Musikstücke.TT AND Musikstücke.Musikrichtung = Musikrichtung.Id ORDER BY TT, Nummer
Das Ergebnis (Abbildung 17.17), das in dem Steuerelement grdTitel ausgegeben wird, ist jetzt sehr viel verständlicher.
338
Sandini Bib
Abbildung 17.17: Vollständige Darstellung der Daten im DBGrid
Der Nachteil, den man durch diese Darstellung in Kauf nehmen muß, ist, daß keine Datensätze mehr
verändert,
gelöscht oder
angehängt
werden können. Wie Sie sehen, ist man sehr schnell an die Grenze der Leistungsfähigkeit dieser Steuerelemente gestoßen. Im nächsten Abschnitt wird die Methode des Datenbankzugriffs beschrieben, bei dem die gesamte Verwaltung programmiert werden muß.
17.4.3
Der Datenzugriff im Programmcode
Um den Datenzugriff aus dem Programmcode zu realisieren, muß als erstes das DAO-Objekt eingebunden werden. Dies geschieht über das Menü PROJEKT|VERWEISE. Aus der Liste des aktiven Fensters wählen Sie den Eintrag MICROSOFT DAO 3.51 OBJECT LIBRARY. Nach Bestätigen mit der Taste Ok steht das DAO-Objekt zur Verfügung.
Einbinden des DAO-Objektes
Das Objekt DBEngine Das oberste Objekt in der DAO-Hierarchie ist das Objekt DBEngine. Es ist Defaultobjekt und muß deshalb in Programmcode nicht explizit gegeben werden. Die beiden wichtigsten Methoden sind
CompactDatabase und
RepairDatabase
339
Sandini Bib
Die Methode CompactDatabase Im allgemeinen sind die JET-Datenbanken größer als ihr eigentlicher Platzbedarf, den sie aufgrund der enthaltenen Daten haben sollten. Dies kommt daher, daß in den Datenbanken darauf verzichtet wird, gelöschte Datensätze tatsächlich auch zu löschen. Der Datensatz wird nicht entfernt, sondern erhält nur eine Markierung, daß er gelöscht ist. Der Grund hierfür ist, die Geschwindigkeitssteigerung die man mit diesem Verfahren erhält. Jedoch behält die Datenbank nicht nur ihren Speicher, wenn ein Datensatz gelöscht wird, sondern sie kann sich auch vergrößern, wenn Änderungen an Datensätzen durchgeführt werden, die zu Änderungen in den Indizes führen. Um eine Datenbank, die in Gebrauch war, wieder auf ihre optimale Größe zu komprimieren, stellt das Objekt DBEngine die Methode CompactDatabase zur Verfügung. Achtung: Beim Verwenden dieser Methode darf die Datenbank nicht benutzt werden. Außerdem muß geprüft werden, ob auf der Festplatte genug freier Platz vorhanden ist, um die alte und die neue Datenbankdatei speichern zu können, denn mit der Methode wird eine optimierte Kopie der alten Datenbank erzeugt. Natürlich kann die alte Datenbank gelöscht werden, wenn der Vorgang erfolgreich abgeschlossen wurde. Bei großen Datenbanken kann das Komprimieren mehrere Minuten in Anspruch nehmen. Der folgende Programmcode komprimiert die Musikdatenbank. Wenn der Vorgang erfolgreich abgeschlossen wurde, wird die alte Datenbankdatei mit dem Befehl Kill gelöscht und danach mit dem Befehl Name umbenannt. Public Sub Compress(Quelle As String) On Error GoTo Err_Compress Compactdatabase Quelle, Quelle + "new" Kill Quelle Name Quelle + "new" As Quelle Exit Sub Err_Compress: Call MsgBox("Datenbank konnte nicht komprimiert werden" & _ Chr(13) & Err.Description, vbOKOnly, & _ "Fehler", Err.HelpFile, Err.HelpContext) Exit Sub End Sub
340
Sandini Bib
Konnte die Datenbank nicht erfolgreich komprimiert werden, wird eine Fehlermeldung ausgegeben. Wenn Sie das Beispielprogramm auf der Diskette ausführen, achten Sie darauf, in welchem Verzeichnis die Datenbank liegt. Voraussichtlich müssen Sie das Verzeichnis anpassen. Dies geschieht im Programmcode durch Doppelklicken auf die Schaltfläche COMPRESS. Die Arbeitsumgebung Workspace Das Objekt Workspace wird dazu verwendet, eine oder mehrere Datenbanken gleichzeitig zu öffnen und zu verwalten. Das Objekt Workspace(0), das automatisch erzeugt wird, gilt auch als Defaultobjekt. Natürlich lassen sich auch mehrere Workspace-Objekte öffnen, um z.B. zwei unabhängige Sitzungen in einer Datenbank zu erhalten. Hiermit würde man gegenüber der Datenbank simulieren, daß zwei unterschiedliche Programme oder zwei Anwender auf die Datenbank zugreifen. In den folgenden Beispielen werden die wichtigsten Workspace-Methoden
CreateDatabase: Erzeugt eine neue Datenbank
OpenDatabase: Öffnet eine bestehende Datenbank
BeginTrans: Definiert den Anfang einer Transaktion
CommitTrans: Läßt die Datenbank die Transaktion ausführen
RollBack: Stellt den Datenbankzustand zum Zeitpunkt von BeginTrans wieder her.
behandelt und vorgestellt. Zuvor muß aber noch das Objekt Database beschrieben werden. Die Datenbank Database Für den Zugriff auf eine bestehende Datenbank wird im Regelfall das Objekt Database verwendet. Um eine bestehende Datenbank zu öffnen, wird die Funktion OpenDatabase wie folgt verwendet: Set Database = OpenDatabase(Filename [, Exclusive] [, Readonly] [, Connect])
341
Sandini Bib
Parameter
Beschreibung
Database
Das Ergebnis dieser Methode repräsentiert die geöffnete Datenbank.
Filename
Hier wird der Dateiname der zu öffnenden Datenbank angegeben.
Exclusive
Mit Exclusive kann festgelegt werden, daß die Datenbank nur von dem aktuellen Programm verwendet werden darf. Voreingestellt ist hier der Wert false. Der Vorteil für das exklusive Öffnen einer Datenbank ist, daß der Zugriff auf die Daten sehr viel schneller erfolgt.
Readonly
Wird auf eine Datenbank nur zum Lesen zugegriffen, dann sollte dieser Parameter auf True gesetzt werden, da die Leseoperationen dann besser unterstützt werden und somit auch schneller sind.
Connect
Hier können zusätzliche Verbindungsoptionen angegeben werden. Muß z.B. ein Paßwort oder eine Benutzerkennung eingegeben werden, so kann dies hier als Parameter übergeben werden.
0 Tabelle 1.2: Die Parameter der Funktion OpenDatabase
Das Objekt Database ermöglicht jetzt den Zugang zu allen weiteren Objekten der Datenbank. Wir werden uns aber nur auf die Methode OpenRecordset zum Erzeugen einer Datensatzliste auf der Basis einer Tabelle beschränken. Hierfür wird dann noch das Objekt Recordset benötigt. Das Objekt Recordset Mit dem Recordset-Objekt wird auf die Datensätze einer Tabelle oder einer Abfrage zugegriffen. Erzeugt wird das Objekt über die Methode OpenRecordset von dem Objekt Database. Das Erzeugen eines Recordset-Objektes geschieht mit dem folgenden Aufruf: Set Recordset = Database.OpenRecordset(Anweisung [, Typ] [, Optionen] [, Zugriff])
342
Parameter
Beschreibung
Recordset
Das Ergebnis der Methode repräsentiert die Datensätze aus einer Tabelle oder einer Abfrage der Datenbank.
Database
Das Objekt, welches auf die geöffnete Datenbank verweist, aus denen die Datensätze geladen werden sollen.
Anweisung
Hier wird die Quelle eingetragen, aus der die Datensätze ermittelt werden. Dabei kann es sich um eine SQL-Anweisung, eine Tabelle oder um eine Abfrage handeln.
Sandini Bib
Parameter
Beschreibung
Typ
Mit dem Typ wird festgelegt, um welche Art von Recordset es sich handelt. Es gibt fünf verschiedene Arten, jedoch wird in diesen Beispielen nur der Typ dbOpenDynaset verwendet, da mit ihm alle benötigten Funktionen realisiert werden können.
Optionen
Hierbei werden die verschiedenen Optionen für den Recordset eingestellt. Es können 11 Parameter miteinander verknüpft werden und so das Arbeiten mit dem Recordset beeinflussen. Für die Beispiele in diesem Buch sind auch diese Parameter nur von geringer Bedeutung.
Zugriff
Hierbei wird festgelegt, wie auf die Daten des Recordsets zugegriffen werden darf. Hier kann z.B. die Beschränkung festgelegt werden, daß die Datensätze nicht verändert (dbReadOnly) werden dürfen.
Tabelle 17.2: Die Parameter der Methode OpenRecordset
17.4.4
Beispiele zum Datenbankzugriff
An dieser Stelle sind alle Objekte, die für den Zugriff auf eine Datenbank nötig sind, besprochen worden. Um die Komplexität der zweiten Methode gegenüber dem Arbeiten mit den datengebundenen Steuerelementen zu zeigen, werden die drei Beispiele
Darstellen eines Datensatzfeldes in einem Textelement,
Füllen eines Listenelementes
und Darstellen von Daten in einem Grid
nochmals entwickelt. Füllen eines Listenelementes Als erstes wird jedoch nicht das Beispiel zum Anzeigen der Daten in einem Textelement, sondern das Füllen eines Listenelementes realisiert. Erzeugen Sie hierfür ein neues Projekt und positionieren Sie ein Listenelement mit Namen LSTALBUM und eine Schaltfläche mit Namen btnFuellen auf das Formular. Als nächstes muß der Verweis Microsoft DAO 3.51 Object Library. über das Menü PROJEKT|VERWEISE. Durch Betätigen der Schaltfläche BTNFUELLEN wird die Verbindung zur Datenbank hergestellt und das Listenelement gefüllt. Für das Füllen des Listenelementes wird die Funktion FillListbox entwickelt.
343
Sandini Bib
Public Function FillListbox(Liste As Object) Dim myDB As Database Dim myRec As Recordset On Error GoTo Err_FillListbox 'Den gesamten Inhalt des Listenelementes löschen Liste.Clear 'Datenbank öffnen Set myDB = OpenDatabase("d:\datenbank\musikverwaltung.mdb") 'Daten aus der Datenbank lesen Set myRec = myDB.OpenRecordset("Select Titel from Titel") 'Wenn Daten aus der Datenbank gelesen werden konnten If Not (myRec Is Nothing) Then 'Solange nicht alle Daten gelesen wurden While Not myRec.EOF 'Füge das aktuelle Datenelement in die Liste ein Liste.AddItem myRec.Fields(0) & "" 'Setze den Zeiger auf den nächsten Datensatz myRec.MoveNext Wend End If 'Datenbank wieder schliessen myDB.Close 'Arbeitsbereich wieder freigeben Exit Function Err_FillListbox: Call MsgBox("Fehler beim Füllen der Datenbank aufgetreten." _ & Chr(13) & _ Err.Description, vbOKOnly, "Fehler", Err.HelpFile, Err.HelpContext) Exit Function End Function
In diesem Beispiel braucht kein Objekt vom Typ Workspace definiert zu werden, da der Default Workspace verwendet wird. Das Füllen des Listenelementes geschieht in einer While-Schleife. Zuerst wird geprüft, ob noch ein Datensatz existiert oder ob das Ende des Datensatzergebnisses erreicht wurde. Danach wird der Inhalt aus dem ersten Feld des aktuellen Datensatzes in das Listenelement eingefügt. Der Zugriff auf das Datensatzelement erfolgt in diesem Fall über den Index, er kann aber auch über die Angabe des Feldnamens erfolgen. Liste.AddItem myRec.Fields![Titel] & ""
344
Sandini Bib
Der leere String wird immer angehängt, damit kein Fehler auftritt. Sind keine Daten in dem Feld enthalten, enthält es den Wert NULL. Durch Anhängen der leeren Zeichenkette wird dieser Nullwert dann in einen String umgewandelt. Jetzt ist der Datensatz bearbeitet worden, und mit der Anweisung MoveNext wird der nächste Datensatz aktiviert. Außer MoveNext werden noch die folgenden Methoden eines Objektes vom Typ Recordset unterstützt:
MoveFirst: Springt auf den ersten Datensatz in dem aktuellen Objekt.
MovePrevious: Springt auf den Datensatz vor dem aktuellen Objekt.
MoveNext: Springt auf den nächsten Datensatz in dem aktuellen Objekt.
MoveLast: Springt auf den ersten Datensatz in dem aktuellen Objekt.
FindFirst : Springt auf den ersten Datensatz, der das Kriterium erfüllt.
Wichtige Eigenschaften des Recordset-Objektes
MyRec.FindFirst "Titel = Live CD2"
Ändern von Feldern in Datensätzen In diesem Beispiel soll wieder ein Textelement (txtAlbum) mit dem Feldinhalt eines Datensatzes gefüllt werden. Wird aber in dem Beschriftungselement eine Änderung gemacht, soll die Änderung auch auf der Datenbank durchgeführt werden. Um zwischen den Datensätzen zu wechseln, wird eine Bildlaufleiste verwendet (hscAlbum). Dim myDB As Database Dim myRec As Recordset Dim myCounter As Long Private Sub Form_Load() On Error GoTo Err_Form_Load 'Verbindung zu DB herstellen Set myDB = OpenDatabase("d:\datenbank\musikverwaltung.mdb") 'Daten aus Tabelle lesen Set myRec = myDB.OpenRecordset("select * from Titel") 'Wenn die Tabelle Daten enthalten hat If Not (myRec Is Nothing) Then 'Inhalt des ersten Datensatzes in Tabelle schreiben txtAlbum.Text = myRec![Titel] 'Springe auf den letzten Datensatz myRec.MoveLast 'den oberen Bereich der Bildlaufleiste festlegen
345
Sandini Bib
hscAlbum.Max = myRec.RecordCount 'den unteren Bereich der Bildlaufleiste festlegen hscAlbum.Min = 1 'Springe auf den ersten Datensatz myRec.MoveFirst 'Zeiger auf aktuellen Datensatz myCounter = 1 End If Exit Sub Err_Form_Load: Call MsgBox("Fehler beim Füllen der Datenbank aufgetreten." & _ Chr(13) & Err.Description, vbOKOnly, "Fehler", _ Err.HelpFile, Err.HelpContext) End End Sub Private Sub hscAlbum_Change() 'Wenn mindestens ein Datensatz existiert If myCounter > 0 Then 'Bereite den aktuellen zum ändern vor myRec.Edit 'Weise dem Datenfeld den neuen Wert zu myRec![Titel] = txtAlbum.Text 'Aktualisiere die Datenbank myRec.Update 'Wenn der nächste Datensatz angezeigt werden soll If hscAlbum.Value > myCounter Then myRec.MoveNext myCounter = myCounter + 1 txtAlbum.Text = myRec![Titel] 'Wenn der vorhergehende Datensatz angezeigt werden soll ElseIf hscAlbum.Value < myCounter Then myRec.MovePrevious myCounter = myCounter - 1 txtAlbum.Text = myRec![Titel] End If End If End Sub
Beim Laden des Formulares muß die Bildlaufleiste initialisiert werden. Aus diesem Grund wird die Anzahl der ausgelesenen Datensätze mit der Funktion RecordCount ausgelesen. Damit diese Funktion aber einen richtigen Wert liefert, muß der Datensatzzeiger zuerst auf den letzten Datensatz bewegt werden. Wird das nicht gemacht, dann liefert die Funktion ein falsches Ergebnis. In diesem konkreten Fall liefert die Funktion den Wert 1.
346
Sandini Bib
Nachdem die Bildlaufleiste mit der Anzahl der Datensätze initialisiert wurde, kann der Datensatzzeiger wieder auf den ersten Datensatz bewegt werden. Im Ereignis Click der Bildlaufleiste wird dann die eigentliche Datenaktualisierung durchgeführt. Mit der Methode Edit des Objektes RecordSet wird die Aktualisierung vorbereitet. Jetzt werden die Daten für alle anderen Anwender gesperrt. Nach dem Verändern der Daten werden sie mit der Methode Update in die Datenbank geschrieben, und die Sperrung der Daten wird aufgehoben. Darstellen eines Recordsets in einem Grid In dem letzten Beispiel zum Arbeiten mit Datenbanken sollen die Daten in einem Grid (grdRecord) dargestellt werden. Hierfür werden zuerst die Daten mittels eines Select-Statements gelesen und danach so in das Grid gefüllt, daß jedes Datenelement jeweils einem Feld in dem Grid zugewiesen wird. Dieses Laden erfolgt beim Initialisieren des Formulares (frmGrid).
Füllen des Grids
Option Explicit Dim myDB As Database Dim myRec As Recordset Private Sub Form_Load() On Error GoTo Err_Form_Load Dim i As Integer Dim Zeile As Integer 'Verbindung zu DB herstellen Set myDB = OpenDatabase("d:\datenbank\musikverwaltung.mdb") 'Daten aus Tabelle lesen Set myRec = myDB.OpenRecordset("select Id, Nummer, Titel " &_ "from Musikstücke") 'Wenn die Tabelle Daten enthalten hat If Not (myRec Is Nothing) Then grdRecord.Cols = myRec.Fields.Count myRec.MoveLast grdRecord.Rows = myRec.RecordCount + 1 myRec.MoveFirst Zeile = 0 grdRecord.Row = Zeile 'Titelfelder des Grids beschriften For i = 1 To myRec.Fields.Count grdRecord.Col = i - 1 grdRecord.Text = myRec.Fields(i - 1).Name & "" Next
347
Sandini Bib
'Schreibe alle Datensätze ins Grid While Not myRec.EOF 'Inhalt des Datensatzes in Tabelle schreiben Zeile = Zeile + 1 For i = 1 To myRec.Fields.Count grdRecord.TextMatrix(Zeile, i - 1) = _ myRec.Fields(i - 1) & "" Next myRec.MoveNext Wend End If Exit Sub Err_Form_Load: Call MsgBox("Fehler beim Lesen der Datenbank aufgetreten" & _ Chr(13) & Err.Description, vbOKOnly, "Fehler", _ Err.HelpFile, Err.HelpContext) End End Sub
Das Grid wird jetzt mit allen Feldern und Spalten des Recordsets gefüllt, jedoch können die Spaltenbreiten nicht an den Inhalt vom Anwender angepaßt werden. Modifizieren des Zellinhaltes eines Grids
Hierfür muß der Eigenschaft AllowUserResizing der Wert flexResizeRows zugewiesen werden. Im nächsten Schritt muß die Eingabe in das Steuerelement ermöglicht werden. Hierfür müssen die beiden Ereignisse KeyDown und KeyPress mit folgendem Programmcode modifiziert werden: Private Sub grdRecord_KeyDown(KeyCode As Integer, Shift As Integer) Select Case KeyCode Case vbKeyDelete grdRecord.Text = "" End Select End Sub Private Sub grdRecord_KeyPress(KeyAscii As Integer) Select Case KeyAscii Case 8 'Backspace If Len(grdRecord.Text) > 0 Then grdRecord.Text = Left(grdRecord.Text, _ Len(grdRecord.Text) - 1) End If Case Is > 31 grdRecord.Text = grdRecord.Text & Chr$(KeyAscii) End Select End Sub
348
Sandini Bib
Natürlich kann die Funktionalität, die durch das Betätigen der Taste ausgeführt wird, beliebig erweitert werden. Z.B. kann das Kopieren von Daten aus Zellen in die Zwischenablage und umgekehrt noch realisiert werden. Wir wollen uns nun aber weiter auf das Modifizieren der Daten beschränken. Hierfür wird eine Schaltfläche (BTNSAVE) eingeführt, mit der die Daten aus dem Grid in die Datenbank gesichert werden, und eine zweite Schaltfläche (BTNRESUME), um die Änderungen nach dem letzten Speichern wieder rückgängig machen zu können.
Speichern der modifizierten Daten
Private Sub btnSave_Click() Dim i As Integer Dim Zeile As Integer myRec.MoveFirst For Zeile = 1 To grdRecord.Rows - 1 myRec.Edit For i = 1 To grdRecord.Cols - 1 myRec.Fields(i) = grdRecord.TextMatrix(Zeile, i) Next i myRec.Update myRec.MoveNext Next Zeile End Sub
Der Programmcode, der entwickelt werden muß, um den Inhalt eines Recordsets in einem Grid darzustellen, ist ein Vielfaches größer, als wenn ein datengebundenes Grid verwendet wird. Der Vorteil dieser Programmierung ist jedoch, daß man die Daten vollständig im Programmcode kontrollieren und somit modifizieren kann. Wie ich eingangs schon mehrfach erwähnt habe, ist das Programmieren mit Datenbanken ein weitaus größeres Gebiet, als es in diesem Buch behandelt wurde. Dieser kleine Einstieg soll eine Grundlage bilden, auf der nun problemlos aufgebaut werden kann.
349
Sandini Bib
Sandini Bib
A
Anhang
Inhalt der Diskette
A.1
Verzeichnis
Beschreibung
Dateien
Ein Beispielprogramm für das Arbeiten mit Dateien.
Testdatei DragDrop Gesicht
Zwei sequentielle Dateien; für das Beispielprogramm. Verzeichnis mit zwei Programmen; für die Programmierung von Drag and Drop. Programm, in dem ein Gesicht auf einem anderen Steuerelement abgelegt wird und seinen Gesichtsausdruck ändert.
Bilder
Beinhaltet die Grafiken, die in diesem Beispielprogramm mit der Methode Drag and Drop verschoben werden.
Mülleimer
Aufwendigeres Drag and Drop-Beispiel, in dem unterschiedliche Reaktionen auf ein Steuerelement realisiert werden.
Bilder
Beinhaltet die Grafiken, die in diesem Beispielprogramm mit der Methode Drag and Drop verschoben werden.
Editor
Beispiel zur Programmierung mit mehreren Fenstern, die steuerelement-Übergreifend arbeiten.
Ereignisse
Verzeichnis mit Programmen, die auf Ereignisse reagieren.
Ereignis
Zwei unabhängige Ereignisse, die sich trotzdem blockieren.
MouseMove
Grundlage eines Mal-Programms. Feststellen der Mausposition und der betätigten Tasten.
Error
Programm zum Erstellen einer Tabelle mit allen Fehlermeldungen von Visual Basic.
Grafik
Verzeichnis mit Programmen; zur Grafikprogrammierung.
Fraktal
Berechnen und Zeichnen eines fraktalen Apfelmännchens.
RGB_Farben
Programm zur Darstellung und Berechnung der RGBFarben.
Menue
Ein Beispielmenü, das mit dem Visual Basic-Menüeditor erstellt wurde.
351
Sandini Bib
Verzeichnis
Beschreibung
Rechner
Das Beispielprogramm: Stackrechner.
Rekursion
Verzeichnis mit Beispielprogrammen für rekursive Berechnungen.
Fakultaet
Berechnung der Fakultät.
Fibonacci
Berechnung der Zahl Fibonacci.
Steuerelemente CheckBox
Das Kontrollkästchen.
ComboBox
Das Kombinationsfeld.
CommonDial
Die Standarddialoge: Datei öffnen/schließen, Farben, Schrift, Drucken.
ListBox
Das Listenfeld.
Listenfelder
Die Listenfelder: Laufwerk, Verzeichnis und Datei.
MDI
Arbeiten mit MDI-Fenstern.
Optionbutton
Das Optionsfeld.
PictureBox
Das Bildfeld-Steuerelement.
Register
Die Registerblätter.
ScrollBar
Die Bildlaufleisten.
Shape
Das Figuren-Steuerelement.
TextBox
Das Texteingabeelement.
Timer
Der Zeitgeber.
Tools
Verzeichnis mit nützlichen Tools und einem Logik-Spiel.
Dir_Groesse
Ermittlung des benötigten Speichers eines Verzeichnisses mit Unterverzeichnissen.
Master
Das Logikspiel MasterMind.
Bilder Random
352
Kurze Beispielprogramme zu den Steuerelementen.
Benötigte Bilder für Drag and Drop. Auflösen eines Gleichungssystems mit dem Zufallsgenerator.
Vorlage
Grundlagenprojekt für sehr viele Beispiele.
Zahl_123
Zahlenspiel. Jede beliebige Zahl endet in der Zahl 123.
Sandini Bib
A.2
Standardbefehle
Befehl
Beschreibung
Abs
Berechnet den Absolutwert einer Zahl.
AddItem
Datensatz zu einem Listenelement hinzufügen.
ChDir
Vergleichbar mit dem Befehl cd von DOS. Er wechselt das aktive Verzeichnis.
ChDrive
Wechselt das aktive Laufwerk.
Circle
Zeichnen eines Kreises oder einer Ellipse.
Clear
Den Inhalt eines Listenelements löschen.
Close
Eine geöffnete Datei schließen.
CurDir
Liefert als Ergebnis das aktive Verzeichnis eines Laufwerks zurück.
DoEvents
Gibt die Steuerung an das Windows-Betriebssystem ab, damit andere aufgetretene Ereignisse verarbeitet werden können.
Dir
Vergleichbar mit dem Befehl dir unter DOS. Er liefert als Ergebnis alle Dateien des Verzeichnisses zurück.
DrawMode
Legt das Aussehen von Zeichnungselementen fest (z.B. Linien).
DrawStyle
Legt das Aussehen der Linien für Zeichnungselemente fest.
DrawWidth
Legt die Stärke der Linie für Zeichnungselemente fest.
End
Beendet die Ausführung des Programms.
Error
Erzeugt einen Fehler im Programmcode.
FileLen
Ermittelt die Größe einer Datei.
Format
Umwandlungsfunktion. Formatiert einen Ausdruck in eine andere Darstellung um.
Get
Lesen aus einer Datei.
Input
Lesen aus einer Datei.
LCase
Wandelt Großbuchstaben eines Strings in Kleinbuchstaben um.
Left, Left$
Schneidet einen Ausdruck nach einer bestimmten Anzahl von Zeichen rechts ab.
Line
Zeichnet eine Linie auf ein Steuerelement oder ein Formular.
Load
Lädt ein Formular in den Hauptspeicher.
Lof
Ermittelt die Länge einer Datei.
Ltrim, Ltrim$
Entfernt alle Leerzeichen, die auf der linken Seite zu Beginn der Zeichenkette stehen.
Mid, Mid$
Schneidet einen Ausdruck nach einer bestimmten Anzahl von Zeichen links und rechts ab.
353
Sandini Bib
354
Befehl
Beschreibung
MkDir
Vergleichbar mit dem Befehl md unter DOS. Er erzeugt ein neues Verzeichnis.
On Error Goto
Fehlerbehandlungsroutine.
Open
Öffnet eine Datei zum Lesen oder Schreiben.
Preserve
Erweitert den bereitgestellten Speicher eines Feldes, ohne den Inhalt der Felder zu löschen.
Print
Ausgabe in eine Datei.
Put
Schreiben in eine Datei.
Randomize
Initialisiert den Zufallsgenerator.
RemoveItem
Datensatz eines Listenelements löschen.
Resume
Wiederaufnahme des Programmablaufs nach dem Auftreten eines Fehlers bei dem Befehl, der den Fehler ausgelöst hat.
Resume Next
Wiederaufnahme des Programmablaufs nach dem Auftreten eines Fehlers sowie Ignorieren des Befehls, der den Fehler ausgelöst hat.
Right, Right$
Schneidet einen Ausdruck nach einer bestimmten Anzahl von Zeichen links ab.
RmDir
Vergleichbar mit dem Befehl rd unter DOS. Entfernt ein leeres Verzeichnis.
Rnd
Liefert eine Zufallszahl.
Rtrim, Rtrim$
Entfernt alle Leerzeichen, die auf der linken Seite zu Beginn der Zeichenkette stehen.
Time, Time$
Liefert als Ergebnis die aktuelle Systemzeit zurück.
UCase
Wandelt Kleinbuchstaben eines Strings in Großbuchstaben um.
Unload
Entfernt ein Formular aus dem Hauptspeicher.
Sandini Bib
A.3
Glossar
Eintrag
Bedeutung
ASCII
American Standardcode for Information Interchange.
Betriebssystem
Enthält alle Programme, die die Ausführung der Benutzerprogramme und ihre Verwaltung auf Systemebene steuern.
Break-Point
Siehe Haltepunkt.
Bitmap
Grafikdatei-Format.
Carrige Return
Wagenrücklauf mit Zeilenvorschub.
Compiler
Übersetzer, der eine Programmiersprache in einen für den Prozessor verständlichen Maschinencode überträgt.
Desktop
Grafische Betriebssystemoberfläche.
Designzeit
Siehe Entwurfszeit.
Endlosschleife
Eine Programmschleife, deren Abbruchbedingung nie erfüllt wird.
Entwicklungsumgebung
Programm zum Erstellen und Verwalten von Applikationen.
Entwurfszeit
Zeit, in der das Programm entwickelt, in der also direkt am Programmcode gearbeitet wird.
FiFo
„First in, first out“: Der Listeninhalt, der als erster in eine Liste eingetragen wurde, wird als erster ausgelesen.
Abbildung A.1: Arbeitsweise einer FiFo-Liste Haltemodus
Modus zum Testen des Programms. Es können einzelne Werte der Ausdrücke angezeigt oder jeder Programmschritt einzeln ausgeführt werden.
Haltepunkt
Zeile im Programmcode, an welcher der Programmablauf unterbrochen wird.
Interpreter
Ein Interpreter erklärt dem Prozessor jeden einzelnen Befehl, d.h. das Programm wird nicht in den Maschinencode übersetzt (siehe Compiler), sondern nur Zeile für Zeile interpretiert.
355
Sandini Bib
Eintrag
Bedeutung
LiFo
„Last in first out“: Der Listeninhalt, der als letzter in die Liste eingetragen wurde, wird als erster ausgelesen. Der Stackspeicher eines Computers arbeitet nach diesem Prinzip.
Abbildung A.2: Arbeitsweise einer LiFo-Liste
356
Linefeed
Siehe Zeilenvorschub.
Metafile (auch erweiterte)
Ein Grafikdatei-Format.
Modal
Ist ein Fenster im Status modal, sind alle anderen Fenster des Programms zwar sichtbar, aber nicht mehr aktiv.
Programmlaufzeit
Phase, in der die entwickelte Applikation im Betriebssystem oder der Entwicklungsumgebung ausgeführt wird.
Prozessor
Kernstück eines Computers. Er bildet einen Teil der Zentraleinheit und arbeitet die einzelnen Prozesse ab.
Pseudocode
Sprache, um die Grundstrukturen der strukturierten Programmierung zu formulieren
Wagenrücklauf
Wenn bei einem mechanischen Drucker der Druckkopf wieder auf die Ausgangsposition gesetzt wird.
Zeilenvorschub
Modus, um bei einer Datenausgabe auf die nächste Zeile wechseln zu können.
Zwischenablage
Ein Speicherbereich, der für den Datenaustausch von Programmen zur Verfügung gestellt wird.
Sandini Bib
A.4
Von Visual Basic 5.0 verwendete Dateitypen
Dateiendung
Beschreibung
.bas
Basic-Moduldatei.
.cls
Klassen-Moduldatei.
.ctl
Benutzer-Steuerelementdatei.
.ctx
Binäre Benutzer-Steuerelementdatei.
.dca
Pufferdatei eines aktiven Designers.
.dep
Abhängigkeitsdatei des Installationsassistenten.
.dob
Benutzerdokument-Formulardatei.
.dox
Binäre Benutzerdokument-Formulardatei.
.dsr
Designerdatei.
.dsx
Binäre Designerdatei.
.frm
Formulardatei.
.frx
Binäre Formulardatei.
.log
Protokolldatei für Ladefehler.
.oca
Steuerelement-Klassenbibliothekspuffer.
.pag
Eigenschaftenseite-Datei.
.pgx
Binäre Eigenschaftenseite-Datei.
.res
Ressourcendatei.
.swt
Visual Basic-Installationsassistent-Vorlagendatei.
.tlb
Remote-Automatisierungs-Klassenbibliotheksdatei.
.vbg
Visual Basic-Gruppenprojektdatei.
.vbl
Benutzersteuerelement-Lizenzdatei.
.vbp
Visual Basic-Projekt.
.vbr
Remote-Automatisierungs-Registrierungsdatei.
.vbw
Visual Basic-Projektarbeitsbereich.
.vbz
Assistent-Startdatei.
357
Sandini Bib
A.5
Zeichentabellen
!
"
#
$ % &
'
(
)
*
+
, - .
/
0
1
2
3
4 5 6
7
8
9
:
;
< = >
?
@
A
B
C
D E F
G
H
I J K L M N
O
P
Q R S T U V
W
X
Y Z [ \ ] ^
_
d
e
f g h i j
` a b c
p
q
w
k l m n o
r s t u v x y z { |
}
~
a
¡ ¢
£
¤
¥ ¦ § ¨ © ª
«
Y
¬ ® ¯ ° ±
²
³
´ µ ¶ · ¸ ¹
º
»
¼ ½ ¾ ¿ À Á
Â
Ã
Ä Å Æ Ç È É
Ê
Ë
Ì Í Î Ï Ð Ñ
Ò
Tabelle A.1: Der DOS-Zeichensatz (in Schriftart Terminal)
358
Sandini Bib
!
"
# $ %
& '
(
)
*
+ ,
-
.
/
0 1
2
3 4 5
6
7
8 9
:
;
< =
>
?
@ A
B
C D E
F
G
H I
J
K L M
N O
P Q
R
S T U
V W
X Y
Z
[
\
`
b
c
d e
a
]
^
_
f
g
j
k
l
m n
o
p q r
s
t
u
v
w
x
y
z
{
|
}
~
‚
¶
„
… †
ˆ
‰ Š ‹
Œ
‘
’
“
”
–
—
˜
™ š
›
œ
Ÿ
¡
¢
£ ¤ ¥
¦
§
¨
© ª
« ¬ -
® ¯
°
± ²
³
¶
¸
¹
» ¼ ½ ¾ ¿
h i
º
´
•
µ
‡
·
À Á Â Ã Ä Å Æ
Ç È É Ê Ë Ì
Í
Î
Ï
Ð Ñ Ò Ó Ô Õ Ö x Ø Ù Ú Û Ü Ý Þ ß à á â
ã ä å
æ ç
è é ê
ë ì
í
î
ï
ð ñ ò
ó ô õ
ö
÷
ø ù ú
û ü ý
þ
Tabelle A.2: Der ANSI-Zeichensatz von Windows (in Schriftart Arial)
!
359
Sandini Bib
!
∀ #
∃ % & ∋
(
)
∗
+
,
−
.
/
0 1
2
3
4
5
6
7
8 9
:
;
< =
>
?
≅ Α Β Χ ∆ Ε Η Ι
ϑ
Φ Γ
Κ Λ Μ Ν Ο
Π Θ Ρ
Σ
Τ Υ ς
Ω
Ξ Ψ Ζ
[
∴ ]
⊥
_
α β
χ
δ
ε
φ
γ
η ι
ϕ
κ
λ µ
ν
ο
π θ
ρ
σ
τ
υ
ϖ ω
ξ ψ ζ
{
|
}
∼
ϒ ′
≤
⁄
∞ ƒ
♦ ♥ ♠ ↔ ← ↑ °
♣
→ ↓
± ″
≥
× ∝ ∂
÷ ≠ ≡
≈
…
•
↵
ℵ ℑ ℜ ℘ ⊗ ⊕ ∅
∩ ∪ ⊃ ⊇ ⊄ ⊂ ⊆ ∈ ∉ ∠ ∇ ∏ √ ¬ ∧ ∨
⇔ ⇐ ⇑
◊ 〈
∑
〉
∫
⌠ ⌡
Tabelle A.3: Die Sonderzeichentabelle mit der Schriftart „Symbol“
360
⋅
⇒ ⇓
Sandini Bib
! " )
# $ % & ' (
* + , - . /
0
1 2 3 4 5 6 7 8 9 : ; < = > ? @
A B C
D E F G H I J K L M N O P Q R S T
U V W X
Y Z [ \ ] ^ _
`
a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
¡ ¢ £ ¤ ¥ ¦
§ ¨ © ª « ¬ ® ¯ ° ± ² ³ ´
µ
¶ · ¸ ¹ º » ¼ ½ ¾ ¿ c À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö
×
Ø Ù Ú Û
Tabelle A.4: Die Sonderzeichentabelle mit der Schriftart „WingDings“
!
361
Sandini Bib
✁ ✂ ✃ ✄ ☎ ✆ ✇
✈ ✉ ☛ ☞ ✌
✍ ✎ ✏
✐ ✑ ✒ ✓ ✔ ✕ ✖ ✗ ✘ ✙ ✚ ✛ ✜ ✝
✞
✟
✠ ✡ ✢ ✣ ✤ ✥ ✦ ✧ ★ ✩ ✪ ✫ ✬ ✭ ✮ ✯ ✰ ✱ ✲ ✳ ✴ ✵ ✶ ✷ ✸ ✹ ✺ ✻ ✼ ✽ ✾ ✿
❀ ❁ ❂
❃ ❄ ❅ ❆ ❇ ❈ ❉ ❊ ❋ ● ❍ ■ ❏ ❐ ❑ ❒ ▲ ▼ ◆ ❖ ◗ ❘
❙
❚
❛
❜
❝ ❞
❡ ❢
❣
❤ ❥ ❦ ❧
♣ ♦ ♥ ♠ ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ❶ ❷ ❸ ❹ ❺ ❻ ❼ ❽ ❾ ❿ ➀ ➁ ➂ ➃ ➄ ➅ ➆
➇ ➈ ➉ ➊ ➋ ➌ ➍ ➎ ➏ ➐ ➑ ➒ ➓ ➔ ✇ ↔ ↕ ➘ ➙ ➚ ➛ ➜ ➝ ➞ ➟ ➠ ➡ ➢ ➣ ➤ ➥ ➦ ➧ ➨ ➩ ➪ ➫ ➬ ➭ ➮ ➯
➱ ➲ ➳ ➴ ➵ ➶ ➷
➸ ➹ ➺ ➻ ➼ ➽ ➾ Tabelle A.5: Die Sonderzeichentabelle mit der Schriftart „Monotype Sorts“
362
Sandini Bib
S
Stichwortverzeichnis
Anzeigesteuerelement Appearance Applikation entwickeln
Befehle ChDir ChDrive Close CurDir EOF FileLen FreeFile Get GOTO Input Kill Line Line Input LoadFile Mid, Mid$ MkDir Name Open Print Put Resume RGB RmDir Rnd Write Befehler
MousePointer Befehlstabelle BeginTrans Beispieldatenbank
Berechnungen mit Zufallsgenerator
Algorithmus Gleichungen
Gleichungsystem Lösung Programmoberfläche Bildfeldsteuerelement eigene Zeichnungen Bildlaufleisten Breitensuche Button
CAB-Dateien Cancel Caption CheckBox Click ComboBox CommitTrans CommonDialog CompactDatabase Connect CreateDatabase
DAO-Bibliothek , DAO-Objekt Data DatabaseName
363
Sandini Bib
DataField DataSource RecordSource Datei Datei öffnen/speichern Eigenschaften Dateien Beispiel Ende formatieren Größe Kanalnummer laden lesen löschen öffnen schließen schreiben Tab Umbenennen Dateien siehe Datei Dateiendungen
Dateilistenfeld Datenbankabfragen Datenbankanbindung
Datenbankprogrammierung Datengebundene Steuerelemente Datenmodell
Datensätze Ändern Einfügen Löschen Datentypen selbstdefinierte umwandeln
DBCombo DBEngine DBGrid , AllowAddNew
DataSoure Refresh DblClick DBList ListField RowSource Debugger Destruktor Drag and Drop Drucken Eigenschaften
364
Edit
Eigenschaft Tag Text ToolTipText Visible Eigenschaften Appearance Caption TabIndex (Name) Ereignisse , Click DblClick GotFocus KeyDown KeyUp Load LostFocus MouseDown MouseMove MouseUp Err Error
Farben QBColor RGB RGB_Farbenbeispiel Farbpalette Eigenschaften Fehlerbehandlung
Err Error On Error Resume Vorgehensweise
Fehlercodetabelle erstellen Felder Benutzerdefinierter Indexbereich Dynamische Felder Eindimensional Feldinhalt löschen Indexbereich ermitteln Mehrdimensionale Felder ,
Sandini Bib
neu dimensionieren selbstdefinierte Datentypen statische Felder Fenster Anzeigen ausblenden Debugger Eigenschaftsfenster entladen Formularfenster Hauptfenster laden mehrere Programmcodefenster Programmfenster Projektfenster Property ToolBox Werkzeugfenster FiFo Figurensteuerelement FindFirst Fokus erhalten verlieren Form Formular Appearance AutoRedraw BackColor Caption General Hide Load MDIChild mehrere Name Show Tag ToolTipText Unload Frame Funktionen
Call-by-Reference Call-by-Value FUNCTION - END FUNCTION
GotFocus Goto Grafik Farben Farbwert berechnen Grundlagen zur Ausgabe Line Programmierung Grundlagen
HelpCompiler Installation Hilfe Begriffserklärungen Datei erstellen Datei schreiben Eigenschaften Grafiken einbinden Helpcompiler Helpcompiler HCW
HelpContext-ID Hilfeindex Hilfesequenzen Hilfesystem kontextsensitiv Querverweis Text formatieren Titel einführen Hilfesystem
Image Installation Visual Basic
Installation VisualBasic Benutzerdefiniert Standard Systermvoraussetzungen Installationsassistent
CAB-Optionen Dateien Installationsdatei generieren Installationsdisketten erstellen Installationstitel Menüeinträge Optionen Projekt festlegen
365
Sandini Bib
starten Startmenü Zielverzeichnis bestimmen Zielverzeichnisse zusätzliche Treiber
Jet-Datenbanken
KeyDown Klasse Datenelemente
Eigenschaften Elementfunktionen
erzeugen hinzufügen Methoden
Kombinationsfeld Konstanten Beispiele Konstruktor Kontrollkästchen Name Tag ToolTipText Value
Label Laufwerklistenfeld LiFo Linie Liniensteuerelement ListBox Listenfeld alle Einträge löschen ColCharacter Datensatz eintragen Datensatz löschen ListCount Listindex Name Tag Text ToolTipText Load LostFocus
366
MasterMind
Programmcode Programmoberfläche
Spielregeln
MDI Formular Caption MDIChild Name Tag Meldungen anzeigen
Menüdesigner Checked Enabled Shortcut Shortkey Visible Menüleiste Add-Ins Ansicht Ausführen Bearbeiten Datei Debuggen Extras Projekt Methoden Microsoft Rich TextBox Control 5.0. Mid, Mid$ MouseMove Beispiel MousePointer MoveFirst MoveLast MoveNext MovePrevious
Objekt Eigenschaften Objektorientierung ODBC On Error OpenDatabase Option Explicit OptionButton Optionsfeld
Sandini Bib
Caption Name Tag ToolTipText
PictureBox Programmbeispiele Bildfeldsteuerelement ,
das erste Kombinationsfeld Listenfeldsteuerelement Optionsschalter Stack-Taschenrechner Texteingabeelement Zahlenloch Programmentwicklung
aufrufen
Programmierung Ablaufgesteuert
Ereignisgesteuert Programmstrukturen Konstanten Variablen Projekte Aufbau
Prozeduren
Call-by-Reference Call-by-Value SUB - END SUB
QBColor
Rahmensteuerelement RecordCount Recordset Registerblättersteuerelement Caption CurrentTab Name TabCount TabsPerRow Tag Registrierdatenbank DeleteSetting GetAllSettings
GetSetting HKey_Classes_Root HKey_Current_Config HKey_Current_User HKey_Dyn_Data HKey_Lokal_Machine HKey_User SaveSetting Zugriff RepairDatabase Resume RGB RGB-Farbenbeispiel RollBack RTF-Steuerelement ,
SelBold
SelItalic
SelStrikethru
SelUnderline
RTF-Steuerelement siehe Microsoft Rich TextBox Control 5.0.
Schaltfläche Schleifen DO - Schleife FOR - Schleife WHILE - Schleife , Schriftart Eigenschaften ScrollBar Shape SQL Aktionsabfragen Dialekt VisData SQL-Abfragen Aggregatsfunktionen Aktualisierungsabfrage As ASC Berechnungen DESC Distinct Distinctrow Einfügeabfrage From Group by Having Löschabfrage
367
Sandini Bib
Order by Parameter Select selektieren sortieren Vergleichsoperatoren verknüpfte Tabellen Where SQLPassThrough SSTab Standard Query Language Standarddialogbefehle ShowColor , ShowFont
ShowHelp
ShowOpen
ShowPrinter
ShowSave
Standarddialoge ,
Datei öffnen/speichern
Drucken Hilfe Schriftart Standardsteuerelemente hinzufügen Statusleiste Steuerelemente aufbringen Steuerelementfarben Systemvoraussetzungen
Tag TextBox Texteingabeelement , Textelement Alignment Border Style Caption Tiefensuche Timer Tools ,
MasterMind
Verzeichnisgröße
Update
368
Variablen Variablendeklaration Deklarationsbeispiel Kurzschreibweise Variant Variablentypen Boolean Byte Currency Date Double Integer Long Object Single String Variant , Verpackungs und weitergabeassistent
Verpackungs und Weitergabeassistent siehe Installationsassistent Verzeichnisgröße
Programmcode Programmoberfläche
Verzeichnislistenfeld Verzeichnisse erzeugen löschen wechseln Verzweigungen IF-THEN-ELSE SELECT CASE Visual Basic Grundlagen Programmoberfläche starten Visual Data Manager Datenbankfenster Ergebnisfenster SQL-Anweisung
WindowState Workspace
Zeichenkette Mid, Mid$
Sandini Bib
Zeichentabellen Zeitgeber Enabled Intervall Name Tag Ziehen und Fallenlassen DragDrop DragOver mit Reaktion
verschieben Ziehen und Fallenlassen siehe Drag and Drop Zufallsgenerator , (Name)
369