Objektorientiertes Programmieren
Transcrição
Objektorientiertes Programmieren
Fachbereich 12 – Maschinentechnik Fachgebiet 5 Mess-, Steuerungs- und Regelungstechnik Einführung in Objektorientiertes Programmieren (Object-Pascal) mit Borland Delphi Prof. Dr.-Ing. U. Pietzsch Wintersemester 1999 ,QKDOWVYHU]HLFKQLV *XQGOHJHQGHV 2EMHNWXQGHUHLJQLVRULHQWLHUWH3URJUDPPLHUXQJ 2EMHNWH 1.2.1 Eigenschaften (Properties) ........................................................................................... 4 1.2.2 Ereignisse (Events)....................................................................................................... 4 1.2.3 Methoden (Methods)..................................................................................................... 4 3URJUDPPHQWZLFNOXQJ 1.3.1 Strukturierung ............................................................................................................... 5 1.3.2 Arbeitsverzeichnis erstellen .......................................................................................... 5 $UEHLWHQPLW'HOSKL 'LH$UEHLWVIHQVWHU 2.1.1 Die Werkzeugleiste ....................................................................................................... 5 2.1.2 Das Formular ................................................................................................................ 6 2.1.3 Der Objektinspektor ...................................................................................................... 6 2.1.4 Das Quelltext-Fenster ................................................................................................... 7 2.1.5 Das Projekt ................................................................................................................... 8 'LH.RPSRQHQWHQSDOHWWH 2.2.1 Standard ....................................................................................................................... 9 2.2.2 Zusätzlich...................................................................................................................... 9 2.2.3 Win32.......................................................................................................................... 10 2.2.4 System ........................................................................................................................ 10 2.2.5 Datenzugriff................................................................................................................. 11 2.2.6 Datensteuerung .......................................................................................................... 11 2.2.7 Dialoge........................................................................................................................ 11 0HQXIXQNWLRQHQ 2.3.1 Datei............................................................................................................................ 12 2.3.2 Bearbeiten................................................................................................................... 12 2.3.3 Suchen........................................................................................................................ 13 2.3.4 Ansicht ........................................................................................................................ 13 2.3.5 Projekt......................................................................................................................... 14 2.3.6 Start ............................................................................................................................ 14 2.3.7 Tools ........................................................................................................................... 15 'DV$UEHLWHQDXIGHP)RUPXODU 6WUXNWXUHLQHU8QLW (UHLJQLVVH 6SUDFKHOHPHQWH =HLFKHQVDW] 5HVHUYLHUWH:|UWHUXQG6WDQGDUGEH]HLFKQXQJHQ $ULWKPHWLVFKH2SHUDWRUHQ 6SUDFKHOHPHQWH 3.4.1 Funktionen und Prozeduren........................................................................................ 22 3.4.2 Variablen und Datentypen .......................................................................................... 22 3.4.3 Integer-Typen.............................................................................................................. 23 3.4.4 Real-Typen ................................................................................................................. 23 3.4.5 Boolean-Typen............................................................................................................ 24 2 3.4.6 Strings......................................................................................................................... 24 3.4.7 Arrays.......................................................................................................................... 25 3.4.8 Typen .......................................................................................................................... 25 3.4.9 Records....................................................................................................................... 26 3.4.10 Zeiger........................................................................................................................ 26 3.4.11 Dynamische Arrays................................................................................................... 27 3.4.12 Variant....................................................................................................................... 28 3.4.13 Mengen ..................................................................................................................... 28 3.4.14 Konstanten................................................................................................................ 28 3.4.15 Kommentare ............................................................................................................. 29 6FKOHLIHQDQZHLVXQJHQ 3.5.1 Repeat-Schleife .......................................................................................................... 29 3.5.2 While-Schleife ............................................................................................................. 30 3.5.3 For-Schleife................................................................................................................. 30 3.5.4 Break&Continue.......................................................................................................... 32 %HGLQJXQJHQXQG9HU]ZHLJXQJHQ 3.6.1 if-Anweisung ............................................................................................................... 32 3.6.2 case-Anweisung.......................................................................................................... 32 6SUXQJIXQNWLRQHQ 'HOSKL)XQNWLRQVNDWDORJ $ULWKPHWLNXQG0DWKHPDWLN 'DWHLYHUZDOWXQJ 'DWXPXQG=HLW 'LDORJH )RUPDWLHUXQJXQG.RQYHUWLHUXQJ 6SHLFKHUYHUZDOWXQJ 6WULQJRSHUDWLRQHQ =HLJHU$GUHVVLHUXQJXQG6RQVWLJHV 0HWKRGHQ *UDILNHQ 'DWHQEDQNDQZHQGXQJHQ $EODXIVWHXHUXQJ 7RROV 'HEXJJHU 'DWHQEDQNREHUIOlFKH %LOGHGLWRU /LWHUDWXU 3 *XQGOHJHQGHV 2EMHNWXQGHUHLJQLVRULHQWLHUWH3URJUDPPLHUXQJ Der grundlegende Unterschied zwischen einem herkömmlichen Programm unter DOS und einem Windowsprogramm besteht im wesentlichen in folgendem: • Im DOS-Programm werden die Befehle VHTXHQWLHOO abgearbeitet; d.h. Schritt für Schritt hintereinander. Die Kommunikation mit der Peripherie erfolgt dabei direkt über das Anwendungs-Programm. • Unter Windows laufen alle Aktionen REMHNWXQGHUHLJQLVRULHQWLHUW ab. Eine streng vorgegebene Reihenfolge für die Eingabe und Abarbeitung der Befehle gibt es nicht mehr. Für jede Aktivität des Anwenders ist ein Programmteil zuständig, das weitgehend unabhängig von den anderen Programmteilen agiert und in dem Moment in Aktion tritt, in dem er aufgerufen wird. Kurz hintereinander aufgerufene Programmteile werden entsprechend der Aufeinanderfolge in einer Liste abgearbeitet. Die Kommunikation mit der Peripherie erfolgt via 'Message-Handling' über das Betriebssystem. 2EMHNWH Objekte sind ganz allgemein die Elemente der Bedienoberfläche, denen wiederum Eigenschaften (1.3.1), Ereignisse (1.3.2) und Methoden (1.3.3) zugeordnet sind. Beschränkt man sich auf die visuelle Benutzerschnittstelle, auf die eine grafische Bedienoberfläche besonders zugeschnitten ist, so hat man es in Delphi mit folgenden Objekten zu tun: • )RUPXODUH (Fenster) Windows-Fenster, in denen eine Delphi-Anwendung (Pascal-Programm) ausgeführt wird. In einem Formular können weitere untergeordnete Formulare, Komponenten (siehe unten), Text und Grafik enthalten sein. • • .RPSRQHQWHQ Komponenten sind vorgefertigte Objekte, die z.B. als Schaltflächen (Button), Bildlaufleisten (Scrollbar), Auswahlfenster (Listbox) usw. auftauchen. VRQVWLJH (Screen, Printer, Clipboard,...) Der Informationsfluß innerhalb des Gesamtprogramms entsteht durch Kommunikation der Objekte untereinander, d.h. durch das Versenden von Botschaften (Messages). Eine solche Botschaft besteht normalerweise aus dem Namen einer Methode (→ Absatz 1.2.3), die das aufgerufene Objekt bei Empfang ausführen soll. (LJHQVFKDIWHQ3URSHUWLHV ... sind die $WWULEXWH von Objekten, wie z.B. die Höhe (Height), die Breite (Width) und die Farbe (Color). Jedes Objekt verfügt über einen eigenen Satz von Eigenschaften, die teilweise nur zur Entwurfszeit oder nur zur Laufzeit veränderbar sind. (UHLJQLVVH(YHQWV ... sind 1DFKULFKWHQ, die vom Objekt empfangen werden und damit die eigentliche Schnittstelle zum Betriebssystem darstellen. So ruft z.B. das Anklicken eines Objektes mit der Maus das OnClick-Ereignis hervor. Aufgabe des Delphi-Programmes ist es, auf alle Ereignisse gemäß den Vorgaben des Programmierers zu reagieren. Realisiert wird die dann folgende Aktion in sogenannten Ereignisbehandlungsroutinen, die anwendungsspezifisch erstellt werden. 0HWKRGHQ0HWKRGV ... sind die im Objekt definierten )XQNWLRQHQ XQG 3UR]HGXUHQ, die gewissermaßen das Ver4 halten beim Eintreffen einer Nachricht bestimmen. So erzeugt z.B. die LineTo-Methode eine Linie auf der Zeichenfläche (Canvas) eines Objektes. Eine Methode kann auch das Verhalten des Objekts bei einem Mausklick oder einer Tastatureingabe definieren. Im Unterschied zu • den (LJHQVFKDIWHQ, die die VWDWLVFKHQ Eigenschaften eines Objekts liefern, • bestimmen die 0HWKRGHQ die G\QDPLVFKHQ Fähigkeiten. 3URJUDPPHQWZLFNOXQJ 6WUXNWXULHUXQJ Sequentiell strukturierte Programme erfordern als erste Aktivität das Erstellen eines Programmablaufplans und Überlegungen zur Gestaltung der unterschiedlichen Schnittstellen. Delphi erfordert in dieser Beziehung ein Umdenken und erlaubt eine systematische Programmentwicklung in drei Stufen: 1. %HGLHQREHUIOlFKH visuell entwerfen, indem die benötigten Komponenten in der gewünschten Form auf dem Bildschirm plaziert werden. 2. 2EMHNWHLJHQVFKDIWHQ zuweisen; d.h. in welcher Form die plazierten Komponenten beim Start des Programms erscheinen sollen. 3. (UHLJQLVEHKDQGOXQJHQ schreiben. Diese Stufe beinhaltet die eigentliche anwendungsorientierte Programmierung und legt fest, wie die verwendeten Komponenten auf das Eintreten eines Ereignisses oder einer Botschaft reagieren sollen. $UEHLWVYHU]HLFKQLVHUVWHOOHQ Vor dem Erstellen eines neuen Projektes empfiehlt es sich, für dieses Projekt einen eigenen 2UGQHU anzulegen, um die mit dem Projekt verknüpften Dateien in übersichtlicher Form zusammenzuhalten. Auf diese Weise ist es später leicht möglich, über den Dateimanager oder eine ähnliche Windows-Funktion z.B. eine Sicherungskopie von einem Projekt zu erstellen. $UEHLWHQPLW'HOSKL 'LH$UEHLWVIHQVWHU Nach dem Starten von Delphi wird der Bildschirm so aufgebaut, wie er in der letzten Sitzung verlassen worden ist. Beim ersten Starten werden das die für die Programmerstellung wichtigsten vier Fenster sein, die in den folgenden Abschnitten vorgestellt werden sollen. 'LH:HUN]HXJOHLVWH Wichtigstes Arbeitsfenster unter Delphi mit Bereitstellung der zur Verfügung stehenden 0HQX IXQNWLRQHQ, einer 6\PEROJUXSSH, in der die wichtigsten Menufunktionen über ein Symbol aufgerufen werden können, und der .RPSRQHQWHQSDOHWWH, die die Programmierbausteine für eine Programmentwicklung beinhaltet. Menuzeile Häufig benutzte Menupunkte In Karteikarten angeordnete Komponenten-Palette 5 'DV)RUPXODU Das Formular, das Delphi mit dem Namen Form1 vorschlägt, ist das zur Laufzeit sichtbare Fenster der Anwendung, in dem alle anderen sichtbaren Komponenten zusammengefaßt sind. Die wichtigsten Eigenschaften des Formulars sind: WindowState Position FormStyle ob das Formular nach dem Programmstart in der aktuellen Größe, als Symbol oder Bildschirm füllend aufgebaut werden soll. Lage und Größe des Formulars auf dem Bildschirm. BorderStyle wie das Formular sich später auf der Oberfläche verhalten soll, wenn andere Formulare (Windows-Anwendungen) angewählt werden. ob es zur Laufzeit in der Größe veränderbar ist BorderIcons welche Standardschalter zur Größenregulierung in der Titelleiste erscheinen Name Der Variablenname mit dem das Formular angesprochen wird Caption Der Texteintrag in der Kopfzeile des Fensters 'HU2EMHNWLQVSHNWRU Im Objektinspektor können die (LJHQVFKDIWHQ der Objekte eingestellt werden, die auf das Formular plaziert worden sind, und er enthält die Verwaltung der zu den Objekten gehörenden (UHLJQLVEHKDQGOXQJVURXWLQHQ, d.h. wie und in welcher Form das Objekt auf ein Ereignis oder eine Botschaft zu reagieren hat. In der Zeile direkt unterhalb der Titelleiste sind durch einen Doppelpunkt getrennt, der 1DPH und der 7\S des Objektes (Variable) dargestellt (z.B. Form1: TForm1). Durch Anklicken des dreieckigen Pfeilsymbols kann eine /LVWH mit allen zum Projekt gehörenden Objekten aufgeklappt werden. Name Typ Liste Durch das Anklicken eines Objektes in der Liste wird dieses mit seinen Eigenschaften und Ereignissen im Fenster des Objekt-Inspektors eingeblendet. Für die Einstellungen der Eigenschaften stehen drei wesentliche Eingabefenster zur Verfügung: • 6WDQGDUGHLQJDEHIHQVWHU wie "Caption" oder "ClientHeight", in die alfanumerische Strings oder Zahlen eingegeben werden können. Abgeschlossen wird eine Eingabe, wenn die Zeile mit der Tastatur (↑↓) oder einem Mausklick auf eine andere Zeile verlassen wird. • 'URS'RZQ)HQVWHU wie "ActiveControl", die es ermöglichen, einen Eintrag aus einer vorbereiteten Liste auszuwählen. Zum Aufklappen der Liste muß der nach unten weisende Dreieckpfeil angeklickt werden. • .RQVWDQWHQOLVWHQ wie "+BorderIcons". Die Aktivierung der Konstantenliste durch Doppelklicken auf das "+"-Symbol blendet eine leicht eingerückte Liste ein, aus der mittels Mausklick ein Eintrag selektiert werden kann; in der aufgeklappten Liste wird das "+"-Symbol durch ein "–"-Symbol ersetzt. Durch Doppelklick auf das "–"-Symbol kann die Liste wieder geschlossen werden. 6 • 0HQXGLDORJH wie "+Font". Einfaches Anklicken des Fensters macht einen durch drei Punkte gekennzeichneten Schalter sichtbar. Das Anklicken des Schalters öffnet ein unter Windows bekanntes Dialogfenster, in dem umfangreichere Einstellungen vorgenommen werden können. 2QOLQH+LOIHIUMHGH(LJHQVFKDIWGXUFK$QNOLFNHQGHU(LJHQVFKDIWXQG DQVFKOLHHQGHV'UFNHQGHU)7DVWH 'DV4XHOOWH[W)HQVWHU Die Unit, für die Delphi hinter der Bezeichnung 'unit' den Namen "Unit1" vorschlägt, ist ein Fenster, in dem der Quelltext der Anwendung enthalten ist. Es enthält eine Liste der eingebundenen Dateien, die zur Handhabung des Formulars erforderlich sind, und eine Beschreibung des (noch leeren) Formulars Form1. Die Einstellung der im Editor verwendeten Farben erfolgt über den Menupunkt: Tools / Umgebungsoptionen... / Farben Neue Prozeduren oder Funktionen werden von Delphi unmittelbar vor der Direktive "end." am Ende der Unit eingefügt. Während ein Formular immer an eine Unit gekoppelt ist, kann eine Unit auch eigenständig, ohne eine dazugehörendes Formular existieren. Sehr häufig ist dies der Fall bei Bibliotheken oder sonstigen Unterprogrammsammlungen. Hinweise: 'LH %H]HLFKQXQJ 8QLW GDUI QLFKW LP 4XHOOWH[W GHU 8QLW JHlQGHUW ZHUGHQ VRQGHUQ PXEHUGLH0HQXIXQNWLRQ'DWHL6SHLFKHUQXQWHUYHUJHEHQZHUGHQ 'HU$XVGUXFN^5')0`GDUIQLFKWHQWIHUQWZHUGHQGDHUGHQXQEHGLQJWHUIRUGHUOL FKHQ+LQZHLVDXIGLH9HUNQSIXQJPLWHLQHP)RUPXODUHQWKlOW 7 'DV3URMHNW Nach dem Speichern eines Projektes wird man feststellen, daß die eigene Anwendung nicht nur aus der Formulardatei und der Quelltext-Unit besteht, sondern daß Delphi noch eine Reihe anderer Dateien angelegt hat. Project1.dpr Project1.dsk Projektdatei, in der die zum Projekt gehörenden Dateien in einer Liste eingetragen sind. Die Zuordnung von zueinander gehörenden Formularen und Units ist dieser Liste eindeutig zu entnehmen. Die Projektdatei sollte vom Programmierer niemals manuell editiert werden. Datei zur Verwaltung der aktuellen Desktop-Oberfläche. Mit Hilfe dieser Datei kann ein Projekt nach seinem Öffnen in derselben Form aufgebaut werden, wie es verlassen worden ist. Project1.exe Das compilierte und gelinkte ausführbare Programm. Das Programm kann auch auf Rechnern laufen, auf denen Delphi nicht installiert ist. Project1.res Die Windows-Ressourcendatei, in der die Komponenten (z.B. Formular, Button, Bildlaufleiste) verwaltet werden. Project1.opt Die für das Projekt eingestellten Optionen (Compiler, Verzeichnispfade, Editor) Unit1.dcu Die compilierte und in Maschinencode vorliegende Quelltextdatei, die vom Compiler aus der Unit1.pas erstellt worden ist. Unit1.dfm Die Formulardatei zu Form1 Unit1.pas Die Quelltextdatei zu Unit1 Die vom Programmierer zu bearbeitenden Dateien sind in der obigen Liste grau hinterlegt dargestellt. 'LH.RPSRQHQWHQSDOHWWH ... stellt eine Reihe an YRUJHIHUWLJWHQ2EMHNWHQ zur Verfügung, die die Grundlage des Anwenderprogramms darstellen. Die Komponenten sind entsprechend ihren Funktionen gruppenweise auf Karteikarten untergebracht, deren Bedeutung oder Wichtigkeit im Prinzip von links nach rechts abnimmt. Eine Komponente wird in zwei Schritten folgendermaßen auf das Formular übertragen: 1. Durch das Anklicken mit der Maus wird sie für die Übertragung DNWLYLHUW. Der aktive Zustand wird durch eine helle Hinterlegung des Symbols angezeigt. 2. Durch das Anklicken einer bestimmten Stelle auf dem Formular wird die markierte Komponente genau an dieser Stelle DEJHOJW. Name und Typ der Komponente erscheinen im Kopffenster (oberste Zeile) des Objektinspektors, in dem die Eigenschaften sofort eingestellt werden können. Nach dem Anklicken im Formular wird die Hervorhebung in der Komponentenleiste wieder deaktiviert. Die für den Standardgebrauch wichtigsten Komponenten werden auf den folgenden Seiten in Kurzform erläutert. Eine ausführliche Beschreibung der einzelnen Komponenten ist der DelphiHilfe entnehmbar, die in folgenden Schritten aufgerufen wird: Komponente auf das Formular SOD]LHUHQ, Komponente auf dem Formular (einfach) anklicken und )7DVWH drücken. 8 6WDQGDUG Grundausstattung der Windows-typischen Dialogelemente, die in nahezu jeder WindowsAnwendung auftreten wie Menus, Texteingabe, Textausgabe, Auswahlelemente und Darstellungsflächen. Komponentenzeiger Bei markiertem Komponentenzeiger kann eine beliebige Komponente durch Anklicken selektiert werden. Die Hervorhebung wechselt dann auf die angeklickte Komponente. MainMenu Entwurf einer 0HQX]HLOH. Starten des Menu-Editors durch Doppelklicken des Symbols auf dem Formular. Die Menueinträge erfolgen dann über den Editor. PopupMenu Entwurf eines PopupMenus, das zur Laufzeit mit der rechten Maustaste geöffnet werden kann. Die Handhabung entspricht der des Menu-Editors. Label 7H[WDQ]HLJH ohne Nutzerzugriff. Darstellung von Texten an beliebigen Bildschirmstellen. Durch Zuweisung der Texte zur Laufzeit können auch mehrzeilige Labels dargestellt werden. Edit Einzeilige 7H[WHLQJDEH und –anzeige. Bei der Eingabe von Zahlen ist darauf zu achten, daß auch diese als Text vorliegen und vor der Verwendung im Programm u.U. erst in Zahlen konvertiert werden müssen. Memo Mehrzeilige 7H[WHLQJDEH und –anzeige. Der Text in sogenannte "Lines" (Zeilen) abgelegt, die über Indizes angesprochen werden können. Button 6FKDOWHU zum Starten einer Operation (Prozedur, Funktion) CheckBox Ja / Nein – Option RadioButton Exklusive Ja / Nein – Option; d.h. in einer zusammenhängenden Gruppe kann (im Gegensatz zur CheckBox) immer nur HLQ Element markiert sein ListBox Auswahlliste ComboBox Editierbare Auswahlliste; der selektierte Eintrag wird in die Kopfzeile des Fensters übernommen ScrollBar %LOGODXIOHLVWH zur Darstellung von Flächen, die größer sind als der zur Veerfügung stehende Sichtbereich GroupBox Ein 6FKDOWIOlFKHQIHOG zur Aufnahme mehrerer Komponenten, in dem eine Bezeichnung eingetragen werden kann RadioGroup Vorbereitetes 6FKDOWHUIHOG mit RadioButtons Panel 'DUVWHOOXQJVIOlFKH zur Aufnahme einer Komponentengruppe. Das Panel kann auch zur Darstellung von Text auf unterschiedlich gestalteten Hintergründen verwendet werden. =XVlW]OLFK Weitere Standardelemente zur Vervollständigung der obigen Gruppe wie Schalter mit eingelagerten Grafiksymbolen, Tabellen und Grafiken. BitButton 6FKDOWHU mit eingelagerter Grafik. Die Grafik kann als bereits bestehende Bitmap aus einer beliebigen Bibliothek importiert oder mit dem Bildeditor (→ Abschnitt 6.3) erstellt werden SpeedButton 6FKDOWHU mit eingelagerter Grafik zur Unterbringung auf einer ToolBar MaskEdit Formatierte Dateneingabe (z.B. Datum, Uhrzeit) StringGrid 7DEHOODULVFKH$Q]HLJH von Zeichenketten (alfanumerische Zeichen) DrawGrid Tabellenförmige allgemeine Datenanzeige 9 Image *UDILN$Q]HLJH (*.BMP, *.ICO, *.WMF) Shape Anzeige von Kreis, Ellipse oder Rechteck Bevel Rechteck oder Rahmen mit 3D-Effekt ScrollBox Erzeugen einer Liste mit Bildlaufleisten CheckListBox Auswahlliste mit Bildlaufleiste StaticText Beschriftungsfeld ähnlich dem Label mit Fenster-Handle Chart Grafische Darstellung einer Datenbank wie unter MS-Excel :LQ Dialogelemente für Windows-32-Bit-Systeme, mit denen über die Maus Auswahlen oder Einstellungen vorgenommen werden können. TabControl Notizbuchregister PageControl Notizbuchregister für mehrseitige Dialogfelder ImageList Bilderliste für TreeView und ListView RichEdit Memo-Komponente für Textdateien unbegrenzter Länge und Formatierungsmöglichkeiten TrackBar Regler zum Einstellen von Werten in einem bestimmten Bereich ProgressBar Fortschrittsanzeige eines Hintergrundprozesses UpDown schrittweises Verändern von Einstellwerten HotKey Tastenfunktionen mit Strg, Umsch und Alt TreeView hierarchische Baumdarstellung einer Liste HeaderControl größenveränderliche Darstellung eines Tabellenkopfes StatusBar Statusleiste mit mehreren Einzelfeldern am unteren Bildschirmrand ToolBar Werkzeugleiste, auf der vorzugsweise BitButtons plaziert werden können CoolBar Symbolleiste mit untergeordneten Steuerelementen, die selbständig verschoben werden können 6\VWHP Timer Bereitstellung eines Timer-Intervalls, mit dem eine Prozedur in einstellbaren regelmäßigen Abständen automatisch aufgerufen werden kann. Der Timer entspricht einem 'Software-Interrupt', der allerdings den Nachteil hat, daß sein schnellstes Arbeitsraster auf 10 Millisekunden beschränkt ist. Für Anwendungen in der Meß-, Steuer- und Regelungstechnik ist er ein wertvolles Hilfsmittel. PaintBox Zeichenfläche zum Zeichnen auf einer rechteckicken Fläche innerhalb eines Formulars. Im Gegensatz zum Image wird die PaintBox vom Betriebssystem nicht automatisch aufgefrischt, wenn sie durch ein anderes Fenster verdeckt war. Ihr Vorteil ist, daß zu entfernende Zeicheninhalte nicht aufwendig gelöscht werden müssen, sondern es reicht ein Neu-Zeichnen mit dem erforderlichen PaintBox-Inhalt. 10 'DWHQ]XJULII Nichtvisuelle Datenbankelemente TTable bildet eine physikalische Tabelle inklusive Indizes ab. Über dieses Objekt können Such- und Sortiervorgänge gestartet werden. TDataSource verknüpft eine Tabelle mit einer datensensitiven Komponente 'DWHQVWHXHUXQJ Visuelle Datenbankelemente TDBGrid Anzeige und Bearbeitung von Datensätzen in einer Tabelle TDBNavigator Steuertasten zum Bewegen und Arbeiten in einer Datenbanktabelle (TDBGrid) TDBText Anzeige eines Feldes der Datenbank als Label TDBEdit Anzeige- und Eingabefeld für eine Textzeile TDBMemo Anzeige und Eingabefeld für Mehrfachzeilen TDBImage Anzeige und Bearbeitungsmöglichkeit für Grafik TDBListBox Listenfeld. Der in der Liste gewählte Eintrag (ItemIndex) wird in der Tabelle gespeichert TDBComboBox ComboBox. Der in der ComboBox gewählte Eintrag (ItemIndex) wird in der Tabelle gespeichert TDBCheckBox Eine Checkbox wird in Abhängigkeit eines Feldes der Datenbank gesetzt oder nicht TDBRadioGroup Setzen eines RadionButtons in Abhängigkeit eines Feldes der Datenbank TDBLookupList Listenfeld. Der in der Liste gewählte Eintrag (ItemIndex) wird in der Tabelle gespeichert. Im Unterschied zur TDBListbox werden die Listeneinträge aus einer zweiten Tabelle geladen TDBLookupComboBox Combobox. Der in der ComboBox gewählte Eintrag (ItemIndex) wird in der Tabelle gespeichert. Im Unterschied zur TDBComboBox werden die Listeneinträge aus einer zweiten Tabelle geladen 'LDORJH Windows-Standarddialoge für Dateihandling, Frbvorgaben und Druckereinstellungen. OpenDialog Dialogfenster: Datei öffnen. Begleitparameter zum Öffnen einer Datei können in der Komponente vorgegeben werden. SaveDialog Dialogfenster: Datei speichern. OpenPictureDialog wie OpenDialog, aber mit Bereich für Grafikvorschau SavePictureDialog wie SaveDialog, aber mit Bereich für Grafikvorschau FontDialog Dialogfenster Zeichensatz einstellen ColorDialog Dialogfenster Farben definieren PrintDialog Dialogfenster Druckerausgabe PrinterSetupDialog Dialogfenster Drucker einrichten 11 0HQXIXQNWLRQHQ Die Steuerung der Entwicklungsoberfläche erfolgt über die Menufunktionen der Werkzeugleiste, von denen nur die wichtigsten vorgestellt werden, um mit Delphi prinzipiell arbeiten zu können. Tiefer greifende Informationen stellt die Delphi-Hilfe zur Verfügung, wenn ein Menupunkt durch Mausklick aktiviert und anschließend die F1-Taste gedrückt wird. 'DWHL Dateifunktionen zum Speichern des entwickelten Programms, das in seiner Gesamtheit als Projekt bezeichnet wird, und zum Generieren einer neuen Anwendung. Neu ... öffnet das Dialogfeld "Neue Einträge", aus dem heraus ein neues Projekt von einem bestimmten vordefinierten Typ erstellt werden kann Neue Anwendung eröffnet ein neues Projekt mit einem Standardformular Neues Formular fügt dem Projekt ein weiteres Formular hinzu Neues Datenmodul fügt dem Projekt ein spezielles Daten-Formular hinzu Öffnen Öffnen eines Projektes oder einer beliebigen Datei Neu Öffnen Öffnen eines Projektes oder einer Datei über eine Liste, in der die letzten Eintragungen gespeichert sind Speichern Strg S Speichern der aktuell vorgenommenen Änderungen Speichern unter ... Speichern der aktiven Datei unter einem neuen Namen Projekt speichern unter... Speichern der Projektdatei (∗.dpr) unter einem neuen Namen Alles speichern Speichern aller geöffneten Dateien eines Projektes Schließen Schließen der angewählten, aktivierten Datei Alle Schließen Schließen aller Dateien eines Projektes Unit verwenden ... Verwenden Sie dieses Dialogfeld, um eine Unit innerhalb der aktuellen Unit zu verwenden. In dem angebotenen Feld wird eine Liste aller Units in dem Projekt angezeigt, die nicht von der aktuellen Unit benutzt werden. Dem Projekt hinzufügen ... Eine Datei zum aktuellen Projekt hinzufügen Aus dem Projekt entfernen ... Eine Datei aus dem aktuellen Projekt entfernen Drucken ... Drucken der aktuell markierten Datei oder eines markierten Textblocks Beenden Schließen der Delphi-Entwicklungsumgebung %HDUEHLWHQ Menufunktionen zum Arbeiten im Quelltexteditor (bis zum Punkt 'Löschen') und auf dem Formular (unterhalb des Punktes 'Löschen'). 0HQXSXQNWH]XP$UEHLWHQLP8QLW4XHOOWH[W Rückgängig Strg Z Widerrufen Umsch Strg Z macht den letzten "Rückgängig-Schritt" unwirksam Ausschneiden Strg X überschreibt die Zwischenablage mit dem markierten Text oder den markierten Elementen Kopieren Strg C kopiert markierten Text oder markierte Elemente in die Zwischenablage Einfügen Strg V fügt den Inhalt der Zwischenablage ein Löschen Strg Entf entfernt die markierten Elemente aus dem Speicher macht die vorangegangene Operation rückgängig 12 0HQXSXQNWH]XP$UEHLWHQDXIGHP)RUPXODU Alles auswählen alle Komponenten eines Formulars markieren Am Raster ausrichten verschiebt die markierten Komponenten zum nächsten Rasterpunkt Nach vorne setzen stellt die markierte Komponte vor die anderen, so daß sie diese bei Überlappungen überdeckt Nach hinten setzen stellt die markierte Komponte hinter die anderen, so daß sie von diesen im Überlappungsfall überdeckt wird Ausrichten ... öffnet das Dialogfenster zum Ausrichten von Komponenten Größe ... öffnet das Dialogfenster zur Einstellung von Breite und Höhe Skalierung ... öffnet das Dialogfenster zur proportionalen Größenänderung Tabulatorreihenfolge ... öffnet das Dialogfenster zur Bearbeitung der Tabulatorreihenfolge Erstellungsfolge ... öffnet das Dialogfenster 'Erstellungsfolge', in dem die Reihenfolge der Erzeugung der unsichtbaren Komponenten editiert werden kann Elemente sperren verankert alle Komponenten in ihrer momentanen Position und Größe, so daß sie durch die Maus nicht mehr unbeabsichtigt verändert werden können. Änderungen über den Objektinspektor sind weiterhin möglich. Zur Schnittstelle hinzufügen ... fügt eine neue Funktion oder Prozedur zur ActiveX-Komponente hinzu 6XFKHQ Suchfunktionen zum Aufsuchen von Quelltext und Laufzeitfehlern. Suchen ... Strg F In Dateien suchen ... öffnet das Dialogfenster "Text suchen", in dem ein beliebiger Textabschnitt in der aktiven Datei gesucht wird erweiterte Suchfunktion "Suchen", die in mehreren Dateien vorgenommen wird Ersetzen ... Strg R öffnet das Dialogfenster "Text ersetzen", in dem ein beliebiger Textabschnitt in der aktiven Datei gesucht und durch einen eingegebenen Text ersetzt wird Suche wiederholen F3 setzt den Suchvorgang ab der aktuellen Stelle fort Inkrementelle Suche Strg E Suche ohne Dialogfenster Gehe zu Zeile ... geht zu einer bestimmten Zeile des Quelltextes Laufzeitfehler suchen ... stoppt in der Zeile des letzten Laufzeitfehlers Symbol anzeigen ... öffnet Dialogfenster zur Eingabe eines Bezeichners $QVLFKW Auswahlmöglichkeiten zur Darstellung unterschiedlichster Fenster, Hilfspaletten, Informationen und Arbeitshilfen. Der wichtigste Unterpunkt steht mit der 'Projektverwaltung' sofort in der ersten Zeile. Projektverwaltung öffnet das Fenster für die Projektverwaltung, in dem alle im Projekt eingebundenen Dateien eingesehen werden können, sowie deren Pfade und Verzeichnisse. Projekt-Quelltext öffnet das Fenster des Quelltexteditors Objektinspektor F11 öffnet das Fenster des Objektinspektors Ausrichtungspalette öffnet eine Werkzeugleiste zum komfortablen Ausrichten von Komponenten Symbolanzeige öffnet den Objekt-Browser Haltepunkte öffnet die Liste der aktuellen Haltepunkte Aufruf-Stack zeigt die Liste der Unterprogramm-Aufrufe 13 Überwachte Ausdrücke zeigt die Lister der vom Debugger überwachten Variablen Module DLL oder Package zur Laufzeit hinzuladen Komponentenliste zeigt eine Lister der verfügbaren Komponenten an Fensterliste ... Alt O zeigt die Liste der geöffneten Fenster F12 schaltet um zwischen Formular und zugeordneter Unit Units ... Strg F12 Liste der Quelltextdateien im Projekt Formulare ... Umsch F12 Lister der Formulare im Projekt Umschalten lar/Unit Formu- Neues Editierfenster öffnet ein Fenster mit einer Kopie des aktuellen Quelltextes Symbolleiste zeigt die Symbolleiste an Komponentenpalette zeigt die Komponentenpalette an 3URMHNW Die ersten beiden Menupunkte können auch über das Menu 'Ansicht / Projektverwaltung' erreicht werden und dienen der Verwaltung der im Projekt befindlichen Dateien. Die wichtigsten Funktionen in dieser Menugruppe betreffen aber das Compilieren (Übersetzen) und das Linken (Zusammenbinden) des Projektes zu einer ausführbaren EXE-Datei. Die Randbedingungen für Compiler und Linker sind im Unterpunkt 'Optionen...' einzustellen. 3URMHNWYHUZDOWXQJ Dem Projekt hinzufügen ... eine Datei zum aktuellen Projekt hinzufügen Aus dem Projekt entfernen ... eine Datei aus dem aktuellen Projekt entfernen Der Objektablage hinzufügen ... selbst erstellte Objekte als Vorlagen für spätere Verwendungen in der Objektablage ablegen &RPSLOHUXQG/LQNHU Compilieren Strg F9 startet die Compilierung der geänderten Dateien Projekt neu compilieren startet die Compilierung aller Dateien eines Projektes Syntaxprüfung startet die Compilierung ohne Linken Information ... informiert nach dem Compilieren über Programm-, Stack-, Datengröße usw. Optionen ... Einstellungen der Parameter für Compiler und Linker, sowie der Startoptionen zum Aufbau der Formulare zur Laufzeit. 6WDUW Die Gruppe ’Start’ dient dem Starten des fertig compilierten und gelinkten Programmes, sowie dem Debuggen zum Auffinden von Fehlerursachen (→ 6.1). 1RUPDOH 3URJUDPPDXVIKUXQJ Start F9 Parameter ... compiliert das Programm, linkt es und führt es aus öffnet ein Dialogfeld zur Eingabe von Kommandozeilenparametern 'HEXJJHU)XQNWLRQHQ Gesamte Routine F8 das Programm wird vom Debugger zeilenweise ausgeführt; d.h. eine Prozedur wird in einem Schritt abgearbeitet 14 das Programm wird einschliesslich auszuführender Prozeduren zeilenweise abgearbeitet Einzelne Anweisung F7 Nächste Quellzeile Umsch F7 Programm hält bei der nächsten Quelltextzeile an Gehe zur Cursorposition F4 das Programm wird bis zu der Position im Quelltext abgearbeitet, an der sich der Cursor befindet Zeige Ausführungsposition setzt den Cursor in die Zeile, in der sich der Debugger bei der Programmausführung befindet Programm Pause unterbricht vorübergehend die Programmausführung Programm zurücksetzen Strg F2 beendet das Programm und gibt den belegten Speicherplatz frei Ausdruck hinzufügen ... Strg F5 öffnet das Dialogfenster zur Eingabe überwachter Ausdrücke Neuer Haltepunkt ... Auswerten/Ändern ... öffnet das Dialogfenster zum Eingeben eines Haltepunktes Strg F7 öffnet das Dialogfenster zum Anzeigen und Editieren einer Variablen zur Laufzeit 7RROV Umgebungsoptionen ... öffnet das Dialogfenster zur Einstellung der Umgebungsoptionen. Das Menu wird im allgemeinen einmal von einem Programmierer zu Beginn seiner Arbeiten benutzt, um sich die Arbeitsoberfläche entsprechend seinen Wünschen einzustellen. Objektablage ... öffnet das Dialogfenster "Objektablage" Tools konfigurieren ... erlaubt das Hinzufügen, Löschen und Bearbeiten von Tools Editor für PackageSammlungen Anzeigen und Bearbeiten von Package-Libraries Bildeditor pixelorientiertes Zeichenprogramm zur Erstellung eigener Bitmaps (→ 6.2) Datenbankoberfläche Programm zur Bearbeitung von Datenbanktabellen (→ 6.3) 'DV$UEHLWHQDXIGHP)RUPXODU Das Formular ist die visuelle Grundlage eines Delphi-Programms und dient der Aufnahme der Komponenten, mit denen der Anwender später in direktem Dialog arbeiten wird. Das Plazieren einer Komponente auf dem Formular ist im allgemeinen der erste Schritt bei der Bearbeitung einer Komponente. Die Einstellungen der auf dem Formular plazierten Komponente erfolgen dann über den Objekt-Inspektor oder durch Ziehen mit der Maus, falls z.B. die Abmessungen oder die Position der Komponente verändert werden sollen. Ein sehr nützliches Instrumentarium ist die Möglichkeit, mehrere Objekte gleichzeitig bearbeiten zu können. Wenn zum Beispiel mehrere Labels die gleiche Breite haben sollen, so muß die Eigenschaft nicht für jedes Objekt separat im Objekt-Inspektor eingetragen werden, sondern die Objekte können vorübergehend zu einer Gruppe zusammengefaßt werden, und der einmalig eingetragene Breitenwert wird in jede Komponente übernommen. Das Zusammenfassen von Objekten zu einer *UXSSH kann auf zwei Arten erfolgen: 1. Das erste Objekt der Gruppe wird ganz normal angeklickt, und die Objekte, die nun dieser Gruppe hinzugefügt werden sollen, werden bei gedrückter Umschalttaste angeklickt. Ab dem zweiten Objekt werden die 8 Markierungspunkte eines Objektes nun nicht mehr in schwarz sondern in Grau dargestellt. 2. Bei gedrückter Steuerungstaste wird mit der Maus ein rechteckförmiger Rahmen um die Objekte gezogen, die in einer Gruppe zusammengefaßt werden sollen. Um ein Objekt zu selektieren, muß es nicht komplett umschlossen werden, sondern der Rahmen braucht es lediglich zu berühren. Auch bei dieser Methode werden die selektierten Objekte durch graue Rahmenpunkte gekennzeichnet. 15 Die Gruppierung wird aufgehoben, wenn irgendein nicht markiertes Element angeklickt wird. Neben der Möglichkeit, an gruppierten Elementen effizient Eigenschaften zu ändern, können die Elemente einer Gruppe auch ohne viel Aufwand angeordnet und ausgerichtet werden. Die dazu erforderlichen Befehle bietet der Menupunkt "Bearbeiten" mit den rechts dargestellten Funktionen an. Größe und Position eines Objektes sind die am häufigsten einzustellenden Eigenschaften und können sowohl für ein einzelnes Objekt, wie auch für eine Objekt-Gruppe besonders exakt mit der Tastatur vorgenommen werden. Die Positionierung erfolgt bei gedrückter 6WHXHUXQJVWDVWH mit den &XUVRUWDVWHQ; die Größe wird ebenfalls durch die &XUVRU WDVWHQ eingestellt, wenn gleichzeitig die 8PVFKDOWWDVWH gedrückt gehalten wird. Die Veränderung von Größe und Position erfolgt bei jedem Cursor-Tastendruck mit einer bestimmten diskreten Schrittweite, deren Größe durch die Rasterung des Hilfsgitters auf dem Formular definiert ist. Das Raster der Gitterpunkte ist im Menupunkt "Tools / Umgebugsoptionen / Vorgaben" einzustellen. Am Raster ausrichten Die markierten Elemente werden so verschoben, daß sie mit ihrer oberen linken Ecke an den nächst gelegenen Raserpunkt positioniert werden. Nach vorne setzen Nach hinten setzen Während der Entwurfszeit können sich auf dem Formular durchaus mehrere Komponenten überlappen, mit den beiden Befehlen kann bestimmt werden, welche Komponente komplett sichtbar und welche überdeckt werden. Ausrichten ... Die gruppierten Komponenten werden zueinander ausgerichtet; z.B. links- oder rechtsbündig, an einer unteren oder oberen Bezugskante, oder auf einen gleichmäßigen Abstand untereinander. Größe für alle markierten Elemente kann die Größe absolut in Bildschirmpixeln eingestellt werden. Skalierung Die markierten Elemente können in Relation zur aktuellen größe relativ, proportional verändert werden. Tabulatorreihenfolge... Schaltelemente können zur Laufzeit über die Maus oder über die Tastatur betätigt werden. Um einen Schalter mit der Tastatur betätigen zu können, muß er allerdings den Focus besitzen (das Schaltelement ist optisch hervorgehoben), der mit der Tabulatortaste von Element zu Element bewegt wird. Die Reihenfolge, in der die Elemente den Focus zugeteilt bekommen, wird über die Tabulatorreihenfolge geregelt. Man kann damit also bewirken, daß der Focus nicht willkürlich zur nächsten Komponente springt, sondern die Komponenten in einer geordneten Reihenfolge aktiviert. Erstellungsfolge... Benutzen Sie dieses Dialogfeld, um die Reihenfolge zu bestimmen, in der Ihr Programm die nicht-visuellen Komponenten erzeugt, wenn Sie das Formular während der Programmentwicklung oder während des Programmablaufs laden. Das Listenfeld zeigt ausschließlich die nicht sichtbaren Komponenten des aktuellen Formulars sowie ihren Typ und ihre momentane Erstellungsreihenfolge an. Standardmäßig entspricht die Erstellungsreihenfolge der Reihenfolge, in der Sie die Komponenten in das Formular eingefügt haben. Elemente sperren Benutzen Sie diese Funktion, um Komponenten des aktuellen Formulars an ihrer momentanen Position zu verankern. Wenn diese Option aktiviert ist, können Sie keine der Komponenten verschieben oder in ihrer Größe verändern. Sie können jedoch den Objektinspektor verwenden, um die Eigenschaften Height, Left, Top und Width einer markierten Komponente zu verändern. Hinweis: Der Befehl Elemente sperren hat keine Wirkung auf das Formular selbst. Auch nach Aktivieren des Befehls können Sie das Formular frei bewegen oder in der Größe verändern. 16 6WUXNWXUHLQHU8QLW Zu einem Formular gehört zwangsläufig immer eine Unit, in der hinterlegt wird, wie die einzelne Komponente auf dem Formular auf ein bestimmtes Ereignis reagieren soll. Die Unit enthält damit den anwendungsspezifischen Teil des Programms, wobei der prinzipielle Aufbau einer Unit fest vorgegeben ist. XQLW MAIN2; LQWHUIDFH {-$DEFINE UseBvKarte} XVHV SysUtils,WinTypes,WinProcs,Messages,Classes,Graphics,Controls; W\SH TFMain = FODVV(TForm) Beenden1: TMenuItem; BBCycOK: TBitBtn; procedure Beenden1Click(Sender: TObject); procedure BBCycOKClick(Sender: TObject); SULYDWH procedure NewData; procedure DisposeData; SXEOLF procedure Sinus1Click(Sender: TObject); procedure Ellipse1Click(Sender: TObject); HQG; FRQVW LEN_EINGABE = 8; YDU FMain: TFMain; Polygon: ^Tpolygon; LPSOHPHQWDWLRQ {$R *.DFM} XVHV Bv, BvImage, DefData, Comm, Hilfe; YDU ODatName,OFullName: string; SURFHGXUH TFMain.MMeldung (text: string); FRQVW FAKTOR = 5.575; YDU Wert1,Wert2: single; EHJLQ ... HQG; SURFHGXUH TFMain.Bildverarbeitung1Click(Sender: TObject); EHJLQ ... HQG; LQLWLDOL]DWLRQ MainInit; ^RSWLRQDO` ILQDOL]DWLRQ Speicher freigeben; ^RSWLRQDO` HQG 17 (UHLJQLVVH Der Ablauf eines Windowsprogrammes ist HUHLJQLVRULHQWLHUW; d.h. es bedarf eines bestimmten Anlasses, wie z.B. dem Drücken einer Taste auf der Tastatur, einem Mausklick oder eines Timer-Ereignisses, damit eine Funktion oder Prozedur ausgeführt wird. Die Ereignisse, die für eine bestimmte Komponente eintreten können, sind in der Seite "Ereignisse" des ObjektInspektors aufgelistet, deren Standardereignisse in der folgenden Tabelle zusammengestellt sind. (UHLJQLV WULWWHLQZHQQ OnClick ... mit der auf dem Desktop definierten Standard-Maustaste auf die Komponente JH NOLFNW wird. OnDblClick ... mit der Standard-Maustaste ein 'RSSHONOLFN auf die Komponente erfolgt. OnMouseDown ... eine Maustaste QLHGHUJHGUFNW wird. Anhand der Variablen Shift, Button und X,Y im Prozedurkopf kann auch unterschieden werden, welche Maustaste gedrückt worden ist, und an welcher Koordinatenposition sich der Mauscursor befindet. Shift Button Bedeutung ssLeft mbLeft linke Maustaste gedrückt ssMiddle mbMiddle mittlere Maustaste gedrückt ssRight mbRight rechte Maustaste gedrückt OnMouseUp ... eine Maustaste losgelassen wird. Es gelten dieselben Randbedingungen wie für das OnMouseDown-Ereignis. OnMouseMove ... die Maus bewegt wird. Im Gegensatz zu OnMouseDown und OnMouseUp tritt das Ereignis auch dann ein, wenn NHLQH0DXVWDVWHJHGUFNW wird. OnKeyPressed ... eine Taste gedrückt wird. Im Prozedurkopf wird der ASCII-Code der gedrückten Taste übergeben. OnKeyDown ... eine Taste nach unten gedrückt wird. OnKeyUp ... eine Taste losgelassen wird. OnKeyDown und OnKeyUp können auf alle Tasten einschließlich Funktionstasten und Tastenkombinationen reagieren. Da der übergebene Parameter aber vom Typ 'Word' ist, müssen hier die unter Windows definierten YLUWXHOOHQ7DVWHQFRGHV verwendet werden (→ Delphi-Hilfe). OnChange ... die Komponente geändert worden ist. OnEnter ... die Komponente den Focus erhält. OnDragDrop ... ein gezogenes Objekt in der Komponente abgelegt wird. OnDragOver ... ein Objekt über die Komponente bewegt wird. OnEndDrag ... Drag&Drop beendet worden ist. OnExit ... die Komponente den Focus verliert. Bei Doppelklicken auf eine leere Ereigniszeile legt Delphi das Gerüst für eine Prozdur an, deren Bezeichnung aus dem Namen der Komponente und dem Namen des Ereignisses zusammengesetzt wird. SURFHGXUH Button1Click (Sender: TObject); EHJLQ HQG; Die Deklaration des Ereignisses wird auch automatisch in der Klassendefinition des übergeordneten Formulars eingetragen. Beim Entfernen einer Ereignisprozedur ist also darauf zu achten, daß sowohl die Prozedur, als auch deren Deklaration gelöscht wird. Hinweis: Detaillierte Informationen zu den Ereignissen bietet auch hier die Delphi-Hilfe, indem das entsprechende Ereignisfeld im Objekt-Inspektor angeklickt und die Funktionstaste F1 gedrückt wird. 18 6SUDFKHOHPHQWH Eine Programmiersprache besteht in den wesentlichen Merkmalen aus 9DULDEOHQ, $QZHLVXQ JHQ und 9HUNQSIXQJHQ. Die als Informationsträger dienenden Variablen sind im allgemeinen nahezu unabhängig von der Sprache; ihre Wahl und Gestaltung bleibt bis auf kleine Einschränkungen allein dem Programmierer überlassen. Fest definiert sind hingegen die zu verwendenden Anweisungen oder Befehle, die auch als reservierte Wörter bezeichnet werden und der Zeichensatz, über den Zuweisungen und Verknüpfungen erfolgen. =HLFKHQVDW] 6\PERO (UNOlUXQJ Zuweisung Addition, Vorzeichen, Vereinigungsmenge, Stringverkettung Subtraktion, Vorzeichen, Differenzmenge ∗ Multiplikation Division (Gleitkomma-Arithmetik) Gleichheitsabfrage ! ! ! Abfrage auf größer als und Abfrage auf kleiner als Abfrage auf größer/gleich als und Abfrage auf kleiner/gleich als Abfrage auf Ungleichheit Dezimalpunkt Bereichsangabe Trennung von Listenelementen Trennung von Deklarationen bzw. Anweisungsblöcken Variablendeklaration, Case-Separator Zeichenkettenanfang und –ende >@ Anfang / Ende von Mengenkonstanten Anfang / Ende von Listen bzw. Klammerausdrücken ^` Anfang / Ende von Kommentaren, die über mehrere Zeilen gehen dürfen Einleitung einer Kommentarzeile A Zeichen für Zeiger (Pointer) # Adreßzeichen Einleitungssymbol einer Hexadezimalzahl Einleitungssymbol einer ASCII-Darstellung Ersatzdarstellung für [ ] ∗∗ Ersatzdarstellung für { } 19 5HVHUYLHUWH:|UWHUXQG6WDQGDUGEH]HLFKQXQJHQ Dem Programmierer steht es frei, welche Namen er an seine Variablen, Funktionen oder Prozeduren in der Anwendung vergibt. Eine Ausnahme bilden aber Bezeichner, die vom Compiler bereits reserviert sind und als Befehle oder Schlüsselworte fungieren. %H]HLFKQHU absolute and array as at asm begin case cdecl const div do downto else end except exports external far file finalization finally for forward function goto if implementation interface label library mod name near nil nodefault not of on or packed (UNOlUXQJ Adressendefinition logisches UND Feld (Tabelle) Überprüfung von Typumwandlungen @-Operator zur Adressenberechnung Zugriff auf den integrierten Assembler Blockanfang Fallunterscheidung Unterstützung von Delphi-fremden Routinen Konstantendeklaration ganzzahlige Division Schleifenausführung unterer Endwert einer Schleife Alternativ- bzw. Neinzweig einer Abfrage Blockende Abschnitt für Fehlerbehandlungscode exportiert Funktionen / Prozeduren aus DLLs Deklaration extern compilierter Funktionen / Prozeduren Aufruf von Routinen von anderen Modulen aus Datei abschließender Abschnitt einer Unit immer ausgeführter Abschnitt eines geschützten Blocks Anfangswert einer Schleife Deklaration einer Funktion / Prozedur im voraus Funktionsdeklaration Sprungbefehl Bedingung Runpf einer Unit globale Deklarationen einer Unit Sprungmarke dynamische Linkbibliothek (DLL) Divisionsrest Namensangabe innerhalb einer H[SRUWV-Klausel Aufrufkonvention undefinierter Zeiger Standardwert einer Eigenschaft wird gesteuert Verneinung Benennung eines Grundtyps ... bildet zusammen mit GR eine Fehlerbehandlungsroutine logisches ODER gepackte Struktur 20 procedure program raise record repeat resident set shl shr string then to try type unit until uses var while with xor Prozedur-Deklaration Programm-Deklaration Auflösen einer Exception (Fehlerbehandlung) Datensatz Schleifenwiederholung mit Endabfrage Exportinformation bleibt beim DLL-Aufruf im Speicher Menge verschieben nach links verschieben nach rechts Zeichenkette Ja-Zweig einer Abfrage oberer Endwert einer Schleife geschützter Code innerhalb einer Exeption-Behandlung Datentyp eigenständiges Programm-Modul Ende einer UHSHDW-Schleife Unit-Deklarationen Datenvariable Schleifen-Wiederholung mit Anfangsabfrage Zugriff auf UHFRUG-Strukturen Exclusiv-ODER $ULWKPHWLVFKH2SHUDWRUHQ Die Gruppe der Operatoren ist im Prinzip lediglich eine Zusammenstellung bestimmter Elemente aus dem Zeichensatz und der Gruppe der reservierten Wörter, mit denen die meisten rechentechnischen Verknüpfungen von Variablen durchgeführt werden. Besonders interessant ist in diesem Zusammenhang allerdings, welche Ergebnisse sich einstellen, wenn unterschiedliche Typen von Variablen miteinander verarbeitet werden. 2SHUDWRU ∗ GLY PRG 2SHUDWLRQ 2SHUDQG 2SHUDQG (UJHEQLVW\S Addition Integer Integer Integer Real Real Real Real Integer Real ZLH$GGLWLRQ Subtraktion Multiplikation Division (Gleitkomma) Ganzzahlige Division Rest Integer Integer Integer Real Real Real Real Integer Real Integer Integer Real Real Real Real Real Integer Real Integer Integer Integer Real Integer Integer Real Real Integer ZLH,QWHJHU'LYLVLRQ 21 6SUDFKHOHPHQWH )XQNWLRQHQXQG3UR]HGXUHQ Die wichtigsten Programmbausteine in einem Windows-Programm sind Funktionen und Prozeduren, die in Form von Unterprogrammen eine exakt umrissene Aufgabe abarbeiten und nach der Abarbeitung beendet werden. Eine )XQNWLRQ ist ein Unterprogramm, das Funktionsparameter übergeben bekommt, diese verarbeitet und in der aufrufenden Programmzeile in Form einer Zuweisung ein Ergebnis zurückgibt. Nach Abarbeitung der Funktion wird das Programm unmittelbar mit der Zeile hinter dem Funktionsaufruf fortgesetzt. ... a := 15.3; IXQFWLRQ Summe (x,y,z: single): single; b := 2.5; EHJLQ c := 2.2; result := x + y + z; s := Summe (b,c,d); RGHU ... Summe := x + y + z; ... HQG; Die 3UR]HGXU ist ein Unterprogramm, das der Funktion weitgehend identisch ist. Der Unterschied besteht darin, daß die Prozedur der aufrufenden Programmzeile keinen separaten Ergebniswert zuweist, sondern daß das oder die Ergebnisse als Variable in der Liste der Übergabeparameter erscheinen. ... a := 15.3; SURFHGXUH Summe ( x,y,z: single; YDU s: single); b := 2.5; EHJLQ c := 2.2; s := x + y + z; Summe (b,c,d,s); HQG; ... ... 9DULDEOHQXQG'DWHQW\SHQ Jedes Programm lebt in erster Linie von seinen Variablen. Mit Variablen wird gerechnet oder ihnen wird mittels Ergebnisanweisung (:=) ein Wert zugewiesen, oder sie werden als Parameter an Funktionen bzw. Prozeduren übergeben. a := 2 ∗ b; y := sin (a); Im allgemeinen haben Variablen einen bestimmten Datentyp (Single, Integer, String ...), der ihnen in der Deklaration der Variablen zugewiesen wird. Deklarationen werden in einem zusammenhängenden Block vorgenommen, der durch das Schlüsselwort "var" gekennzeichnet ist. YDU kurs, dm, dollar: single; code: integer; vorname: string; Innerhalb von Prozeduren und Funktionen deklarierte Variable bezeichnet man als ORNDO, außerhalb von Prozeduren/Funktionen deklarierte alsJOREDO. Für globale Variable muß darüberhinaus noch unterschieden werden, ob sie im ,PSOHPHQWDWLRQVWHLO oder im ,QWHUIDFHWHLO deklariert worden sind. Im Implementationsteil angelegte Variable sind innerhalb der Unit jeder Funktion und Prozedur bekannt; sie können aber nicht von anderen Units verwendet werden. Im Interfaceteil deklarierte globale Variable können dagegen auch von anderen Units benutzt werden. 22 LQWHUIDFH YDU s0: string; // globale Variable, die für andere Units verwendbar ist LPSOHPHQWDWLRQ YDU s1, s2: string; // globale Variable, die nur innerhalb der Unit verwendet werden können SURFHGXUH test1; YDU s3,s4: string; EHJLQ s3 := 'Müller'; s4 := 'Meier'; HQG; lokale Variable, die nur innerhalb der Prozedur 'test1' gültig sind SURFHGXUH test2; EHJLQ s1 := 'Vorname'; s2 := 'Nachname'; HQG; Globalen Variablen kann bereits bei der Deklaration ein Anfangswert zugewiesen werden; d.h. sie können bereits mit der Deklaration initialisiert werden. YDU s1: string = 'Müller'; i: integer = 5; ,QWHJHU7\SHQ Zu dieser Gruppe zählen die in der folgenden Tabelle zusammengestellten Ganzzahl-Variablen, die mit Wortlängen bzw. Auflösungen von 8-bit, 16-bit oder 32-bit arbeiten. 7\S :HUWHEHUHLFK )RUPDW 6KRUWLQW -128..127 Acht Bit einschließlich Vorzeichen 6PDOOLQW -32768..32767 16 Bit einschließlich Vorzeichen /RQJLQW -2147483648..2147483647 32 Bit einschließlich Vorzeichen %\WH 0..255 8 Bit, besitzt kein Vorzeichen :RUG 0..65535 16 Bit, besitzt kein Vorzeichen ,QWHJHUELW6\VWHP -32768..32767 16 Bit einschließlich Vorzeichen &DUGLQDO 0..65535 16 Bit, besitzt kein Vorzeichen ,QWHJHUELW6\VWHP -2147483648..2147483647 32 Bit einschließlich Vorzeichen &DUGLQDO 0..2147483647 32 Bit, besitzt kein Vorzeichen 5HDO7\SHQ Für das eigentliche "Rechnen" in Programmen werden in der Regel Gleitkommavariablen verwendet, deren Darstellung mit 32-bit bis 80-bit-Genauigkeit vorgenommen werden kann. Bei der Deklaration von Gleitkomma-Variablen wird man die Auflösung nicht höher als erforderlich wählen, da höhere Auflösungen im allgemeinen mehr Speicherplatz und längere Rechenzeiten bedeuten. Für die reine Ablage von Daten auf der Festplatte ist eine Darstellungsbreite von 32 Bit in der Regel vollkommen ausreichend. 23 7\S :HUWHEHUHLFK 6LQJOH 6LJQLILNDQWH =LIIHUQ *U|HLQ%\WH 1.5 x 10^-45 .. 3.4 x 10^38 7-8 4 5HDO 2.9 x 10^-39 .. 1.7 x 10^38 11-12 6 'RXEOH 5.0 x 10^-324 .. 1.7 x 10^308 15-16 8 ([WHQGHG 3.4 x 10^-4932 .. 1.1 x 10^4932 19-20 10 &RPS -2^63+1 .. 2^63 –1 19-20 8 &XUUHQF\ -922337203685477.5808.. 19-20 8 922337203685477.5807 Hinweis: Der Typ Real wird nur noch aus Kompatibilitätsgründen zu früheren Pascal-Versionen "mitgeschleppt". Da das Real-Speicherformat mit 6 Byte von Intel-CPUs nicht unterstützt wird, sind Operationen mit diesem Datentyp deutlich langsamer als die coprozessorunterstützten Datentypen Single, Double und Extended. Der Datentyp Extended ist die Basis für alle Gleitkommaberechnungen. Auch wenn nur Single oder Double-Variablen in mathematischen Ausdrücken verwendet werden, werden die Rechenoperationen intern immer mit der imposanten 10 Byte-Datenbreite des Extended-Formats durchgeführt. %RROHDQ7\SHQ Der logische Datentyp boolean kann nur die Zustände False und True annehmen, die als Konstantenbezeichner fest vordefiniert sind. Der Speicherbedarf dieser Variablen beschränkt sich damit auf ein einziges Byte. Die hauptsächliche Verwendung erfolgt in Abfragen für bedingte Verzweigungen. 6WULQJV Der wichtigste Datentyp neben den Integer-, Boolean- und Realtypen ist die Deklaration von Text- oder Zeichenketten, die als Strings bezeichnet werden. Strings sind Zeichen des erweiterten ASCII-Zeichensatzes, sind in Apostrophe (') einzuschließen und müssen im Quelltext in einer Zeile stehen. YDU s1: string; EHJLQ .. s1 := ’Hallo’; s1 := ’’; HQG; // Deklaration einer Zeichenkette // Zuweisung des Wortes ’Hallo’ an die Stringvariable s1 // Leerstring Ab Delphi 2.0 werden neben den üblichen "kurzen" Strings mit maximal 255 Zeichen nun auch "lange" Strings mit einer Länge von 2 GByte unterstützt. 7\S (UOlXWHUXQJ *U|H $QVL6WULQJ Zeichenkette unbegrenzter Länge 4 Byte (Zeiger!) 6KRUW6WULQJ Zeichenkette mit max. 255 Byte (Länge + 1) Byte VWULQJ AnsiString bei Compilereinstellung ($H+) ShortString bei Compilereinstellung ($H-) Für alle Typen der Tabelle kann nach wie vor das reservierte Schlüsselwort 'string' verwendet werden. Die Grundeinstellung ist über den Menupunkt "Projekt/Optionen/Compiler" durch Mar24 kieren des Feldes "Huge-String" vorzunehmen, das in der Standardeinstellung auch aktiviert ist. {$H+} YDU s1: string; s2: string [40]; s3: AnsiString; s4: ShortString; // lange Strings einschalten; kann entfallen, wenn ’Huge-Strings’ markiert ist // langer String, abhängig von $H // kurzer String mit max. 40 Zeichen, unabhängig von $H // langer String, unabhängig von $H // kurzer String, unabhängig von $H In einem String läßt sich jedes einzelne Zeichen als Element eines Feldes gezielt ansprechen und auch 'herausschneiden'. Das einzelne Zeichen entspricht einem String der Länge 1, kann aber auch durch den speziellen Datentyp FKDU aufgenommen werden. YDU z: char; s: string; EHJLQ s := ’Hallo’; z := s[1]; HQG; // Dem String s wird der Test Hallo zugewiesen // Die Variable z enthält nun den Buchstaben 'H' Im Falle sehr langer Strings oder im Sinne einer übersichtlicheren Darstellung des Quelltextes kann eine Stringzuweisung auch über mehrere Zeilen gehen. Die in Apostrophe eingekleideten Teilstrings werden dabei durch das Zeichen "+" über die Zeilen hinweg miteinander verbunden. YDU ls: string; EHJLQ ls := ’Dies ist ein relativ langer String, ’ + 'der sich im Quelltext über zwei Zeilen erstreckt.'; HQG; $UUD\V Im allgemeinen ist die Aufgabe eines Rechnerprogramms die Bearbeitung großer Datenmengen, wie z.B. von Meßdaten. Große Mengen gleichartiger Zahlenwerte werden dann nicht mit separaten Variablennamen belegt, sondern als Datenfeld (Array) betrachtet, das mit HLQHP Variablennamen versehen wird, und in dem die einzelnen Werte über einen Zählerindex angesprochen werden. Die Erscheinungsform des Datenfeldes ist bei der Behandlung von Strings bereits aufgetaucht, da ein String im Grunde genommen nichts anderes ist als ein Array von Zeichen (char). YDU Kundenname : array [1..1000] of string; Alter : array [1..1000] of integer; MessWert : array [1..50000] of single; Matrix : array [1..100,1..10] of double; EHJLQ Kundenname [52] := 'Müller'; // Der 52. String im Array Kundenname ist 'Müller' Alter [13] := 22; // Der 13. Eintrag im Array Alter ist die Zahl 22 MessWert [2560] := 155.25; // Der 2560 te Meßwert ist 155.25 Element := Matrix [20,5]; // Die Variable Element bekommt den Wert zugewiesen, der im // Array Matrix in der Zeile 20 und der Spalte 5 steht HQG; 7\SHQ Das Beispiel Array zeigt, daß man bereits bestehende Datentypen kombinieren kann, was dann im Grunde genommen zu einem neuen Datentyp führt. Die Deklaration einer Array-Variablen kann unter diesem Blickwinkel auch über den Umweg einer Typdeklaration vorgenommen werden, die über das Schlüsselwort W\SH eingeleitet wird. Besonders interessant ist die "Typisierung" von Arrays bei der Verwendung von Zeigern und beim effizienten Aufrufen von Funktio25 nen und Prozeduren. W\SH TKundenname = array [1..1000] of string; TAlter = array [1..1000] of integer; TMessWert = array [1..50000] of single; TMatrix = array [1..100,1..10] of double; YDU Kundenname: TKundenName; Alter: TAlter; MessWert: TMessWert; Matrix: TMatrix; EHJLQ Kundenname[487] := ’Schmidt’; // Der Kunde mit der Indexnummer 487 heißt Schmidt Alter[487] := 33; // Herr Schmidt ist 33 Jahre alt MessWert := 127.52; Matrix[75,1] := MessWer; // MessWert wird mit der lfd. Nummer 75 (Zeile )in Spalte 1 abgelegt HQG; 5HFRUGV Den Vorteil, eine eigene Typdeklaration durchführen zu können, macht die Benutzung der Strukturvariablen UHFRUG deutlich, die es erlaubt ein Datenfeld zu definieren, in das Variable unterschiedlicher Gattungen aufgenommen werden können. W\SH TPerson = UHFRUG Name: string [30]; Alter: integer; Gewicht: single; HQG; YDU Person1, Person2: TPerson; EHJLQ Person1.Name := 'Müller'; Person1.Alter := 37; Person1.Gewicht := 75.3; Person2 := Person1; HQG; Definition des neuen Typs "TPerson" // Deklaration von Variablen vom Typ TPerson // Zuweisung des Namens von Person1 // Zuweisung des Alters von Person1 // Zuweisung des Gewichts von Person1 // Name, Alter und Gewicht von Person1 an Person2 zuweisen Eine Vereinfachung des Zugriffs auf Record-Strukturen schafft die with-Anweisung, die es gestattet innerhalb eines Blockes direkt auf die Feldbezeichner des Records zuzugreifen. EHJLQ ZLWK Person1 do EHJLQ Name := 'Müller'; Alter := 37; Gewicht := 75.3; HQG; Person2 := Person1; HQG; // Zuweisung des Namens von Person1 // Zuweisung des Alters von Person1 // Zuweisung des Gewichts von Person1 // Name, Alter und Gewicht von Person1 an Person2 zuweisen =HLJHU Ein Zeiger ist im Gegensatz zu einer Variablen ein Wert, der auf eine Variable eines bestimmten Typs zeigt, also deren Adresse enthält. Das Symbol einer Zeigervariablen ist '∧' und wird auf der Tastatur durch das getrennt hintereinanderfolgende Drücken der Tasten '∧' und Leertaste erzeugt. Während der Laufzeit eines Programmes wird der Zeigervariablen im allgemeinen eine Adresse zugeordnet werden, die auf irgend eine andere Variable zeigt. Das Feststellen und Auslesen 26 solch einer Adresse erfolgt mit dem Operator @. YDU Zahl1,Zahl2: integer; Zeiger: ^integer; EHJLQ Zeiger := NIL; Zahl1 := 100; Zeiger := @Zahl1; Zahl2 := Zeiger^; HQG; // Die Variablen ’Zahl1’ und ’Zahl2’ als Ganzzahlvariable deklarieren // Deklaration einer Zeigervariablen // Initialisierung der Zeigervariablen auf einen noch nicht definierten Zeiger // ’Zahl1’ wird der Zahlenwert 100 zugewiesen // Die Zeigervariable wird auf die Adresse der Variablen ’Zahl1’ gerichtet // ’Zahl2’ wird der Inhalt der Speicheradresse zugewiesen, auf die ’Zeiger’ zeigt Das obige Beispiel zeigt die Anwendung eines W\SLVLHUWHQ=HLJHUV, d.h. eines Zeigers, der für einen bestimmten Datentyp definiert worden ist. Ein 3RLQWHUist einuntypisierter Zeigertyp, der auf eine beliebige Variable zeigen kann. Ein 3&KDU ist ein spezieller Zeiger, der auf einen sogenannten null-terminierten String zeigt. Der normale Pascal-String besteht aus einer Zeichenkette, in deren erstem Element (Position 0) die Länge des Strings steht. Auf den Positionen 1 bis N folgen dann die N Zeichen des Strings. Ein 'PChar'-String beginnt direkt an der Adresse, auf die der Zeiger zeigt, und zur Indikation des Stringendes wird der ASCII-Code "00" an die Zeichenkette angehängt, womit diese Variante der entspricht, die auch in C verwendet wird. Bei Stringoperationen ist also darauf zu achten, ob es sich um einen Pascal-String oder einen nullterminierten String handelt. Nullterminierte Strings werden als Arrays von Zeichen gespeichert. Als Index fungiert ein Integer-Wert, wobei die Elementzählung bei Null beginnt. Somit ist ein nullterminierter String ein Array der folgenden Form: DUUD\ [0..X] RI Char. Pascal-String 6 ’S’ ’o’ ’m’ ’m’ ’e’ ’r’ Endezeichen Stringlänge Nullterminierter String 'S' 'o' 'm' 'm' 'e' 'r' #00 '\QDPLVFKH$UUD\V Besonders interessant ist die Verwendung von Zeigern bei der Erstellung dynamischer Arrays; d.h. bei der Deklaration von Datenfeldern, deren Größe den Laufzeit-Verhältnissen dynamisch angepaßt werden soll. W\SH TMessWert = UHFRUG // Definition des Typs TMessWert x,y: single; // x- und y-Koordinate HQG; TAMessWert = array [1..1] of TMessWert; // Definition eines ArrayTyps vom Typ TMessWert YDU MeWe: ^TAMessWert; // Zeiger auf ein Array des Typs TAMessWert deklarieren AnzMeWe: LongInt; // Anzahl der Messwerte EHJLQ AnzMeWe := 950; // Anzahl der Messwerte zur Laufzeit GetMem (MeWe, AnzMeWe∗Sizeof(TAMessWert)); // Speicher für AnzMeWe Messwerte reservieren .. x := MeWe^[150].x; // x-Koordinate des 150. Messwertes aus dem Array auslesen y := MeWe^[150].y; // y-Koordinate des 150. Messwertes aus dem Array auslesen .. MeWe^[200].x := x ∗ 2.5; // x-Koordinate in Messwert 200 abspeichern MeWe^[200].y := y + 100 ; // y-Koordinate in Messwert 200 abspeichern FreeMem (MeWe); // Nicht mehr benötigten Speicher zum Programmende wieder freigeben HQG; 27 9DULDQW Wenn der Datentyp, der in einer Funktion oder Prozedur bearbeitet werden soll, zur Zeit der Compilierung noch nicht bekannt ist, kann der Datentyp YDULDQW benutzt werden, der zur Laufzeit jedes Datenformat annehmen kann. Den Vorteil der hohen Flexibilität erkauft man sich aber mit dem beachtlichen Speicherplatz von 16 Byte für eine Variable und deutlich längeren Rechenzeiten. YDU V1, V2, V3, V4, V5: Variant; I: Integer; D: Double; S: string; EHJLQ V1 := 1; { Integer } V2 := 1234.5678; { Real } V3 := ’Hallo Welt’; { String } V4 := ’1000’; { String } V5 := V1 + V2 + V4; { Reelle Zahl 2235,5678 } I := V1; {I=1} D := V2; { D = 1234,5678 } S := V3; { S = ’Hallo Welt’ } I := V4; { I = 1000 } S := V5; { S = ’2235,5678’ } HQG; 0HQJHQ Das reservierte Wort VHW definiert eine Menge von Elementen eines Typs. Beim Feststellen der Mengenzugehörigkeit verwendet man zur Laufzeit das reservierte Wort LQ als Bezugsoperator. W\SH TVokal = VHW of Char; YDU Vokale: TVokal; Zeichen,Vokal: char; s: string = ’abcdef’; EHJLQ Vokale := [’a’,’e’,’i’,’o’,’u’]; Zeichen := s[1]; LI Zeichen LQ Vokale WKHQ Vokal := Zeichen; HQG; // TVokal als Menge vom Typ char definieren // Eine Variable des Mengentyps deklarieren // Variable zur Aufnahme eines beliebigen Zeichens und eines Vokals // zu untersuchende Zeichenfolge // Menge der Vokale definieren // Zeichen 1 dem String entnehmen und in Variable ’Zeichen’ ablegen Abfragen ob ’Zeichen’ in der Menge der Vokale vorkommt // wenn ja, ’Zeichen’ in Vokal abspeichern .RQVWDQWHQ Variablen enthalten Werte, die sich während der Ausführung des Programms ändern können. Konstanten enthalten dagegen unveränderliche Werte, die ihren Wert zu dem Zeitpunkt erhalten, zu dem sie deklariert werden. Gerade so, wie Variablen in einer Variablendeklaration deklariert werden, werden Konstanten in einer Konstantendeklaration deklariert. Eine Konstantendeklaration beginnt mit dem reservierten Wort FRQVW, die Zuweisung wird wie bei der TypDefinition mit dem Zeichen "=" gemacht. Um sie im Quelltext besser von 'normalen' Variablen unterscheiden zu können, werden die Bezeichner oft in Großbuchstaben geschrieben (Anmerkung: PASCAL unterscheidet auch hier QLFKW zwischen Groß- und Kleinschreibung). FRQVW PI = 3.14159; ANTWORT = 342; STAMM_VERZEICHNIS = ’C:\ANWENDUNG\’; 28 $XI]lKOXQJV.RQVWDQWHQ Die Deklaration eines Aufzählungstyps verzeichnet alle Werte, die der Typ haben kann. Hier einige Beispiele für Aufzählungstypdeklarationen: W\SH TTage = (Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag, Sonntag); TAbteilung = (Finanzen, Personal, Konstruktion, Marketing, MIS); THund = (Pudel, GoldenRetriever, Dachshund, NorwegischerElkhound, Beagle); YDU Wochentag: TTage; Abteilung: TAbteilung; Hunderasse: THund; Zu jedem der in Klammern in einer Aufzählungstyp-Deklaration verzeichneten Werte gehört eine *DQ]]DKO, die durch die Position des Wertes in der Liste festgelegt ist. Zum Beispiel hat Montag in der Typdeklaration TTage den Wert 0, Dienstag hat den Wert 1 usw. man könnte das gleiche Ergebnis erhalten, wenn man die Variable Wochentag als Typ Integer deklarierten und dann einen Integer-Wert zuweisen würde, um die Wochentage zu repräsentieren. Während dieses System in geordneten und vorhersagbaren Abfolgen - wie Wochentagen oder Monaten funktionieren mag, hilft es kaum weiter, wenn die Reihenfolge der repräsentierten Werte zufällig ist. Kaum jemand kann sich merken, welche Bedeutung einer Zahl zugewiesen wurde. Die Zuweisung Hunderasse := Dachshund; ist dementsprechend aussagekräftiger als Hunderasse := 2; .RPPHQWDUH Um ein Programm zu dokumentieren und leserlich zu gestalten besteht die Möglichkeit, Kommentare in den Text einzuflechten. Da Kommentartexte nicht vom Compiler übersetzt werden dürfen, muß dieser sie erkennen können. Die folgenden Konstrukte und Kommentare werden vom Compiler ignoriert: ^ Beliebiger Text, der keine schließende geschweifte Klammer enthält ` Beliebiger Text, der kein Sternchen zusammen mit einer schließenden Klammer enthält Beliebiger Text zwischen einem doppelten Backslash und dem Ende der Zeile 6FKOHLIHQDQZHLVXQJHQ Object Pascal kennt drei Anweisungen, die Quelltext-Blöcke wiederholt ausführen, und zwar die Anweisungen UHSHDW, ZKLOH und IRU. 5HSHDW6FKOHLIH Die Anweisung UHSHDW wiederholt eine Anweisung oder eine in einen begin/end-Block eingekleidete Folge von Anweisungen, bis eine Bedingung am Ende der Schleife True ergibt. Die Anweisung beginnt mit dem reservierten Wort UHSHDW und endet mit dem reservierten Wort XQ WLO, das von der auszuwertenden Bedingung gefolgt wird. Die Bedingung ist immer ein boolescher Ausdruck. SURFHGXUH TForm1.RepeatButtonClick (Sender: TObject); YDU I: Integer; EHJLQ I := 0; // Variable auf Startwert setzen UHSHDW Beginn des „repeat“-Blocks I := I + 1; // Variable inkrementieren 29 RepeatButton.Caption := IntToStr (I); Delay (1000); XQWLO I = 10; HQG; // Beschriftung des Buttons mit der aktuellen Zahl versehen // 1 Sekunde warten // Schleife beenden, wenn Variable I den Wert 10 hat Wenn die Anwendung gestartet und die Schaltfläche Repeat angeklickt wird, werden die Zahlen 1 bis 10 als Beschriftung der Schaltfläche ausgegeben. Der boolesche Ausdruck I = 10 wird erst am Ende des Blocks repeat..until ausgewertet. Das bedeutet, daß die Anweisungen innerhalb des repeat..until-Blocks in jedem Fall ZHQLJVWHQVHLQPDO ausgeführt werden. :KLOH6FKOHLIH Während die repeat-Anweisung einen Ausdruck am Ende der Schleife auswertet, nimmt die Anweisung ZKLOH diese Prüfung am Anfang der Schleife vor. Sie beginnt mit dem reservierten Wort ZKLOH und der überprüften Bedingung, die immer ein boolescher Ausdruck sein muß. SURFHGXUH TForm1.WhileButtonClick (Sender: TObject); YDU J: Integer; EHJLQ J := 0; // Initialisierung der Schleifenvariable ZKLOH J < 10 GR Abfragebedingung prüfen EHJLQ J := J + 1; WhileButton.Caption := IntToStr (J); // Beschriftung des Buttons mit der aktuellen Zahl versehen Delay (1000); // 1 Sekunde warten HQG; HQG; Wird die Bedingung erfüllt (der Ausdruck ergibt True), wird der Quelltext in der while-Anweisung ausgeführt, bis das Ende der Anweisung erreicht und die Bedingung erneut überprüft wird. Sobald die Bedingung den Wert False annimmt, wird die Ausführung der while-Anweisung abgebrochen und die Programmausführung nach der while-Schleife fortgesetzt. Wenn die Anwendung gestartet und die Schaltfläche While angeklickt wird, wird der boolesche Ausdruck "J < 10" als erstes ausgewertet. Ergibt er True, wird der restliche Quelltext innerhalb der while-Anweisung ausgeführt und der Ausdruck anschließend erneut ausgewertet. Ergibt der Ausdruck False, wird die Ausführung der while-Anweisung abgebrochen. In dem Beispiel erscheinen also die Zahlen 1 bis 9 im Sekundenabstand als Beschriftung des angeklickten Schalters. Die while-Schleife muß also nicht wie die repeat-Schleife zwingend durchlaufen werden. )RU6FKOHLIH Bisher sind zwei Schleifentypen vorgestellt worden, die Anweisung repeat und die Anweisung while. Die Anweisung repeat wird ausgeführt, ELV eine Bedingung True ergibt, und die Anwendung while wird ausgeführt, VRODQJH eine Bedingung True ergibt. Die Anweisung IRU stellt den dritten Schleifentyp in Object Pascal dar. Der Quelltext innerhalb einer for-Schleife führt eine festgelegte Anzahl von Wiederholungen aus. Der Wert einer Steuervariablen, die tatsächlich nur ein einfacher Zähler ist, bestimmt, wie oft eine for-Anweisung ausgeführt wird. Für jede for-Schleife, die im Quelltext verwendet wird, muß eine Variable deklariert werden. Die Variable ist normalerweise ein Integertyp, kann aber auch ein Boolean- und Char-, Aufzählungs- oder Unterbereichstyp sein. Die allgemeine Syntax lautet IRU Laufvariable Startwert WR Endwert GR wenn der Endwert größer ist als der Zielwert; d.h. wenn die Laufvariable inkrementiert wird, und IRU Laufvariable Startwert GRZQWR Endwert GR wenn die Laufvariable dekrementiert werden soll. Der Absolutwert der Schrittweite der Laufva30 riablen beträgt immer 1 und ist nicht weiter einstellbar. Andere Schrittweiten müssen also mit einer while- oder repeat-Schleife realisiert werden. SURFHGXUH TForm1.ForButtonClick (Sender: TObject); YDU K: Integer; EHJLQ IRU k:=1 WR 10 GR // Schleifendefinition mit Startwert 1 und Zielwert 10 EHJLQ ForButton.Caption := IntToStr (K); // Beschriftung des Buttons mit der aktuellen Zahl versehen Delay (1000); // 1 Sekunde warten (Unterprogramm) HQG; HQG; Diese for-Anweisung definiert einen Anfangswert (1) und einen Endwert (10) für die Variable K. Wenn die Ausführung der for-Anweisung beginnt, wird K der Anfangswert zugewiesen und die Beschriftung des Schalters ausgeführt, die den aktuellen Wert von K anzeigt. Der Wert von K wird dann am Ende des for-Blocks in der end-Anweisung um eins erhöht und mit dem Zielwert verglichen. Da der neue Wert von K, jetzt 2, nicht größer als der Endwert (10) ist, wird die Beschriftung erneut ausgeführt und gibt diesmal den Wert von K als 2 aus. Dieser Vorgang wird fortgesetzt, bis der Wert von K größer wird als der Endwert 10, und die Ausführung der forAnweisung endet. :LFKWLJ: Der Wert der Steuervariablen LQQHUKDOE der Schleife darf durch Zuweisungen nicht verändert werden, da ansonsten Fehler kaum vermeidbar sind. 9HUZHQGHQYRQYHUVFKDFKWHOWHQIRU6FKOHLIHQ Eine for-Schleife in einer anderen for-Schleife zu verschachteln ist sehr nützlich, wenn Daten in einer Matrix, Tabelle oder einem Gitter angezeigt oder bearbeitet werden müssen. Dieses Beispiel verwendet das Gitternetz. Der Quelltext gibt einfache Zeilen- und Spaltentitel in den Feldern des Gitters aus und zeigt die Zeilen- und Spaltenkoordinaten mit einem Schrägstrich getrennt in jeder Zelle an. SURFHGXUH TForm1.GitterBeschriftenClick (Sender: TObject); YDU Spalte, Zeile: Integer; EHJLQ { Beschriftung der Zellen 1 bis 5 in der ersten Zeile als Spaltenüberschriften. Zelle 0 bleibt } { leer, da hier in der folgenden Schleife die Zeilenkommentare eingetragen werden. } IRU Spalte := 1 WR 5 do StringGrid1.Cells[Spalte, 0] := 'Spalte ' + IntToStr(Spalte); { Beschriftung der Zellen in der ersten Spalte als Zeilenkommentar. } { Auch hier wird Zelle 0 nicht beschrieben. } IRU Zeile := 1 WR 5 do StringGrid1.Cells[0, Zeile] := 'Zeile ' + IntToStr(Zeile); { Beschriftung der übrigen Zellen im Innern des Gitters mit der Zeilen- und Spaltenposition } IRU Spalte := 1 WR 5 do IRU Zeile := 1 WR 5 do StringGrid1.Cells[Spalte, Zeile] := IntToStr (Spalte) + ' / ' + IntToStr(Zeile); HQG; $XVZDKOGHVULFKWLJHQ6FKOHLIHQW\SV Die IRU-Schleife wird verwendet, wenn die Zahl der Schleifendurchgänge genau bekannt ist; sie ist sehr schnell und effizient. Die UHSHDWXQWLO-Schleife wird verwendet, wenn die Zahl der erforderlichen Schleifendurchgänge nicht bekannt ist, aber man genau weiß, daß die Schleife ZHQLJVWHQVHLQPDO durchlaufen werden muß. Die ZKLOHGR-Schleife wird verwendet, wenn die Zahl der erforderlichen Schleifendurchgänge unbekannt ist und die Schleife unter Umständen gar nicht ausgeführt werden muß. 31 %UHDN&RQWLQXH Die Prozedur %UHDN bewirkt, daß eine for, while oder repeat-Anweisung beendet und die Ausführung mit der nächsten Anweisung nach der Schleife fortgesetzt wird. Wird Break außerhalb eines for-, while- oder repeat-Konstrukts verwendet, gibt der Compiler eine entsprechende Fehlermeldung aus. Ist zwischen Break und dem Schleifenende ein finally-Block definiert, wird die Ausführung mit diesem fortgesetzt. Die Prozedur &RQWLQXH bewirkt, daß direkt zum Kopf des Blockes gesprungen und der nächste Durchlauf der aufrufenden for-, while- oder repeat-Anweisung ausgeführt wird. Wird Continue außerhalb eines for-, while- oder repeat-Konstrukts aufgerufen, gibt der Compiler eine entsprechende Fehlermeldung aus. %HGLQJXQJHQXQG9HU]ZHLJXQJHQ LI$QZHLVXQJ Das gebräuchlichste Mittel zur Realisierung einer einfachen Verzweigung in einem Programm ist die bedingte Abfrage. Die Syntax dieser sogenannten LI-Anweisung lautet folgendermaßen: LI Bedingung = True WKHQ EHJLQ Mach_dies; HQG HOVH EHJLQ Mach_das; HQG Prüfen der logischen Bedingung hinter if Auszuführender Block, falls die Bedingung HUIOOW ist LQGHU=HLOHYRUHOVHGDUINHLQ6HPLNRORQVWHKHQ .. andernfalls .. // Auszuführender Block, falls die Bedingung QLFKWHUIOOW ist Das Ergebnis der Bedingung muß vom Typ Boolean sein. Wenn der if-Ausdruck True ergibt, wird die auf das reservierte Wort then folgende Anweisung (Anweisungsblock) ausgeführt. Wenn der if-Ausdruck False ergibt und ein HOVH-Zweig existiert, wird die auf das reservierte Wort else folgende Anweisung ausgeführt. Fehlt der else-Zweig, wird die Programmausführung mit der Anweisung fortgesetzt, die auf die if-Anweisung folgt. Eine else-Alternative ist also QLFKW zwingend erforderlich. FDVH$QZHLVXQJ Die zweite Möglichkeit, um eine Verzweigung zu den entsprechenden Quelltext-Zeilen vorzunehmen, ist die Verwendung der FDVH-Anweisung, die besonders dann effizient eingesetzt werden kann, wenn mehrere Alternativen eines Zustandes geprüft werden müssen. Die Anweisung FDVH ist einer Folge von if-Anweisungen besonders dann vorzuziehen, wenn die auszuwertende Variable ein RUGLQDOHU Typ ist (Aufzählungstyp wie z.B. Byte oder Integer). Die Logik einer case-Anweisung ist auf Grund ihrer übersichtlichen Gestaltung normalerweise leichter zu verstehen als die von komplex geschachtelten if-Anweisungen, und darüber hinaus wird der Quelltext in case-Anweisungen schneller ausgeführt. Eine case-Anweisung besteht aus einem Ausdruck (6HOHNWRU) und einer Reihe von $QZHLVXQ JHQ. Jeder Anweisung geht entweder eine oder mehrere Konstanten (sogenannte caseKonstanten) oder das reservierte Wort HOVH voran. Der Selektor muß ordinal sein (darf also beispielsweise nicht vom Typ String sein). Alle caseKonstanten müssen ebenfalls von einem ordinalen Typ sein, der zum Typ des Selektors kompatibel ist. In einer Selektionszeile kann entweder ein einzelner Selektor aufgeführt sein, der von der folgenden Anweisung durch einen Doppelpunkt abgetrennt wird, oder aber mehrere Selektoren, die dann untereinander durch Kommata getrennt werden. Die dritte Variante ist die Angabe eines Bereiches, der durch den unteren Selektionswert und den oberen Selektionswert mit zwei dazwischenliegenden Punkten definiert wird. 32 SURFHGXUH TForm1.ZahlenTestClick (Sender: TObject); YDU Zahl: Integer; EHJLQ Zahl := StrToInt (Edit1.Text); // Zahl aus einem EditFeld lesen FDVH Zahl RI 0: Label2.Caption := 'Zahl 0'; 1, 3, 5, 7, 9: Label2.Caption := 'Ungerade einziffrige Zahl'; 0, 2, 4, 6, 8: Label2.Caption := 'Gerade einziffrige Zahl'; 10..100: Label2.Caption := 'Zwischen 10 und 100'; HOVH Label2.Caption := 'Größer als 100 oder negativ'; HQG; HQG; Zahl ist die Steuergröße der case-Anweisung // Zahlenwert 0 testen // Selektoren für ungerade einziffrige Zahl // Selektoren für gerade einziffrige Zahl // Zahl im Bereich von 10 bis 100 alle anderen Fälle // Ende-Marke des case-Blocks Wie die Anweisung if kann auch die Anweisung case optional einen HOVH-Teil enthalten, der ausgeführt wird, wenn keine der zuvor geprüften Alternativen zugetroffen hat. CaseAnweisungen enden mit dem reservierten Wort end. Wenn mehr als eine Anweisung in den Anweisungsteil (den Teil hinter dem Doppelpunkt (:)) einer case-Anweisung einzufügen ist, setzt man die mehrfachen Anweisungen zwischen die reservierten Wörter begin und end. FDVH Zahl RI 1, 3, 5, 7, 9: EHJLQ Label2.Caption := 'Ungerade Zahl'; Form1.Color := clBlue; HQG; HQG; // Selektor-Liste auszuführender Block für den Fall, daß der // Selektor zutrifft // Ende des case-Blocks 6SUXQJIXQNWLRQHQ Unbedingte Sprünge können mittels des Befehls JRWR durchgeführt werden, wobei das Sprungziel als sogenanntes /DEHO deklariert sein muß. Im Sinne einer sauberen Programmierung sollte man auf diese Hilfe aber nur zugreifen, wenn es unbedingt erforderlich ist. YDU label 10, 20; s: string; EHJLQ .. JRWR 10; ... 10: s := ’Hier ist das Sprungziel label 10’; ... HQG; $EEUHFKHQHLQHU)XQNWLRQVRGHU3UR]HGXUDXVIKUXQJ Es kann sich während der Abarbeitung einer Funktion oder Prozedur herausstellen, daß eine Weiterführung des Programmteils keinen Sinn mehr macht und ein Abbruch erfolgen kann (muß). Die einfachste Art ein Unterprogramm abzubrechen, besteht im Aufrufen der Prozedur H[LW, die die gleiche Wirkung hat wie der Befehl 'break' in einer Schleife. Trifft das Programm auf den Befehl, springt es sofort auf die end-Zeile der Funktion oder Prozedur und beendet diese damit. Alle Variablen im Kopf des Unterprogramms behalten dabei ihre aktuellen Werte. Es empfiehlt sich also bei Vorhandensein eines exit-Befehls, die Ergebniswerte der Funktion oder Prozedur YRU diesem Befehl zu initialisieren. 33 'HOSKL)XQNWLRQVNDWDORJ Der Delphi-Funktionskatalog ist erreichbar über den Menupunkt "Hilfe / VCL-Referenz / VCL Objekt- und Komponenten-Referenz", in dem das Kapitel "VCL Alphabetische Liste der Routinen" den Zugriff auf die zur Verfügung stehenden Funktion ermöglicht. Die Funktionen sind hier in alphabetischer Reihenfolge geordnet. Die wichtigsten Funktionen sind im folgenden nach )XQNWLRQVJUXSSHQ aufgelistet. Um nähere Informationen über die zu verwendende Funktion zu erhalten, muß der Funktionsname lediglich im Quelltext eingetippt und F1 gedrückt werden. Artverwandte Begriffe lassen sich leicht auffinden, wenn der Funktionsname in der Stichwortsuche (Index) eingetippt wird, da zu der aktuell eingegebenen Zeichenfolge automatisch eine Positions-Korrektur in der Liste der zur Verfügung stehenden Indexwörter vorgenommen wird. $ULWKPHWLNXQG0DWKHPDWLN Abs gibt einen absoluten Wert (Betrag) zu einer Zahl zurück ArcCos berechnet den inversen Cosinus des übergebenen Arguments ArcCosh berechnet den Kehrwert des hyperbolischen Cosinus ArcSin berechnet den inversen Sinus des Arguments ArcSinh berechnet den inversen hyperbolischen Sinus des Arguments ArcTan berechnet den Arcustangens des Arguments ArcTanh berechnet den inversen hyperbolischen Tangens des Arguments Cos berechnet den Cosinus Cosh berechnet den hyperbolischen Cosinus Cotan berechnet den Cotangens eines Winkels CycleToRad wandelt eine Winkelgröße von Kreiszyklen in Bogenmaß um Dec dekrementiert eine Variable um 1 oder N DegToRad konvertiert einen in Grad angegebenen Winkel in das Bogenmaß Exp gibt die Potenz von X zurück Floor rundet Variablen ab FPower10 multipliziert einen Wert mit der angegebenen Potenz von 10 Frac gibt den Nachkommaanteil einer reellen Zahl zurück High gibt den größten Wert im Bereich des Arguments zurück Hypot berechnet die Länge der Hypotenuse in einem rechtwinkligen Dreieck Inc inkrementiert eine Variable um den Wert 1 oder N Int gibt den ganzzahligen Anteil einer reellen Zahl zurück 34 IntPower gibt das Ergebnis von Basis (Parameter Base) hoch Exponent zurück Ln gibt den natürlichen Logarithmus eines Real-Ausdrucks zurück Lo gibt das niederwertige Byte eines Integer-Werts zurück Log10 berechnet den Logarithmus zur Basis 10 (dekadisch) Log2 berechnet den Logarithmus zur Basis 2 LogN berechnet den Logarithmus zur Basis N Hi gibt das höherwertige Byte einer Integerzahl als vorzeichenlosen Wert zurück. Low gibt den kleinsten Wert eines bestimmten Datentyps zurück MaxIntValue gibt den größten vorzeichenbehafteten Wert in einem Integer-Array zurück MaxValue gibt den größten vorzeichenbehafteten Wert eines Arrays zurück Mean gibt den Mittelwert der Elemente eines Arrays zurück MeanAndStdDev berechnet den Mittelwert und die Standardabweichung der Elemente eines Arrays MinIntValue liefert den kleinsten vorzeichenbehafteten Wert eines Integer-Arrays zurück MinValue gibt den kleinsten vorzeichenbehafteten Wert eines Arrays zurück Ord gibt den Ordinalwert eines Ausdrucks des Typs Ordinal zurück Pi gibt den Wert von Pi zurück (3,1415926535897932385) Poly wertet ein einheitliches Polynom einer Variable für den Wert X aus Power errechnet aus der Basis Base und dem beliebigen Wert Exponent die Potenz RadToCycle wandelt einen im Bogenmaß angegebenen Winkel in Kreiszyklen um RadToDeg konvertiert einen Winkel vom Bogen- in das Gradmaß RadToGrad konvertiert Winkel vom Bogenmaß in das Neugradmaß RandG generiert anhand der Gaußschen Normalverteilung eine Zufallszahl Random erzeugt eine Zufallszahl innerhalb eines bestimmten Bereichs Randomize initialisiert den Zufallszahlengenerator mit einem zufälligen Wert Sin gibt den Sinus des mit X angegebenen Winkels im Bogenmaß (Rad) zurück SinCos gibt Sinus und Cosinus eines Winkels zurück. SinCos ist doppelt so schnell wie der getrennte Aufruf von Sin und Cos für denselben Winkel Sinh berechnet den hyperbolischen Sinus eines Winkels Sqr gibt das Quadrat eines Wertes zurück Sqrt gibt die Quadratwurzel eines Werts zurück StdDev gibt die Standardabweichung der Elemente eines Arrays zurück Sum... Funktionen zur Berechnung von Summenausdrücken Tan berechnet den Tangens Tanh berechnet den hyperbolischen Tangens Variance berechnet die statistische Varianz der Werte eines Arrays 'DWHLYHUZDOWXQJ BlockRead liest einen oder mehrere Datenblöcke aus einer geöffneten Datei in eine Variable ein BlockWrite schreibt ein oder mehrere Datensätze aus einer Variablen in eine geöffnete Datei ChangeFileExt ändert die Namenserweiterung einer Datei. ChDir wechselt das aktuelle Verzeichnis. CreateDir legt ein neues Verzeichnis an. DeleteFile löscht eine Datei und gibt im Fehlerfall False zurück. DirectoryExists ermittelt, ob ein bestimmtes Verzeichnis existiert. 35 DiskFree gibt die Anzahl der freien Bytes auf einem Laufwerk zurück. DiskSize gibt die Größe eines Laufwerks in Byte zurück. Eof prüft, ob das Dateiende erreicht ist. Eoln prüft, ob das Zeilenende erreicht ist. ExtractFileDir extrahiert Laufwerks- und Verzeichnisinformationen aus dem angegebenen Dateinamen. ExtractFileDrive extrahiert die Laufwerksangabe aus dem angegebenen Dateinamen. ExtractFileExt extrahiert die Namenserweiterung aus dem angegebenen Dateinamen. ExtractFileName extrahiert den Namen und die Erweiterung aus dem angegebenen Dateinamen. ExtractFilePath extrahiert Laufwerk- und Verzeichnisinformationen aus dem angegebenen Dateinamen. File... Mit dem Schlüsselwort FILE beginnen eine ganze Reihe an Dateifunktionen GetCurrentDir gibt den Namen des aktuellen Verzeichnisses zurück. GetDir ermittelt das aktuelle Verzeichnis eines bestimmten Laufwerks. MkDir legt ein neues Unterverzeichnis an. PasswordDialog zeigt ein Dialogfeld an, in dem der Benutzer zur Eingabe eines Kennworts für den Zugriff auf eine lokale, kennwortgeschützte Tabelle aufgefordert wird. RemoveDir löscht ein vorhandenes leeres Verzeichnis. Rename ändert den Namen einer externen Datei. Reset öffnet eine vorhandene Datei. Rewrite erstellt eine neue Datei und öffnet sie anschließend. SelectDirectory zeigt ein Dialogfeld an, in dem der Benutzer einen Verzeichnisnamen eingeben kann. SetCurrentDir legt das aktuelle Verzeichnis fest und liefert nach erfolgreicher Ausführung True zurück. 'DWXPXQG=HLW Date ermittelt das aktuelle Datum DateTimeToStr konvertiert einen TDateTime-Wert in einen String. DateToStr konvertiert eine Variable des Typs TDateTime in einen formatierten String. DayOfWeek gibt für ein bestimmtes Datum den Wochentag zurück. DecodeDate zerlegt einen TDateTime-Wert in Jahr, Monat und Tag. DecodeTime zerlegt einen TDateTime-Wert in Stunden, Minuten, Sekunden und Millisekunden. EncodeDate setzt aus den angegebenen Jahres-, Monats- und Tageswerten einen Wert des Typs TDateTime zusammen. EncodeTime setzt aus den angegebenen Stunden-, Minuten-, Sekunden- und Millisekundenwerten einen Wert des Typs TDateTime zusammen. FormatDateTime formatiert einen Datums-/Zeitwert. IsLeapYear gibt an, ob es sich bei einem bestimmten Jahr um ein Schaltjahr handelt. Time gibt die aktuelle Uhrzeit zurück. TimeToStr konvertiert einen TDateTime-Wert in einen String. 'LDORJH MessageDlg zeigt in der Mitte des Bildschirms ein Dialogfeld mit einer Meldung an. MessageDlgPos blendet ein Meldungsdialogfeld an den angegebenen Bildschirmkoordinaten ein. ShowMessage zeigt ein Meldungsfenster mit dem angegebenen Text der Schaltfläche OK an. ShowMessageFmt zeigt ein Dialogfeld mit einer formatierten Meldung und der Schaltfläche OK an. 36 )RUPDWLHUXQJXQG.RQYHUWLHUXQJ CurrToStr konvertiert einen Währungswert in einen String. CurrToStrF konvertiert einen Währungswert in einen String mit dem angegebenen Format. FloatToDecimal konvertiert eine Gleitkommazahl in den entsprechenden Dezimalwert. FloatToStr konvertiert eine Gleitkommazahl in den entsprechenden String-Wert. FloatToStrF konvertiert eine Gleitkommazahl in einen String-Wert mit dem angegebenen Format, der Genauigkeit und den Stellen. FloatToText konvertiert einen Gleitkommawert in die entsprechende Dezimaldarstellung mit dem angegebenen Format, der Genauigkeit und den Stellen. FloatToTextFmt konvertiert eine Gleitkommazahl in eine Dezimaldarstellung mit dem angegebenen Format. Format gibt einen formatierten String zurück, der sich aus einem Pascal-Format-String und einer Reihe von Array-Argumenten ergibt. FormatFloat formatiert einen Gleitkommawert. IntToHex gibt einen String in hexadezimaler Darstellung des angegebenen Integer-Wertes zurück. IntToStr konvertiert einen Integer-Wert in einen String. Round rundet den Gleitkomma-Wert von X auf den nächsten Integer-Wert. Trunc konvertiert eine Gleitkommazahl in einen Integer-Wert. 6SHLFKHUYHUZDOWXQJ AllocMem weist einen Speicherblock zu und initialisiert jedes Byte mit Null. Dispose gibt den für eine dynamische Variable reservierten Speicher frei. FreeMem gibt eine dynamische Variable von einer bestimmten Größe aus dem Speicher frei. GetMem erzeugt eine dynamische Variable und einen Zeiger auf ihre Speicheradresse. Move kopiert eine bestimmte Anzahl Bytes von der Quelle Source in das Ziel Dest. New erzeugt eine neue dynamische Variable und einen Zeiger P, der auf diese Variable zeigt. Mit der Standardprozedur Dispose kann die Variable wieder freigegeben werden. Im Gegensatz zu 'GetMem' ist der Speicherbedarf bei 'New' bekannt. Der Vorteil der Funktion gegenüber einem Array besteht in alten 16-Bit-Systemen darin, daß eine mit 'New' deklarierte Variable wesentlich weniger Speicherplatz auf dem (auf 64k-Byte begrenzten) lokalen Heap benötigt. 6WULQJRSHUDWLRQHQ Bei den zur Verfügung stehenden Stringoperationen ist immer darauf zu achten, ob es sich um Pascal-Strings oder Nullterminierte Strings handelt. Zur Unterscheidung werden die Funktionen, die Nullterminierte Strings behandeln, mit dem Schlüsselwort 'Ansi' eingeleitet. Ansi... Mit dem einführenden Wort ‚Ansi...‘ bietet Delphi eine ganze Palette an Stringfunktionen zur Behandlung Nullterminierter Strings vom Typ Pchar an. Unter dem Menupunkt "Hilfe / Suche über Schlüsselwort..." braucht also lediglich das Stichwort 'ansi' eingegeben zu werden, um die Liste die zur Verfügung stehenden Funktionen einsehen zu können. AppendStr fügt einen String an einen vorhandenen String an. CompareStr vergleicht Strings unter Berücksichtigung der Groß-/Kleinschreibung. CompareText vergleicht zwei Strings ohne Berücksichtigung der Groß-/Kleinschreibung. Concat verknüpft zwei oder mehr Strings zu einem einzigen String. Copy gibt einer Stringvariablen einen Teil-String eines Strings zurück. Delete entfernt einen Teilstring aus einem String. Length gibt die Anzahl der Zeichen eines Strings zurück. Pos gibt den Indexwert (Position) des ersten Zeichens innerhalb des angegebenen Teil-Strings zurück, der in einem String vorkommt. 37 SetLength legt die dynamische Länge einer String-Variablen fest. Str konvertiert einen numerischen Wert in einen formatierten String. StrAlloc reserviert Speicher für einen nullterminierten String und gibt einen Zeiger auf die Adresse des ersten Zeichens zurück. Ist der Speicherbedarf bereits vor der Compilierung bekannt, kann der Speicher über die Deklaration auch als 'array [..] of Char' reserviert werden. StrCat hängt eine Kopie von Source an das Ende von Dest an und gibt den zusammengefügten String zurück. Zur Längenprüfung verwenden Sie die Funktion StrLCat. StrComp vergleicht die beiden Strings Str1 und Str2. Verwenden Sie bei der Arbeit mit internationalen Zeichen statt dessen AnsiStrComp. StrCopy kopiert den Inhalt von Source nach Dest und gibt einen Zeiger auf Dest zurück. Soll beim Kopieren die Länge überprüft werden, verwenden Sie statt dessen die Funktion StrLCopy. StrDispose ist nur aus Gründen der Abwärtskompatibilität vorhanden und entfernt einen String vom Heap, der zuvor mit StrAlloc oder StrNew zugewiesen wurde. StrLen gibt die Anzahl der Zeichen in einem String zurück. StrMove kopiert eine bestimmte Anzahl Zeichen in einen String. StrPas konvertiert einen nullterminierten String in einen Pascal-String. StrPCopy kopiert einen Pascal-String in einen nullterminierten String. StrPos durchsucht einen String nach einem bestimmten Teilstring. StrScan sucht nach dem ersten Vorkommen eines bestimmten Zeichens in einem String. StrToDate konvertiert einen String in einen Datumswert. StrToDateTime konvertiert einen String in einen TDateTime-Wert. StrToFloat konvertiert einen String in einen Gleitkommawert. StrToInt konvertiert einen String in einen Integer-Wert. StrToTime konvertiert einen String in einen Zeitwert. Str... sonstige Funktionen zur Behandlung von Stringketten TextToFloat konvertiert einen nullterminierten String in einen Gleitkommawert. Trim entfernt alle am Anfang und Ende eines Strings vorhandenen Leer- und Steuerzeichen. UpperCase konvertiert einen String in Großbuchstaben. Val konvertiert einen String in einen numerischen Wert. =HLJHU$GUHVVLHUXQJXQG6RQVWLJHV Addr ... gibt die Adresse eines beliebigen Variablen-, Prozedur- oder Funktionsbezeichners zurück. Ptr konvertiert eine Adresse in einen Zeiger. Beep generiert einen Standard-Signalton, der über den Computer-Lautsprecher ausgegeben wird Chr gibt das Zeichen zurück, das dem entsprechenden ASCII-Wert entspricht. Chr(64) wäre also der Buchstabe 'A'. Printer gibt eine globale Instanz von TPrinter zurück, mit der der Drucker verwaltet und als Komponente angesprochen werden kann. Unter globaler Instanz kann man in diesem Zusammenhang eine variable Komponente bezeichnen, die den Zugriff auf den Drucker in der Form erlaubt, als handele es sich bei ihm um eine Canvas-Eigenschaft. Screen gibt eine globale Instanz von TScreen zur Bearbeitung des Bildschirms und der zur Verfügung stehenden Parameter zurück, wie z.B. die Bildschirmauflösung. SizeOf gibt die Anzahl der von einer beliebigen Variablen belegten Bytes zurück. Die Funktion ist besonders wertvoll zur dynamischen Ermittlung der Größe von Records. 38 0HWKRGHQ Methoden sind Funktionen und Prozeduren, die in einer Klasse mit einer Komponente zusammengefaßt sind. Diese Eigenschaft stellt die wesentliche Erweiterung gegenüber den artverwandten Records dar und bildet die Grundlage der objektorientierten Programmierung. *UDILNHQ Das Erstellen von Grafiken und Zeichnungen erfolgt mit Hilfe der Komponenteneigenschaft „Canvas (Leinwand)“, die für verschiedene Komponenten (z.B. Formular, PaintBox, Image, ...) zur Verfügung steht. (LJHQVFKDIWHQYRQ&DQYDV Pixels Setzt oder liest die Farbe der Pixel innerhalb des aktuellen Clipping-Rechtecks. Alle vorgefertigten Zeichenmethoden bauen auf dieser Eigenschaft auf. Pen legt fest, welchen Stift die Zeichenfläche zum Zeichnen von Linien und Umrissen verwendet. Farbe, Strichstärke und Strichart können mit dieser Eigenschaft definiert werden. Für alle Parameter sind Konstante vordefiniert, die durch Drücken der F1-Taste auf dem Wort 'Pen' im Quelltext eingesehen werden können. Brush Legt fest, welche Farbe und welches Muster die Zeichenfläche zum Füllen von graphischen Formen und Hintergründen verwendet. Font Legt fest, welche Schriftart bei der Ausgabe von Text im Bildbereich verwendet wird. PenPos gibt die gegenwärtige Position des Stifts als x- und y-Koordinate wieder. 0HWKRGHQ Arc Zeichnet einen Bogen entlang der Peripherie einer Ellipse, die von dem angegebenen Rechteck umgeben wird. Chord Zeichnet einen geschlossenen Umriß, der von einer Linie und einer Ellipse begrenzt wird. Ellipse Zeichnet auf der Zeichenfläche eine Ellipse, die durch ein umgebendes Rechteck definiert ist. LineTo Zeichnet ausgehend von der aktuellen Stiftposition (PenPos) eine Linie zum Punkt (X,Y) und setzt PenPos anschließend auf (X, Y). MoveTo Macht den Punkt (X,Y) zur aktuellen Zeichenposition (PenPos). Pie Zeichnet einen Abschnitt der Ellipse, die durch das Rechteck (X1, Y1) und (X2, Y2) begrenzt ist. Polygon Zeichnet eine Reihe von Linien auf der Zeichenfläche, die die als Parameter übergebenen Punkte der Reihe nach verbinden. Eine Linie vom letzten zum ersten Punkt schließt den Umriß. Polyline Zeichnet mit dem aktuellen Stift eine Reihe von Linien, indem die im Parameter Points übergebenen Punkte miteinander verbunden werden. Rectangle Zeichnet ein Rechteck mit der linken oberen Ecke am Punkt (X1, Y1) und der rechten unteren Ecke am Punkt (X2, Y2). TextOut Gibt beginnend am Punkt (X,Y) einen String auf der Zeichenfläche aus und setzt die Eigenschaft PenPos auf das Ende des Strings. Der Punkt x,y kennzeichnet die obere linke Ecke des Textfensters. TextRect gibt einen String innerhalb eines Clipping-Rechtecks aus. TextHeight Gibt die Höhe eines Strings, der in der aktuellen Schriftart ausgegeben wird, in der Einheit Pixel zurück. TextWidth gibt die Breite eines Strings, der in der aktuellen Schriftart ausgegeben wird, in der Einheit Pixel zurück. TextHeight und TextWidth ermöglichen damit die dynamische Anpassung von Beschriftungsfeldern an die aktuell verwendete Zeichengröße oder Bildschirmauflösung. 39 'DWHQEDQNDQZHQGXQJHQ Um unter Delphi mit einer Datenbank arbeiten zu können, sind die Komponenten TTable und TDataSource erforderlich. Mit Hilfe von 77DEOH können Sie über die Borland Database Engine (BDE) auf Daten in einer Datenbanktabelle zugreifen. TTable bietet direkten Zugriff auf jeden Datensatz und jedes Feld der zugrundeliegenden Datenbanktabelle. Dabei kann es sich um eine Paradox-, dBASE-, Access-, FoxPro-, eine ODBC-konforme oder eine SQL-Datenbank auf einem Remote-Server handeln (wie InterBase, Oracle, Sybase, MS SQL Server, Informix oder DB2). Mit 7'DWD6RXUFH können Sie eine Verbindung zwischen einer Datenmenge und den datensensitiven Steuerelementen herstellen, mit denen die der Datenmenge zugrundeliegenden Daten angezeigt und bearbeitet werden können. Die rein visuelle Darstellung erfolgt über die Komponenten der Gruppe „Datensteuerung“, wie z.B. das Tabellengitter '%*ULG. Um sich in den Zeilen und Spalten einer Tabelle zu bewegen, sowie Datensätze bearbeiten zu können, stellt die Komponente 7'%1DYLJDWRU ein einfach zu bedienendes Hilfsmittel dar. Die beiden letzt genannten sind zur Bearbeitung einer Tabelle aber nicht unbedingt erforderlich. Um den Signalfluß von TTable über TDataSource nach TDBGrid und TDBNavigator zu ermöglichen, müssen folgende Eigenschaften im Objektinspektor definiert werden: .RPSRQHQWH (LJHQVFKDIW )XQNWLRQVEHVFKUHLEXQJ TTable DatabaseName Pfad der Datenbanktabelle TableName Name der Datei, die die Tabelle enthält Active Öffnen oder Schließen der Datei TDataSource DataSet Name der TTable-Komponente, deren Datenbankdatei verwaltet und angesteuert werden soll TDBGrid DataSource Name der DataSource, die dargestellt werden soll TDBNavigator DataSource Name der DataSource, die angesteuert werden soll Die grundlegende Tabellenbearbeitung erfolgt über die Eigenschaften und Methoden von TTable. (LJHQVFKDIWHQ Active True: Tabelle ist geöffnet (entspricht der Methode OPEN) False: Tabelle ist geschlossen (entspricht der Methode CLOSE) EOF Mit EOF (End Of File) können Sie feststellen, ob sich der Cursor auf einem Datensatz einer Datenmenge befindet. Hat EOF den Wert True, befindet sich der Cursor hinter der letzten Datenzeile der Datenmenge. FieldCount Gibt die Anzahl der Feldkomponenten in einer Datenmenge an und entspricht damit der Anzahl der Spalten in einer matrixförmigen Tabelle.. Fields Mit Fields können Sie auf die Feldkomponenten einer Datenmenge über deren Indexnummern zugreifen. Z.B.: Wert := Table1.Fields[0].Value FieldValues Ermöglicht den Zugriff auf alle Feldwerte im aktuellen Datensatz der Datenmenge. ReadOnly Gibt an, ob eine Tabelle in dieser Anwendung bearbeitet werden kann. Mit der Eigenschaft 'ReadOnly' läßt sich ein sehr flexibel zu definierender Schreibschutz aufbauen. 40 RecNo Gibt den aktuellen Datensatz der Datenmenge an. Mit einer Vorgabe an ’RecNo’ kann der Cursor auch auf einen Datensatz positioniert werden. RecordCount gibt die Gesamtzahl der Datensätze in einer Datenmenge an. 0HWKRGHQ Append Append fügt einen neuen leeren Datensatz am Ende der Datenmenge hinzu. Zum Anhängen eines Datensatzes an das Ende der Tabelle wird der Tabellencursor auf die erste freie Zeile am Ende der Tabelle gesetzt. Die Tabelle befindet sich damit automatisch im Editiermodus AppendRecord fügt einen neuen Datensatz mit Daten für alle Feldelemente eines Records am Ende der Datenmenge hinzu und trägt ihn in die Datenbank ein. Close Durch einen Aufruf der Methode Close wird die Eigenschaft Active einer Datenmenge auf False gesetzt. Die Datenmenge wird daraufhin geschlossen und kann nicht mehr für den Zugriff auf die zugrundeliegende Datenbank verwendet werden (identisch zu Active := False) Create Mit dem Aufruf von Create kann eine in einer Anwendung deklarierte Tabelle instantiiert werden, d.h. es wird eine neue Tabelle angelegt, deren Struktur von einer bereits vorhandenen Tabelle abkopiert wird, und die natürlich vorhanden und zugänglich sein muß. DatabaseName Laufwerk und Pfad, in dem die Tabelle sich befindet. Delphi bietet für diese Eigenschaft auch sogenannte 'Aliase' an, über die einem kompletten Pfad eine prägnante Kurzbezeichnung zugewiesen werden kann. Delete löscht den aktuellen Datensatz und setzt den Cursor auf die nächste Zeile. DeleteTable löscht und entfernt eine vorhandene Datenbanktabelle DisableControls Mit DisableControls können Sie die Datenanzeige in den datensensitiven Steuerelementen deaktivieren, bevor Sie eine große Anzahl von Datensätzen in einer Schleife verarbeiten. Auf diese Weise können Sie den ständigen Bildaufbau in den Steuerelementen während der Iteration verhindern und die Verarbeitung beschleunigen, da die Anzeige nicht laufend aktualisiert werden muß. Edit Mit Edit können Sie das Bearbeiten des aktuellen Datensatzes einer Datentabelle ermöglichen. EmptyTable Die Methode EmptyTable löscht sämtliche Datensätze aus der Datenbanktabelle, die mit den Eigenschaften DatabaseName und TableName angegeben wird. Im Gegensatz zu 'Deletetable' bleibt die leere Datenbank aber bestehen. Find... Suchfunktionen in einer Datenrabelle First Der Tabellenzeiger wird auf das erste Datenrecord plaziert GetFieldNames ruft eine Liste mit den Namen der Felder in einer Datenmenge ab. Insert fügt einen neuen leeren Datensatz in eine Datenmenge ein. Last setzt den Cursor auf den letzten Datensatz einer Datenmenge. LockTable sperrt eine Paradox- oder dBASE-Tabelle zum Lesen und/oder Schreiben. MoveBy positioniert den Cursor in einer Datenmenge um eine bestimmte Anzahl Datensätze vor oder zurück. Next Der Tabellenzeiger wird um ein Record weiterbewegt Open öffnet eine Datenmenge (identisch zu Active := True). Post schreibt einen geänderten Datensatz in die Datenbank. Das Editieren eines Datensatzes wird damit beendet Prior setzt den Cursor auf den vorhergehenden Datensatz einer Datenmenge. RecNo gibt die Nummer des aktuellen Datensatzes der Datenmenge an. Refresh aktualisiert eine Datenmenge durch erneutes Abrufen der Daten aus der Datenbank. RenameTable benennt die Paradox- oder dBASE-Tabelle um, die mit dieser Tabellenkomponente verknüpft ist. TableName Name der Tabelle UnlockTable entfernt eine vorher zugewiesene Sperre von einer Paradox- oder dBASE-Tabelle. 41 $EODXIVWHXHUXQJ Unter einer ereignisorientierten Programmieroberfläche werden Prozeduren durch ein beliebiges Ereignis angestoßen und laufen anschließend bis zu ihrer Terminierung, d.h. dem Erreichen der letzten end-Anweisung, ab. Weitere Aktionen anderer Prozeduren können demzufolge erst erfolgen, wenn die vorherige Prozedur abgearbeitet worden ist. Für die in einer Endlosschleife laufende Steuerungs-Funktion bedeutet das aber, daß sie alle anderen Aktivitäten blockiert und das Programm z.B. nicht mehr auf eine neue Aktion reagieren kann. Das sich hier einstellende Problem ist an und für sich die grundlegende Problematik der parallelen Abarbeitung unterschiedlicher Prozeduren, und da Windows kein Echtzeit-Betriebssystem ist, erfordert das Parallel-Tasking einen recht beträchtlichen Aufwand, was das MessageRouting innerhalb der eigenen Anwendung angeht. Dieser Aufwand läßt sich für viele Anwendungen aber umgehen, wenn man die von Delphi zur Verfügung gestellte Timer-Komponente verwendet. Timer-Komponente Eigenschaften der TimerKomponente Durch den Timer aufgerufene Prozedur Die Steuerung eines kontinuierlich ablaufenden Prozesses, der aber auch zu jedem Zeitpunkt über den Anwender beeinflußbar bleiben soll, erfolgt zu diesem Zweck über die TimerKomponente aus der Gruppe „System“, die eine Prozedur in einem frei definierbaren Zeitraster regelmäßig aufruft und abarbeitet. Das Aufrufintervall kann allerdings nicht beliebig klein gewählt werden, da der Timer in die Taskliste des Betriebssystems eingereiht und von diesem verwaltet wird. Für die kleinste Zeitscheibe muß man sich unter WindowsNT daher mit 10 Millisekunden begnügen. Für größere Geschwindigkeitsansprüche muß weiterhin auf die nicht ganz unproblematische Interrupt-Programmierung zurückgegriffen werden. Der abzuarbeitende Gesamt-Prozeß wird zu diesem Zweck in kleine Teilprozesses aufgeteilt, die im Zeitscheibenverfahren zyklisch abgearbeitet werden. Während des Wechsels von einem Teilprozeß zum nächsten besteht dann für das Programm die Möglichkeit, auf extern anliegende Ereignisse, wie z.B. einen Mausklick, zu reagieren. Das grundlegende Schema eines 'zerlegten' Prozesses ist im Prinzip eine case Anweisung, in der während der zyklischen Abarbeitung immer die Funktion ausgeführt wird, die durch den Ablauf-Selektor bestimmt ist. Die 'Schalterstellung' des Selektors erfolgt dabei während der Abarbeitung der einzelnen Unterprogramme. Für kompliziertere Steuerungen können durchaus mehrere Timer eingesetzt werden, die ein zeitscheiben-orientiertes Paralleltasking erlauben. Die Verwendung des Timers soll am Beispiel einer kamerabasierten Stopfen-Erkennungsanlage für Automobilfelgen demonstriert werden. Die Aufgabe der Prüfeinrichtung besteht darin, Kunststoffhülsen zu erkennen, die nicht aus den Anschraublöchern der aus der Lackiererei kommenden Felgen entfernt worden sind. Im Grunde genommen handelt es sich um eine Steuerung, die über den zentralen Sensor 'Kamera' realisiert worden ist. Typisch für eine derartige Steuerung ist das Einlesen der Eingangssignale vor dem case-Block und das Setzen der Ausgangssignale nach der Abarbeitung des case-Blocks. 42 SchiebeWeiche Kamera Kamera-Messzelle Transport-Rollgang aus der Lackiererei Messrechner mit Monitor Auslauf für NIO-Teile Pneumatischer Zylinderstopper Lichtschranke Auslauf für IO-Teile {-------------------------------------------------------------------------------------------------------------------------} { *** Ablauf-Steuerung für eine Stopfenerkennungsanlage*** } {-------------------------------------------------------------------------------------------------------------------------} SURFHGXUH TFBV.AblaufTimerTimer (Sender: TObject); begin 5HDG'LJLWDO,Q; case Ablauf of $E1LFKWV: AufStartEreignisWarten; $E%LOG$XIQDKPH: KamerabildAufnehmen; $E%LOG$XVZHUWXQJ: CalculateStopfenLoch; $E6WRHUXQJ: begin DigOut [ARollgang] := False; { Rollgang stoppen } DigOut [ABetrieb] := False; { Ablaufbetrieb stoppen } if FehlerAnzRadIO then HandleAnzRadIO; if FehlerTimeOut then HandleTimeOut; if FehlerRadOhneResult then HandleRadOhneResult; end; end; &KHFN(QGVFKDOWHU; &KHFN7LPH2XW)HKOHU; &DOFXODWH'LJLWDO2XW; 6KRZ6\VWHP6WDWXV; :ULWH'LJLWDO2XW; end; 43 7RROV 'HEXJJHU Zur Analyse von Programmfehlern bietet Delphi einen sehr leistungsfähigen Debugger an, der eine schrittweise Ausführung des Programmes erlaubt, während der die Inhalte der einzelnen Variablen eingesehen und für Testzwecke auch editiert werden können. Zum Debuggen eines Programmes erfolgt vor dessen Start das Setzen eines +DOWHSXQNWHV durch Anklicken der grauen Leiste am linken Rand des Unit-Fensters. Die Zeile mit dem Haltepunkt erscheint rot hinterlegt (je nach Farbdefinition im Menupunkt "Tools / Umgebungsoptionen .. / Farben") und erhält am linken Rand einen roten Markierungspunkt. Das Programm wird später bei seiner Ausführung an dieser Position stoppen (der Textcursor blinkt in dieser Zeile), und die interessierenden Variablen können in der Liste der EHUZDFKWHQ $XVGUFNH dargestellt werden. Geöffnet wird die Liste mit dem Menu-Befehl "Ansicht / Überwachte Ausdrücke". fi0: 0,528 a0:37,455 b0:37,672 c0:108,334 d0:92,449 fi0:0,528 Um eine neue Variable in die Liste aufzunehmen, klickt man mit der Maus in das Fenster und drückt die Taste (LQIJ ; eine andere Möglichkeit ist, den Textcursor im Quelltext auf die Variable zu positionieren und 6WUJ) zu drücken. Das Positionieren des Textcursors auf die Variable vor dem Drücken der Funktionstaste erspart es, den Variablennamen im Editierfenster extra einippen zu müssen, da die Variable beim Cursor automatisch im Editor angeboten wird. Zum Entfernen eines Variablenwertes aus der Liste, klickt man diesen mit der Maus an und drückt anschließend die Taste (QWI . Nach dem Stop des Programms am Haltepunkt hat man die Möglichkeit, das Programm mit ) normal weiterlaufen zu lassen, oder kann es schrittweise weiter abarbeiten. Die VFKULWWZHLVH $EDUEHLWXQJ erfolgt mit den Funktionstasten ) oder ). Der Unterschied zwischen den beiden Funktionen kommt nur zum Tragen, wenn der Debugger auf einer Quelltextzeile steht, die wiederum eine Funktion oder Prozedur aufruft. Mit F8 wird die Funktion oder Prozedur mit einem Schritt als Block abgearbeitet, mit F7 springt der Debugger in die Funktion oder Prozedur hinein und arbeitet hier schrittweise weiter. Mehrere Befehle auf einmal lassen sich abarbeiten, indem man den Cursor auf die Quelltextzeile positioniert, an der das Programm wieder stoppen soll und anschließend die Funktionstaste ) drückt. Diese Verfahrensweise ist besonders vorteilhaft, wenn Schleifen überprüft werden sollen. 44 Die einfachste Art und Weise, den Inhalt einer Variablen vorübergehend darzustellen besteht darin, den Mauscursor auf die Variable zu bewegen und dort einfach für ca. 2 Sekunden stehen zu lassen. Der Inhalt der Variablen wird in einem gelben Fenster dargestellt; das verschwindet, sobald man die Maus wieder bewegt. Bei Arrays und Record-Variablen kann man unterschiedliche Darstellungen erreichen, je nachdem wo man den Mauszeiger im Variablennamen positioniert. Ein Variableninhalt läßt sich für Testzwecke im Debugger-Modus auch ändern, indem der Menupunkt "Start / Auswerten/Ändern ..." oder 'Strg F7' 'DWHQEDQNREHUIOlFKH Wie man mit einer Datenbank-Tabelle arbeitet, ist in den grundlegenden Zügen in Abschnitt 5.2 angerissen worden. Allerdings gehen die dort aufgeführten Operationen davon aus, daß mit einer bereits bestehenden Dantenbank-Tabelle gearbeitet werden kann. Das Erstellen einer eigenen Datenbank geht am einfachsten mit der %RUODQG'DWHQEDQNREHU IOlFKH, die über den Menupunkt "Tools / Datenbankoberfläche" aufgerufen werden kann. Der nächste Schritt zur Erstellung einer Datenbank erfolgt dann bereits auf dem Formular der Datenbankoberfläche mit dem Menupunkt "Datei / Neu / Tabelle ...". In einem Fenster kann aus einer Liste der 7DEHOOHQW\S selektiert werden, der als Gerüst für die Datenbanktabelle verwendet werden soll. Nach der Typvorgabe erscheint das eigentliche Eingabefenster, um die )HOG HOHPHQWH der Tabelle entsprechend den Erfordernissen definieren zu können. In einer zweidimensionalen Tabelle könnte man die Felddefinitionen mit den Spalteninhalten der Tabelle identifizieren. Mit dem Schalter 'Speichern unter ...' kann die nun angelegte Tabelle DEJHVSHLFKHUW und in der Delphi-Anwendung verwendet werden, indem die Eigenschaften 'DataBaseName' und 'TableName' mit dem Pfad und dem Namen der Tabelle belegt und die Eigenschaft 'Active' auf True gesetzt wird. %LOGHGLWRU Eine grafische Bedienoberfläche lebt von aussagekräftigen Grafikelementen, wie sie z.B. als Symbole für Schaltflächen eingesetzt werden. Das Einfügen eines Grafikelements in die Anwendung erfolgt über die Eigenschaft der Komponente, die das Grafikelement verwaltet. Bei einem Image wäre das die Eigenschaft 3LFWXUH , beim SpeedButton die Eigenschaft *O\SK . Nach dem Anklicken dieser Eigenschaft läßt sich eine vorbereitete Grafik über ein dialoggeführtes Menufenster in die Komponente einfügen. Das Grafikelement ist von nun an Bestandteil der Komponente. Der einzige Nachteil dieser Methode ist, daß man die Grafik, so wie sie angeboten wird, akzeptieren muß. Relativ häufig kommt es vor, daß man eine bereits bestehende Grafik nur ein klein wenig ändern möchte, und an dieser Stelle bietet der Bildeditor seine Dienste an. Er ist ein pixelorientiertes Malprogramm und entspricht in vielen Zügen dem weit verbreiteten 'PaintBrush'. Die Grafik, die als Vorlage verwendet werden soll, wird in den Bildeditor geladen und kann hier nach eigenen Wünschen geändert und unter einem anderen Namen gespeichert werden. Die geänderte Grafik wird dann über die bildverwaltende Eigenschaft in die Komponente eingebunden. Etwas mehr Aufwand bereitet es, wenn keine adäquate Vorgabe vorhanden ist. In diesem Fall muß die Größe für eine neue Grafik im Bildeditor vorgegeben werden, und in das vom Bildeditor angebotene leere Fenster eine komplett neue Bitmap gemäß den eigenen Vorstellungen gezeichnet werden. Auch diese Grafik wird unter einem eigenen Namen gespeichert und kann anschließend in die Komponente eingeladen werden. 45 /LWHUDWXU Programmieren lernen in Borland Delphi 3 Walter Doberenz / Thomas Kowalski, Carl-Hanser-Verlag, 1998, ISBN 3-446-19219-0 Das große Buch zu Delphi Data Becker, Arthur Burda, Günther Färber, Wiener Verlag, ISBN 3-8158-1107-4 Borland Delphi – Das Buch Tewi Verlag, 1995, ISBN 3-89362-408-2 46