(7+Zürich Institut für Wissenschaftliches Rechnen Dr. H. Hinterberger Sommersemester 1999 Programmieren und Problemlösen Die visuelle Programmierumgebung von Delphi Zusammenfassung für Übung 5 Die visuelle Programmierumgebung von Delphi H. Hinterberger, J. Lindenmeyer 1 Die Symbolleiste Die Symbolleiste mit ihren 14 Symbolen ist von der rechts neben ihr plazierten Komponentenpalette zu unterscheiden: Während alle Symbolleisten-Schalter zu einem Hauptmenübefehl äquivalent sind, gibt es zur Auswahl der einzelnen Komponenten aus der Palette mit der Maus keine direkte alternative Zugriffsmöglichkeit. Eine alphabetische Auflistung aller Komponenten befindet sich unter dem Menüpunkt ANSICHT → KOMPONENTENLISTE (siehe Menüs der Entwicklungsumgebung). Die Symbolleiste Die Symbolleiste erlaubt per Mausklick den schnellen Zugang zu einer Reihe von Funktionen, die alle auch über die herkömmlichen Menüs zugänglich sind. Wird mit der Maus über die Symbolleiste oder die Komponentenpalette gefahren, so öffnen sich Pop-up-Fenster mit Informationen über die Funktionen der Symbole. Projekt öffnen: Dieser Schalter ist identisch zum Menüpunkt DATEI → ÖFFNEN. Projekt speichern. Dieser Schalter ist identisch zum Menüpunkt DATEI → ALLES SPEICHERN. Datei zum aktuellen Projekt hinzufügen: Dieser Schalter ist identisch zu demjenigen im Projekt-Manager mit demselben Symbol. Datei vom aktuellen Projekt entfernen: Hinzufügen oder entfernen einer Quelltext-Einheit bewirkt auch das Hinzufügen oder Entfernen des dadurch codierten Formulars. Datei öffnen: Laden einer Quelltext-Einheit und automatisch auch des dazugehörigen Formulars. Datei speichern: Speichern des aktuellen Quelltextes. Auswählen einer Einheit aus einer Liste aller Einheiten im aktuellen Projekt. Auswählen eines Formulars aus einer Liste aller Formulare im aktuellen Projekt. Umschalter: Erlaubt das Umschalten zwischen dem aktuellen Formular und dem dazugehörigen Quelltext. Neues Formular (und damit assoziierten Quelltext): Dieser Schalter ist identisch zu demjenigen im Projekt-Manager mit demselben Symbol. Formulare, die so erstellt werden, werden dem ganzen Projekt hinzugefügt. 2 2 Die Komponentenpalette Mit Delphi können komplexe Dialogfenster sehr einfach durch Zusammenstellen von Komponenten auf einem Formular entwickelt werden. Die Komponentenpalette enthält alle Komponenten, die in die Formulare eingezeichnet werden können. Beim Verweilen des Mauszeigers über einer Komponente wird deren Name in einer Pop-Up-Sprechblase ersichtlich. Aufgrund der grossen Zahl der Komponenten sind sie thematisch gegliedert und auf mehrere Seiten verteilt, wobei die einzelnen Seiten durch einen Mausklick auf die Seitenbeschriftung (Registerzunge) aufgerufen werden können: Auf der Seite Standard befinden sich alle Standardkontrollelemente von Windows, die auch von vielen andern Windows-Anwendungen benutzt werden: z.B. Listenfenster, Beschriftungen (Labels), Eingabefelder (Edit-Komponente) und Markierungsschalter. Auf den andern Seiten folgen die Komponenten, die speziell für Delphi programmiert sind, also nicht jeder Windows-Anwendung gleichermassen zur Verfügung stehen. Zusätzlich: Hier befinden sich weitere häufig ausgewählte Komponenten wie der Bitmap-Schalter (ganz links) sowie der Speedbutton (2. von links), der in Symbolleisten wie derjenigen von Delphi vorkommt. Win95 enthält ausschliesslich Komponenten für Steuerelemente, die von Windows 95 neu eingeführt worden sind: z.B. Baumansichten, Komponenten zum Zusammenstellen mehrseitiger Dialogboxen und Statuszeilen. Datenzugriff: Hier befinden sich die Datenbankkomponenten von Delphi, mit denen Verbindungen zu Datenbanken und zu Datenbankservern aufgebaut werden können. Datensteuerung: Damit kann der Inhalt einer Datenbank auf vielfältige Weise angezeigt und editiert werden. Win3.1: Hier liegt unter anderem die Komponente für mehrseitigeDialogboxen. Diese Seite ist wichtig für die Kompatibilität mit Delphi 1. 3 Internet stellt Funktionen zur Einbindung dieses weltweiten Computernetzes zur Verfügung. Dialoge: Diese Seite enthält 8 Komponenten, welche die von Windows vordefinierten Standarddialoge "verpacken", z.B. der in Aufgabe 3 gebrauchte Font-Dialog zur Auswahl von Schriftart und -grösse. System enthält neben speziellen Listen zur Anzeige von Dateien, Laufwerken und Verzeichnissen auch die in Aufgabe 3 gebrauchte Komponente "Timer", welche Systemereignisse kontrolliert. Zusätzlich besteht die Möglichkeit zur Installation neuer Komponenten (KOMPONENTE→ INSTALLIEREN (siehe Menüs der Entwicklungsumgebung) oder zum Austausch bereits installierter Komponenten zwischen den einzelnen Seiten (KOMPONENTE→ PALETTE KONFIGURIEREN (siehe Menüs der Entwicklungsumgebung). 3 Der Objektinspektor Der Objektinspektor listet alle Eigenschaften und Ereignisse einer ausgewählten Komponenten auf. Jede Komponente und jedes Formular verfügt über eine Vielzahl an veränderbaren Eigenschaften, von denen die meisten im Objektinspektor verändert werden können. Jedes Fenster, das zur Laufzeit des Programms auf Grundlage dieses Formulars erstellt wird, enthält nun nicht nur dessen Komponenten, sondern auch dessen Werte der Eigenschaften (z.B. Farbe). Die Daten der Komponenten verteilen sich im Objektinspektor auf die beiden Seiten Eigenschaften und Ereignisse. Beide bestehen jeweils aus einer zweispaltigen Liste, die sich mit einer Bildlaufleiste bewegen lässt. Die erste Spalte gibt den Namen des Eigenschaft, resp. des Ereignisses an (z. B. "Caption": Beschriftung, oder "OnClick": Reaktion auf einen Mausklick), die zweite Spalte enthält den jeweiligen Wert, falls einer eingegeben wurde. Alle Komponenten haben Eigenschaften und die meisten können auch auf Ereignisse reagieren. 4 Da ein Grossteil der Komponenten von Windows vorgegeben werden, reduziert sich der Aufwand von Delphi. Als Nebeneffekt der grossen Freiheit, die Windows in der Gestaltung der Komponenten zulässt, haben die Komponenten oft grosse Mengen an festzulegenden Werten. Delphi vereinfacht hier durch das Setzen von Standardwerten. So müssen die Eigenschaften im Objektinspektor nur geändert werden, wenn sie andere Werte besitzen sollen. (Wenn der Schalter z.B. nicht mehr standardmässig "Button1" sondern neu "OK" heissen soll.) 4 Der Formulardesigner Eine Serie von gleichmässig plazierten Punkten bildet ein Raster, das eine ausgerichtete Plazierung von Komponenten auf einem Formular wesentlich erleichtert: Beim visuellen Entwurf einer Delphi-Anwendung liegt der Mittelpunkt des Interesses auf dem Formular. Der Formulardesigner liefert zur Entwurfszeit die Übersicht, wie das Formular zur Laufzeit aussehen wird. Auf dem Formulardesigner als Arbeitsfläche können während der Entwurfszeit mit den visuellen Werkzeugen der Entwicklungsumgebung Komponenten im Formular plaziert und deren Eigenschaften im Objektinspektor eingestellt werden. Werden im Objektinspektor Attribute des Formulars und seiner Bestandteile geändert, so passen diese meistens ihr Aussehen entsprechend an (z. B. die Farbe, die Schriftart etc.). Alle auf der Komponentenpalette verfügbaren Komponenten können ausgewählt und einem Formular hinzugefügt werden. Die Ausrichtungspalette (Menü ANSICHT→ AUSRICHTUNGSPALETTE (siehe Menüs der Entwicklungsumgebung)) ermöglicht weiteren Einfluss auf das Formular. Verschiedene Einrichtungen der Delphi-Entwicklungsumgebung (Objektinspektor, Komponentenpalette, Ausrichtungspalette, BEARBEITEN-Menu) arbeiten mit der EntwurfszeitVersion des Formulars zusammen und bilden mit dieser den Formulardesigner. 5 Der Quelltexteditor Nach dem Aufstarten von Delphi befindet sich der Quelltexteditor hinter dem von ihm codierten Formular des Formular-Designers. Für das bis jetzt leere Formular enthält der Quelltexteditor Standard-Deklarationen und Programmstrukturen in objektorientiertem Pascal. Die Statuszeile am unteren Rand des Quelltexteditor-Fensters informiert über die aktuelle Position des Cursors, den verändert-/gespeichert-Status und über den Einfügungs-Modus. In der Bewegung der Eingabemar5 kierung, der Bedienung der Bildlaufleisten und dem Markieren von Text sowie den Zwischenablageoperationen hält sich der Quelltexteditor von Delphi weitgehend an den WindowsStandard. Delphi erstellt für jedes Formular, das erzeugt wird, eine eigene Object Pascal-Datei. Diese Datei trägt den speziellen Namen "Unit". Eine Unit ist eine Textdatei, die von Delphi als Instruktionssammlung gebraucht wird, um mit dem Compiler ein Programm zu erstellen. Allgemein werden Units dazu verwendet um die Eigenschaften und das Verhalten von Formularen zu definieren. Jedoch können auch Units erstellt werden, die nichts mit Formularen zu tun haben, sondern nur dazu dienen das Programm in überschaubarere Einheiten zu gliedern. Eine weitere Massnahme zur besseren Übersicht über die einzelnen Quelltext-Dateien ist die Vergabe von geeigneten Dateinamen für die Units (z.B. Wecker.pas statt Unit1.pas). 6 Die Projektverwaltung Jedes Delphi-Programm kann, wie herkömmliche Pascal-Projekte, nicht nur eine Vielzahl gleichberechtigter Units, sondern darüber hinaus ein Hauptmodul besitzen, das nach dem Programmstart als erstes die Kontrolle übernimmt (das Hauptmodul wird nicht als Unit bezeichnet). In vielen Computersprachen gibt es Projektdateien, die dem Entwickler und dem Entwicklungssystem einen Überblick über alle Module des Projekts geben. In Delphi ist es nicht notwendig, dafür eine eigene Datei anzulegen: Das Hauptmodul ist die Projektdatei und trägt daher die Endung .DPR (für Delphi PRoject). Sie wird von Delphi automatisch verwaltet, kann aber auch vom Programmierer verändert werden. Einsicht in die Projektdatei erhält man durch Auswahl des Menüpunktes ANSICHT → PROJKET-QUELLTEXT (siehe Abbildung 9). Alle Units tragen die Endung .PAS (für PAScal; Quelltext-Datei). Darüber hinaus muss Delphi den Aufbau der Formulare speichern und verwendet dazu binäre Dateien mit der Endung .DFM (für Delphi ForM). Für jedes Projekt gibt es also eine einzige .DPR-Datei und für jedes Formular ein Dateipaar, bestehend aus einer .DFM-Datei und einer .PAS-Unit. Dies sind die Dateien, die standardmässig im Fenster der Projektverwaltung angezeigt werden. Im Windows Explorer werden zusätzlich Delphi-Dateien mit folgenden Dateiendungen angezeigt: .exe .res, .dof .~pa ausführbare Binärcode-Datei Delphi Ressourcen-Dateien Sicherungskopie der entsprechenden Quelltext-Datei (.pas) Obwohl das Hauptprogramm bereits als Projektdatei dient, gibt es in Delphi zusätzlich ein Projektfenster, das unter ANSICHT→PROJEKTVERWALTUNG (siehe Abbildung 9) zum Vorschein gebracht wird: 6 Das Fenster besteht im wesentlichen aus einer Liste, die den Inhalt der Projektdatei tabellarisch darstellt. Wenn der Inhalt des Projektfensters verändert wird, passt Delphi diese Datei automatisch an. Umgekehrt kann nach einer Veränderung der Projektdatei das Projektfenster durch den Schalter zum Aktualisieren (am "i" erkennbar) auf den neusten Stand gebracht werden. 7 Die Hilfefunktionen Delphi bietet verschiedene Hilfsinformationen an: • Zu den Schaltern der Symbolleiste und zu den Komponenten zeigt Delphi Hilfsinformationen in kleinen Hinweisfenstern an. Diese erscheinen dann, wenn sich der Mauszeiger eine kurze Zeit über einem Element der Entwicklungsumgebung bewegt. • In Delphi 2.0 sind alle Hilfedateien (Haupt-Hilfedatei, Hilfe zur Komponentenentwicklung und Hilfe zur Windows-Programmierschnittstelle) in einem gemeinsamen, hierarchischen Inhaltsverzeichnis zusammengefasst. Dieses wird über das Menü HILFE→HILFETHEMEN (siehe Menüs der Entwicklungsumgebung) aufgerufen (unten links). • Um bei der Programmierung schnelle Hilfe zu einer bestimmten Komponente zu erhalten, kann aus dem Editor heraus mit STRG + F1 Delphis Online-Sprachreferenz aufgerufen werden. Delphi schlägt dann die Seite der Hilfedatei auf, die das Wort an der Cursorposition beschreibt (unten rechts). 7 Für weitergehende Beschreibungen der Entwicklungsumgebung von Delphi und zur Vertiefung spezieller Kenntnisse sei auf die Fachliteratur im Literaturverzeichnis des Vorlesungsskripts verwiesen. 8 Die Menüs der Entwicklungsumgebung von Delphi 4.0 Das anschliessende Verzeichnis dient als Übersicht über die einzelnen Punkte der Menüs der Entwicklungsumgebung: 8 9 Eine Beispielanwendung Programmierung eines Weckers In diesem Beispiel entwickeln Sie schrittweise einen Wecker, der auf ihrem Bildschirm läuft und über eine grafische Benutzeroberfläche gesteuert werden kann. Nennen Sie ihr Projekt "Wecker". Ihr Bildschirmwecker sollte zur Erfüllung dieser Aufgabe a) funktionieren, und b) etwa folgendermassen aussehen: Links sehen Sie die Laufzeitansicht und rechts das Alarmfenster, das durch den Wecker erzeugt wird. Entwerfen Sie ihre eigene Benutzeroberfläche, denken Sie dabei aber an die Benutzerinnen und Benutzer Ihres Programms. Die Enwurfsansicht für das Formularoben links sieht wie folgt aus: Erstellen einer Uhr Delphi stellt mit der Funktion "Time" eine Funktion zur Verfügung, mit der die Systemzeit abgefragt werden kann. Allerdings wird das Resultat der Funktion in dem für uns nichtssagenden Format "TDateTime" dargestellt. Mit der Funktion "TimeToStr" kann dieses Format in das für uns übliche Format HH:MM:SS umgewandelt werden. 9 Um eine einfache Uhr zu erhalten fügen Sie dem Formular als erstes die folgenden beiden Komponenten hinzu: • • Ein Label (aus der Palette "Standard") für die Anzeige der Uhrzeit Einen Timer (aus der Palette "System") um mit der Funktion "Time" die Systemzeit abfragen zu können. Setzen Sie mit Hilfe des Objektinspektors für die obigen beiden Komponenten die folgenden Eigenschaften: Komponente Formular Label Timer Eigenschaft Name Caption Name Alignment AutoSize Caption Name Interval Wert WeckerFormular Bildschirmwecker Zeitanzeige taCenter False Jetzt kommt gleich die Zeit... Timer 1000 Doppelklicken Sie im Objektinspektor unter den Ereignissen für den Timer das "OnTimer"-Feld an und fügen Sie im Quelltexteditor in die angezeigte Prozedur "TWeckerFormular.TimerTimer" die Zeile Zeitanzeige.Caption := TimeToStr(Time); ein. Wählen Sie nun im Menu "Start" die Option "Start" oder drücken Sie in der Symbolleiste die grüne "Play"-Taste. Sie sollten nun eine lauffähige Uhr haben. Ändern der Anzeigeschrift Brechen Sie das laufende "Uhr"-Programm nun wieder ab, indem Sie auf das "Fenster-schliessen"Kreuz rechts oben im Programmfenster klicken oder im Menu "Start" die Option "Programm zurücksetzen" wählen. Da verschiedene Leute je nach Geschmack und Sehkraft verschiedene Zifferblätter bevorzugen, sollten Sie in ihre Uhr noch einen Schriftwahlschalter einbauen. Dazu benötigen Sie aus der Standardpalette einen "Button" und aus der Dialogpalette einen "FontDialog". Der FontDialog soll auch den Namen "FontDialog" tragen. Der Button soll den Namen "FontButton" und die Beschriftung (=Caption) "Schriftart verändern" tragen. Auf das Ereignis "OnClick" des FontButtons sollen folgende Anweisungen durchgeführt werden (ohne Zahlen): FontDialog.Font := Zeitanzeige.Font; FontDialog.Execute; Zeitanzeige.Font := FontDialog.Font; Erklärung des obigen Programmcodes: 1) Die Standardeinstellungen des FontDialogs werden von der aktuellen Zeitanzeige übernommen. 2) Der Benutzer kann Font-Einstellungen durchführen. (3): Die Zeitanzeige übernimmt die durchgeführten Font-Einstellungen. Führen Sie das Programm aus und wählen Sie eine Schriftart und -grösse, die angenehm lesbar ist (z. B. Arial, 12 Punkt). Können Sie die Zeitanzeige noch lesen? Was müssen Sie anpassen? Uhr + Alarm = Wecker Das bestehende Formular mit der Uhr soll nun zu einem Wecker ausgebaut werden. Dazu benötigen Sie noch je eine Komponente zur Eingabe und zur Beschriftung: Edit (Name: "AlarmEdit"; Text: " ") und Label (Caption: "Weckzeit"). Das Label dient zur Beschriftung des Edit-Feldes. Um der 10 Edit-Komponente zur Laufzeit des Programmes den Tastaturfokus zu geben, muss das Formular noch die Eigenschaft "ActiveControl: AlarmEdit" erhalten. Die Methode für das Ereignis "OnTimer" des Timers wird nun ergänzt durch folgende zwei Zeilen: if IstWeckzeit (AlarmEdit.Text) then Weckmeldung(’Rrring!!! Alarm zur Zeit ’+AlarmEdit.Text); Die Funktion "IstWeckzeit" und die Prozedur "Weckmeldung" müssen Sie im Gegensatz zu z.B. "TimeToStr" selbst schreiben. Schreiben Sie dazu im Implementationsteil der Unit folgende Methoden: function TWeckerFormular.IstWeckzeit(Alarm: string): Boolean; begin IstWeckzeit := Alarm = Zeitanzeige.Caption; end; und procedure TWeckerFormular.Weckmeldung(Alarm: string); begin BringToFront; MessageBeep(MB_ICONEXCLAMATION); MessageDlg(Alarm, mtInformation, [mbOK], 0); end; und deklarieren Sie die eingeführte Funktion und die Prozedur im "private"-Bereich der Deklarationen: function IstWeckzeit (Alarm: string): Boolean; procedure Weckmeldung (Alarm: string); Starten Sie nun das Programm und geben Sie eine sekundengenaue Weckzeit ein. Letzte Verbesserungen In der vorliegenden Version kann der Wecker in Zeiten hoher Systemauslastung mal eine Sekunde "übersehen". Wenn dies zur Alarmzeit passiert, wird kein Alarm ausgelöst. Versuchen Sie einmal, den Wecker zu überlisten. Ausserdem hat die vorliegende Version noch mehr Nachteile: Erstens ist es umständlich, die Weckzeit sekundengenau angeben zu müssen und zweitens ist es überflüssig, dass Vergleiche auch dann stattfinden, wenn noch keine Alarmzeit eingegeben wurde. Ausserdem hilft Ihnen die Komponente "Checkbox" (Name: "AlarmEin") die Alarmfunktion des Weckers einund auszuschalten und ihn somit eleganter steuern zu können. Beheben Sie diese Nachteile! Hinweise: Eine leere Zeichenkette (String) wird durch 2 Hochkommata ('') dargestellt. Benutzen Sie die Funktion "StrToTime", die eine Zeichenkette in einen Wert vom Typ "TdateTime" umwandelt, damit Sie Zahlen und nicht Zeichenketten vergleichen. Dazu deklarieren Sie in der Funktion "IstWeckzeit" vor dem "begin" die Variable Var Weckzeit : TDateTime; 11