Sprach-Übersicht
Nach oben zu Delphi-Sprachreferenz - Index
Delphi ist eine höhere Compiler-Sprache mit strenger Typisierung, die eine strukturierte und objektorientierte Programmierung ermöglicht. Sie basiert auf Objekt Pascal. Zu ihren Vorzügen gehören einfache Lesbarkeit, schnelle Compilierung und modulare Programmierung durch Verteilen des Quelltextes auf mehrere Unit-Dateien. Delphi verfügt über spezielle Leistungsmerkmale, die das Komponentenmodell und die visuelle Entwicklungsumgebung von Embarcadero unterstützen. In den Beschreibungen und Beispielen dieser Sprachreferenz wird davon ausgegangen, dass Sie die Embarcadero-Entwicklungstools verwenden.
Die meisten Entwickler, die mit Software-Entwicklungstools von Embarcadero arbeiten, schreiben und compilieren ihre Programme in der integrierten Entwicklungsumgebung (IDE). Hier kümmert sich das Entwicklungstool um viele Details, die beim Einrichten von Projekten und Quelltextdateien von Bedeutung sind (z. B. Verwalten der Abhängigkeiten zwischen den Units). Dabei gelten Regeln bezüglich der Programmorganisation, die aber nicht zur Sprachdefinition von Object Pascal gehören. So werden beispielsweise bestimmte Namenskonventionen für Dateien und Programme verwendet, an die Sie aber nicht gebunden sind, wenn Sie Programme außerhalb der IDE schreiben und in der Befehlszeile compilieren.
Im allgemeinen geht diese Sprachreferenz davon aus, dass Sie in der IDE arbeiten und Anwendungen mithilfe der Embarcadero-VCL (Visual Component Library) erstellen. Wo es erforderlich ist, wird jedoch zwischen Delphi-spezifischen Regeln und der normalen Programmierung mit Object Pascal unterschieden. Beschrieben werden die Delphi-Compiler für Win32 und für die .NET-Plattform. Auf plattformspezifische Unterschiede und Funktionen wird bei Bedarf hingewiesen.
Dieser Abschnitt enthält Informationen zu folgenden Themen:
- Programmorganisation. Eine Beschreibung der grundlegenden Leistungsmerkmale der Sprache, die das Aufteilen einer Anwendung in Units und Namespaces ermöglichen.
- Beispielprogramme. Kurze Beispiele für Konsolen- und GUI-Anwendungen veranschaulichen die Verwendung des Befehlszeilen-Compilers.
Inhaltsverzeichnis
Programmorganisation
Delphi-Programme werden normalerweise auf mehrere Quelltextmodule (so genannte Units) verteilt. Die meisten Programme beginnen mit einer program-Kopfzeile, in der der Programmname angegeben wird. Darauf folgt eine optionale uses-Klausel und ein Block von Deklarationen und Anweisungen. Mit der uses-Klausel geben Sie die Units an, die in das Programm eingebunden werden. Units können von mehreren Programmen gemeinsam benutzt werden und verfügen häufig über eigene uses-Klauseln.
Die uses-Klausel liefert dem Compiler Informationen über die Modulabhängigkeiten. Da diese Abhängigkeiten in den Modulen selbst gespeichert werden, benötigen die meisten Delphi-Programme keine Make-Dateien, Header-Dateien oder #include-Präprozessordirektiven.
Delphi-Quelltextdateien
Der Compiler erwartet Delphi-Quelltexte in einem der folgenden Dateitypen:
- Unit-Quelltextdateien mit der Namenserweiterung .PAS
- Projektdateien mit der Namenserweiterung .DPR
- Package-Quelltextdateien mit der Namenserweiterung .DPK
In den Unit-Quelltextdateien befindet sich in der Regel der größte Teil des Programmcodes. Jede Anwendung besteht aus einer Projektdatei und mehreren Unit-Dateien. Die Projektdatei entspricht dem Hauptprogramm im herkömmlichen Pascal und organisiert die Units der Anwendung. Embarcadero-Entwicklungstools verwalten für jede Anwendung automatisch eine Projektdatei.
Wenn Sie ein Programm in der Befehlszeile compilieren, können Sie den gesamten Quelltext in Unit-Dateien (.PAS) aufnehmen. Erstellen Sie die Anwendung jedoch mithilfe der IDE, wird eine Projektdatei (.DPR) angelegt.
Package-Quelltextdateien ähneln Projektdateien, werden aber für spezielle, dynamisch ladbare Bibliotheken (so genannte Packages) verwendet.
Weitere Anwendungsdateien
Embarcadero-Produkte verwenden neben den Quelltextmodulen auch die folgenden Dateitypen, die keinen Pascal-Code enthalten und ebenfalls automatisch von der IDE verwaltet werden:
- VCL-Formulardateien mit der Namenserweiterung .DFM (Win32) oder .NFM (.NET)
- Ressourcendateien mit der Namenserweiterung .RES
- Projektdateien mit der Namenserweiterung .DOF
Eine VCL-Formulardatei enthält die Beschreibung der Eigenschaften des Formulars und seiner Komponenten. Sie repräsentiert ein Formular, das normalerweise einem Fenster oder Dialogfeld in einer Anwendung entspricht. Formulardateien können in der IDE als Text angezeigt und bearbeitet und danach entweder im Text- oder im Binärformat gespeichert werden. (Das Textformat eignet sich hervorragend zur Versionskontrolle.) Obwohl Formulardateien standardmäßig als Text gespeichert werden, ist eine manuelle Bearbeitung nicht üblich. Normalerweise werden dazu die visuellen Tools von Embarcadero verwendet. Jedes Projekt hat mindestens ein Formular. Zu jedem Formular gehört eine Unit-Datei (.PAS), die standardmäßig denselben Namen wie die Formulardatei erhält.
Zusätzlich zu den VCL-Formulardateien verwendet jedes Projekt eine Ressourcendatei (.RES), in der das Anwendungssymbol und andere Ressourcen, wie Strings, gespeichert werden. Diese Datei erhält automatisch denselben Namen wie die Projektdatei (.DPR).
Die Projektoptionsdatei (.DOF) enthält Compiler- und Linker-Einstellungen, Suchpfadinformationen, Versionsinformationen usw. Diese Datei erhält automatisch denselben Namen wie die Projektdatei (.DPR). Die Einstellungen in dieser Datei können im Dialogfeld Projektoptionen festgelegt werden.
Verschiedene Tools in der IDE speichern Daten in speziellen Dateitypen. Desktop-Konfigurationsdateien (.DSK) enthalten Informationen über die Anordnung der Fenster und andere Konfigurationseinstellungen. Desktop-Einstellungen können projektspezifisch sein oder für die gesamte Umgebung gelten. Die Desktop-Konfigurationsdateien haben keine direkten Auswirkungen auf die Compilierung.
Vom Compiler generierte Dateien
Wenn Sie eine Anwendung oder ein Package zum ersten Mal erstellen, generiert der Compiler für jede im Projekt verwendete Unit eine compilierte Unit-Datei (.DCU für Win32 ). Diese Dateien werden dann zu einer ausführbaren Datei bzw. zu einem gemeinsam genutzten Package gelinkt. Bei der ersten Erstellung eines Package wird für jede im Package enthaltene neue Unit eine Datei erstellt. Danach generiert der Compiler eine .DCP- und eine Package-Datei. Wenn der Befehlszeilenschalter GD verwendet wird, generiert der Linker eine Map- und eine .DRC-Datei. Die .DRC-Datei enthält String-Ressourcen und kann in eine Ressourcendatei compiliert werden.
Beim Erstellen eines Projekts wird eine Unit nur dann erneut compiliert, wenn ihre Quelltextdatei (.PAS) seit dem letzten Compilieren geändert wurde, die zugehörige .DCU/.DPU-Datei nicht gefunden werden kann, der Compiler explizit dazu angewiesen wird oder das Interface der Unit von einer anderen Unit abhängig ist, die geändert wurde. Wenn der Compiler auf die entsprechende compilierte Unit-Datei zugreifen kann und die Unit nicht von anderen Units abhängig ist, die geändert wurden, wird die Quelltextdatei der Unit nicht benötigt.
Beispielprogramme
Die folgenden Beispielprogramme zeigen die Grundzüge der Programmierung mit Delphi. Es handelt sich um einfache Anwendungen, die nicht in der IDE, sondern nur in der Befehlszeile compiliert werden können.
Eine einfache Konsolenanwendung
Das folgende Beispiel zeigt eine einfache Konsolenanwendung, die Sie in der Befehlszeile compilieren und ausführen können.
program greeting;
{$APPTYPE CONSOLE}
var
MyMessage: string;
begin
MyMessage := 'Hello world!';
Writeln(MyMessage);
end.
Durch die erste Anweisung wird das Programm Greeting deklariert. Die Direktive {$APPTYPE CONSOLE} teilt dem Compiler mit, dass es sich um eine Konsolenanwendung handelt, die in der Befehlszeile ausgeführt wird. In der nächsten Zeile wird die String-Variable MyMessage deklariert (in Delphi gibt es echte String-Datentypen). Im Programmblock wird der Variable MyMessage der String "Hello world!" zugewiesen. Anschließend wird die Variable mit der Standardprozedur Writeln an die Standardausgabe gesendet. (Writeln ist implizit in der Unit System definiert, die automatisch in jede Anwendung eingebunden wird).
Sie können nun das Programm in eine Datei mit dem Namen greeting.pas oder greeting.dpr eingeben und dann compilieren:
dcc32 greeting
Hiermit erhalten Sie eine ausführbare Win32-Datei.
Die ergebende ausführbare Datei gibt die Meldung Hello world! auf dem Bildschirm aus.
Neben seiner Einfachheit unterscheidet sich dieses Beispiel noch in anderen wichtigen Punkten von den Anwendungen, die Sie normalerweise mit Embarcadero-Entwicklungstools erstellen. Zum einen handelt es sich bei dem Beispiel um eine Konsolenanwendung. Mit Embarcadero-Entwicklungstools werden hauptsächlich Anwendungen mit grafischen Benutzeroberflächen entwickelt, in denen natürlich keine Writeln-Aufrufe benötigt werden. Außerdem befindet sich das gesamte Beispielprogramm (abgesehen von Writeln) in einer einzigen Datei. Bei einer typischen GUI-Anwendung steht der Programmkopf (im Beispiel die erste Zeile) in einer separaten Projektdatei, die mit Ausnahme einiger Routinenaufrufe keinerlei Programmlogik enthält.
Ein komplexeres Beispiel
Das Programm im nächsten Beispiel ist auf zwei Dateien verteilt, eine Projektdatei und eine Unit-Datei. Die Projektdatei, die Sie unter dem Namen greeting.dpr speichern können, hat folgenden Inhalt:
program greeting;
{$APPTYPE CONSOLE}
uses
Unit1;
begin
PrintMessage('Hello World!');
end.
In der ersten Zeile wird das Programm greeting deklariert, das wiederum eine Konsolenanwendung ist. Über die Klausel uses Unit1; wird dem Compiler mitgeteilt, dass das Programm greeting von einer Unit namens Unit1 abhängig ist. Zum Schluss wird die Prozedur PrintMessage mit dem String Hello World! aufgerufen. Die Prozedur PrintMessage ist in Unit1 definiert. Unit1 hat folgenden Inhalt (speichern Sie sie unter dem Namen Unit1.pas):
unit Unit1;
interface
procedure PrintMessage(msg: string);
implementation
procedure PrintMessage(msg: string);
begin
Writeln(msg);
end;
end.
Unit1
definiert eine Prozedur namens PrintMessage
, die einen String als Argument übernimmt und diesen String an die Standardausgabe sendet. (In Delphi heißen Routinen ohne Rückgabewert Prozeduren. Routinen, die einen Wert zurückgeben, heißen Funktionen.)
Beachten Sie, dass PrintMessage
zweimal in Unit1
deklariert ist. Die erste Deklaration im interface-Abschnitt macht PrintMessage
für andere Module verfügbar (z. B. für das Programm greeting
), die Unit1
einbinden. Durch die zweite Deklaration (im implementation-Abschnitt) erfolgt die eigentliche Definition der Prozedur PrintMessage
.
Sie können greeting
nun in der Befehlszeile compilieren:
dcc32 greeting
Hiermit erhalten Sie eine ausführbare Win32-Datei.
Unit1
braucht in der Befehlszeile nicht angegeben zu werden. Der Compiler liest beim Bearbeiten von greeting.dpr
automatisch die Unit-Dateien ein, von denen greeting
abhängig ist. Die neue ausführbare Datei führt dieselbe Operation durch wie im ersten Beispiel, gibt also die Meldung Hello world!
aus.
Eine VCL-Anwendung
Als nächstes erstellen wir eine Anwendung mithilfe von VCL-Komponenten (VCL, Visual Component Library) in der IDE. Im Programm werden die automatisch generierten Formular- und Ressourcendateien verwendet. Es kann daher nicht allein aus dem Quelltext compiliert werden. Das Beispiel zeigt einige wichtige Merkmale von Delphi. Neben mehreren Units werden auch Klassen und Objekte verwendet.
Die Anwendung besteht aus einer Projektdatei und zwei neuen Unit-Dateien. Betrachten wir zuerst die Projektdatei:
program greeting;
uses
Forms, Unit1, Unit2;
{$R *.res} { Diese Direktive linkt die Ressourcendatei des Projekts. }
begin
{ Aufruf der globalen Application-Instanz Application
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.Run;
end.
Unser Programm heißt auch diesmal greeting. Es werden drei Units eingebunden: Forms ist ein Bestandteil der VCL, Unit1 gehört zum Hauptformular der Anwendung (Form1) und Unit2 zu einem weiteren Formular (Form2).
In Programm finden mehrere Aufrufe des Objekts Application statt, das eine Instanz der in Forms deklarierten Klasse Vcl.Forms.TApplication ist (für jedes Projekt wird automatisch ein Application-Objekt erstellt). Die Methode CreateForm von Vcl.Forms.TApplication wird zweimal aufgerufen. Durch den ersten Aufruf CreateForm wird Form1 erstellt, eine Instanz der in Unit1 deklarierten Klasse TForm1. Durch den zweiten Aufruf von CreateForm wird Form2 erstellt, eine Instanz der in Unit2 deklarierten Klasse TForm2.
Unit1
hat folgenden Inhalt:
unit Unit1;
interface
uses SysUtils, Types, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
uses Unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.ShowModal;
end;
end.
Unit1
erstellt eine Klasse namens TForm1
(abgeleitet von Vcl.Forms.TForm) und eine Instanz dieser Klasse (Form1
). Die Klasse TForm1
enthält eine Schaltfläche Button1
(eine Instanz von Vcl.StdCtrls.TButton) und die Prozedur Button1Click
, die aufgerufen wird, wenn der Benutzer auf Button1
klickt. Button1Click
verbirgt Form1
und zeigt Form2
an (durch den Aufruf von Form2.ShowModal
).
Hinweis: Im vorhergehenden Beispiel ist Form2.ShowModal von automatisch erstellten Formularen abhängig. Auch wenn sich solche Formulare gut für Beispielcode eignen, wird von ihrer Verwendung doch ausdrücklich abgeraten.
Das Objekt Form2
ist in Unit2 definiert:
unit Unit2;
interface
uses SysUtils, Types, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm2 = class(TForm)
Label1: TLabel;
CancelButton: TButton;
procedure CancelButtonClick(Sender: TObject);
end;
var
Form2: TForm2;
implementation
uses Unit1;
{$R *.dfm}
procedure TForm2.CancelButtonClick(Sender: TObject);
begin
Form2.Close;
end;
end.
Unit2
erstellt eine Klasse namens TForm2
und eine Instanz dieser Klasse (Form2
). Die Klasse TForm2
enthält eine Schaltfläche (CancelButton
, eine Instanz von Vcl.StdCtrls.TButton) und eine Beschriftung (Label1
, eine Instanz von Vcl.StdCtrls.TLabel). Obwohl es aus dem Quelltext nicht ersichtlich ist, zeigt Label1
unseren Lieblingsgruß Hello world!
an. Die Komponente ist in der Formulardatei von Form2
, Unit2.dfm
, definiert.
TForm2
deklariert und definiert die Methode CancelButtonClick
, die zur Laufzeit aufgerufen wird, wenn der Benutzer auf die Schaltfläche CancelButton
klickt. Solche Prozeduren (wie auch TForm1.Button1Click
in Unit1
) nennt man Ereignisbehandlungsroutinen, weil sie auf Ereignisse reagieren, die zur Laufzeit der Anwendung eintreten. Sie werden durch die Formulardateien für Form1
und Form2
bestimmten Ereignissen zugewiesen.
Nach dem Starten der Anwendung greeting wird lediglich Form1 angezeigt, während Form2 nicht sichtbar ist (standardmäßig ist nur das erste in der Projektdatei erstellte Formular, das Hauptformular, zur Laufzeit sichtbar). Klickt der Benutzer auf die Schaltfläche in Form1
, wird in Form2
die Meldung Hello world!
angezeigt. Wenn der Benutzer auf CancelButton
oder auf das Schließfeld Close
in der Titelleiste klickt, wird Form2
geschlossen.