Présentation du langage
Remonter à Guide du langage Delphi - Index
Delphi est un langage compilé de haut niveau à types stricts qui gère la conception structurée et orientée objet. Basé sur Object Pascal, ses avantages incluent la lisibilité du code, une compilation rapide et l'utilisation de multiples fichiers unité permettant une programmation modulaire. Delphi propose des fonctionnalités spéciales qui prennent en charge l'environnement et le framework de composants de RAD Studio. Dans la plupart des cas, les descriptions et exemples de ce guide du langage supposent que vous utilisez les outils de développement Embarcadero.
La plupart des développeurs utilisant les outils de développement Embarcadero écrivent et compilent leurs programmes dans l'environnement de développement intégré (EDI). Les outils de développement Embarcadero gèrent de nombreux détails de la configuration des projets et des fichiers source, comme par exemple la maintenance des informations sur les dépendances entre les unités. Le produit impose par ailleurs des contraintes sur l'organisation des programmes qui ne font pas à proprement parler partie des spécifications du langage Object Pascal. Ainsi, les outils de développement Embarcadero imposent certaines conventions sur les noms de fichier ou de programme que vous pouvez éviter en n'utilisant pas l'EDI pour coder vos programmes et en compilant depuis la ligne de commande.
Généralement, ce guide suppose que vous travaillez dans l'EDI et que vous concevez des applications qui utilisent la bibliothèque de composants visuels (Visual Component Library, VCL). Néanmoins, dans certains cas, les règles propres à Delphi sont distinguées des règles s'appliquant à tous les programmes Object Pascal.
Cette section traite des rubriques suivantes :
- Organisation d'un programme : couvre les fonctionnalités de base du langage qui vous permettent de diviser votre application en unités et espaces de nommage.
- Programmes exemple : brefs exemples d'applications console et GUI avec des instructions de base sur l'exécution du compilateur à partir de la ligne de commande.
Sommaire
Organisation d'un programme
Les programmes Delphi sont généralement divisés en modules de code source appelés unités. La majorité des programmes commencent par un en-tête program qui spécifie le nom du programme. L'en-tête program est suivi d'une clause uses facultative puis d'un bloc de déclarations et d'instructions. La clause uses énumère toutes les unités liées à ce programme ; ces unités, qui peuvent être partagées par différents programmes, peuvent également avoir leur propre clause uses.
La clause uses fournit au compilateur des informations sur les dépendances entre modules. Comme ces informations sont stockées dans les modules mêmes, la plupart des programmes en langage Delphi n'ont pas besoin de makefiles, de fichiers d'en-tête ou de directives "include" du préprocesseur.
Fichiers source Delphi
Le compilateur s'attend à trouver du code source Delphi sous trois formes différentes :
- Des fichiers source d'unité (se terminant par l'extension .pas)
- Des fichiers projet (se terminant par l'extension .dpr)
- Des fichiers source de package (se terminant par l'extension
.dpk
)
Généralement, les fichiers source d'unité contiennent l'essentiel du code d'une application. Chaque application n'a qu'un seul fichier projet et plusieurs fichiers unité ; le fichier projet (qui correspond au fichier programme en Pascal standard) organise les fichiers unité en application. Les outils de développement Embarcadero gèrent automatiquement un fichier projet pour chaque application.
Si vous compilez un programme depuis la ligne de commande, vous pouvez placer tout le code source dans des fichiers unité (.pas). Si vous utilisez l'EDI pour concevoir votre application, il produira un fichier projet (.dpr).
Les fichiers source de package sont semblables aux fichiers projet, mais ils sont utilisés pour créer des bibliothèques de liaison dynamique spéciales appelées des packages.
Autres fichiers utilisés pour construire des applications
Outre les modules de code source, les produits Embarcadero utilisent plusieurs fichiers non-Pascal pour construire les applications. Ces fichiers sont gérés automatiquement par l'EDI, ce sont :
- Les fichiers fiche VCL (d'extension .dfm sous Win32)
- Les fichiers ressource (d'extension .res)
- Les fichiers d'options de projet (d'extension .dof)
Un fichier fiche VCL contient la description des propriétés d'une fiche et des composants qu'elle possède. Chaque fichier fiche représente une seule fiche correspondant généralement à une fenêtre ou à une boîte de dialogue de l'application. L'EDI vous permet de visualiser et de modifier les fichiers fiche sous forme de texte et d'enregistrer les fichiers fiche en format texte (très approprié au contrôle de version) ou en format binaire. Bien que par défaut les fichiers fiche soient enregistrés sous forme de texte, vous ne les modifierez généralement pas manuellement ; vous utiliserez plutôt les outils de conception visuelle de Embarcadero. Chaque projet contient au moins une fiche et chaque fiche dispose d'un fichier unité (.pas) associé portant, par défaut, le même nom que le fichier fiche.
Outre les fichiers fiche VCL, chaque projet utilise un fichier de ressource (.res) standard pour contenir l'icône de l'application et d'autres ressources comme des chaînes. Par défaut, ce fichier porte le même nom que le fichier projet (.dpr).
Un fichier d'options de projet (.dof) contient les paramètres du compilateur et du lieur, les informations de chemin de recherche, les informations de version, etc. Chaque projet est associé à un fichier d'options qui porte le même nom que le fichier projet (.dpr). Ces options sont généralement définies dans le dialogue Options de projet.
Divers outils de l'EDI permettent de stocker les données dans des fichiers de types différents. Les fichiers de paramètres de bureau (.dsk) contiennent des informations sur la disposition des fenêtres et d'autres options de configuration ; les paramètres de bureau peuvent être spécifiques au projet ou concerner l'environnement tout entier. Ces fichiers n'ont pas d'effet direct sur la compilation.
Fichiers générés par le compilateur
Lors de la première construction d'une application ou d'un package, le compilateur produit un fichier unité compilée (.dcu sur Win32) pour chaque nouvelle unité utilisée dans votre projet ; tous les fichiers .dcu de votre projet sont ensuite liés pour créer un exécutable unique ou un package partagé. A la première construction d'un package, le compilateur produit un fichier pour chaque nouvelle unité contenue dans le package, puis il crée à la fois un fichier .dcp et un fichier package. Si vous utilisez le commutateur GD du compilateur, le lieur génère également un fichier map et un fichier .drc ; le fichier .drc qui contient des chaînes de ressource peut être compilé en fichier ressource.
Quand vous construisez un projet, les unités individuelles ne sont pas recompilées sauf si leur fichier source (.pas) a été modifié depuis la dernière compilation, si leurs fichiers .dcu/.dpu sont introuvables, si vous demandez explicitement au compilateur de les régénérer, ou si l'interface de l'unité dépend d'une autre unité ayant été modifiée. En fait, il n'est même pas nécessaire que le fichier source d'une unité soit présent, du moment que le compilateur trouve le fichier unité compilée et que cette unité n'a pas de dépendances sur d'autres unités modifiées.
Programmes exemple
Les exemples suivants décrivent les caractéristiques de base de la programmation Delphi. Les exemples montrent des applications simples qui ne seraient pas correctement compilées depuis l'EDI ; vous pouvez les compiler à partir de la ligne de commande.
Une application console simple
Le programme ci-dessous est une application console simple que vous pouvez compiler et exécuter depuis l'invite de commande :
program Greeting;
{$APPTYPE CONSOLE}
var
MyMessage: string;
begin
MyMessage := 'Hello world!';
Writeln(MyMessage);
end.
La première ligne déclare un programme appelé Greeting. La directive {$APPTYPE CONSOLE} indique au compilateur que c'est une application console qui doit être exécutée depuis la ligne de commande. La ligne suivante déclare une variable appelée MyMessage, qui contient une chaîne (Delphi dispose directement d'un type de donnée chaîne). Puis, le programme assigne la chaîne "Hello world!" à la variable MyMessage et envoie le contenu de MyMessage sur la sortie standard en utilisant la procédure Writeln (Writeln est définie implicitement dans l'unité System que le compilateur inclut automatiquement dans chaque application).
Vous pouvez saisir ce programme dans un fichier appelé greeting.pas ou greeting.dpr, puis le compiler en entrant :
dcc32 greeting
pour produire un exécutable Win32
L'exécutable résultant affiche le message Hello world!
Mis à part sa simplicité, cet exemple diffère largement du type de programme que vous allez probablement écrire avec les outils de développement Embarcadero. Tout d'abord, c'est une application console. Les outils de développement Embarcadero sont généralement utilisés pour écrire des applications ayant une interface graphique ; ainsi, vous ne devez normalement pas appeler Writeln. De plus, la totalité du programme exemple (à l'exception de Writeln) se trouve dans un fichier unique. Dans une application GUI typique, l'en-tête du programme (la première ligne de cet exemple) se trouve dans un fichier projet séparé qui ne contient pas la logique réelle de l'application sinon quelques appels aux routines définies dans les fichiers unité.
Un exemple plus sophistiqué
L'exemple suivant propose un programme qui est divisé en deux fichiers : un fichier projet et un fichier unité. Le fichier projet, que vous pouvez enregistrer sous le nomgreeting.dpr, a la forme suivante :
program Greeting;
{$APPTYPE CONSOLE}
uses
Unit1;
begin
PrintMessage('Hello World!');
end.
La première ligne déclare un programme appelé greeting qui, encore une fois, est une application console. La clause uses Unit1; spécifie au compilateur que greeting inclut une unité appelée Unit1. Enfin, le programme appelle la procédure PrintMessage en lui passant la chaîne Hello World! La procédure PrintMessage est définie dans Unit1. Voici le code source de Unit1 que vous devez enregistrer dans un fichier appelé Unit1.pas :
unit Unit1;
interface
procedure PrintMessage(msg: string);
implementation
procedure PrintMessage(msg: string);
begin
Writeln(msg);
end;
end.
Unit1
définit une procédure appelée PrintMessage
qui attend un seul paramètre chaîne comme argument et envoie la chaîne dans la sortie standard. (En Delphi, les routines qui ne renvoient pas de valeur sont appelées des procédures. Les routines qui renvoient une valeur sont appelées des fonctions.)
Remarquez
la double déclaration de PrintMessage
dans
Unit1
. La première déclaration, après le mot réservé interface, rend PrintMessage
accessible aux autres modules (comme greeting
) qui utilisent Unit1
. La deuxième déclaration, sous le mot réservé implementation, définit réellement PrintMessage
.
Vous pouvez maintenant compiler Greeting depuis la ligne de commande en saisissant :
dcc32 greeting
pour produire un exécutable Win32
Il n'est pas nécessaire d'inclure Unit1
comme argument de la ligne de commande. Quand le compilateur traite le fichier greeting.dpr
, il recherche automatiquement les fichiers unité dont dépend le programme greeting
. L'exécutable résultant fait la même chose que le premier exemple : il imprime le message Hello world!
Une application VCL
L'exemple suivant est une application construite en utilisant les composants de la bibliothèque de composants visuels (VCL) de l'EDI. Ce programme utilisant des fichiers fiche et ressource générés automatiquement, il n'est pas possible de compiler le code source tout seul. Mais ce programme illustre des caractéristiques importantes du langage Delphi. Outre diverses unités, le programme utilise des classes et objets.
Le programme inclut un fichier projet et deux nouveaux fichiers unité. Tout d'abord le fichier projet :
program Greeting;
uses
Forms, Unit1, Unit2;
{$R *.res} { This directive links the project's resource file. }
begin
{ Calls to global Application instance }
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.Run;
end.
Là encore, notre programme est appelé greeting. Il utilise trois unités : Forms, qui fait partie de la VCL; Unit1, qui est associée à la fiche principale de l'application (Form1) ; et Unit2, qui est associée à une autre fiche (Form2).
Le programme fait une série d'appels à un objet nommé Application, qui est une instance de la classe Vcl.Forms.TApplication définie dans l'unité Forms. (Chaque projet dispose d'un objet Application généré automatiquement.) Deux de ces appels invoquent la méthode Vcl.Forms.TApplication nommée CreateForm. Le premier appel à CreateForm crée Form1, une instance de la classe TForm1 définie dans Unit1. Le second appel à CreateForm crée Form2, une instance de la classe TForm2 définie dans Unit2.
Unit1
a la forme suivante :
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
crée une classe nommée TForm1
(dérivée de la classe Vcl.Forms.TForm) et une instance de cette classe, Form1
. La classe TForm1
contient un bouton (Button1
, une instance de Vcl.StdCtrls.TButton) et une procédure nommée Button1Click
qui est appelée quand l'utilisateur clique sur Button1
. Button1Click
cache Form1
et affiche Form2
(l'appel à Form2.ShowModal
).
Remarque : Dans l'exemple précédent, Form2.ShowModal se repose sur l'utilisation de fiches créées automatiquement. Bien que cela soit correct dans le code exemple, l'utilisation de fiches auto-créées est déconseillée.
Form2
est définie dans Unit2 :
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
crée une classe nommée TForm2
et une instance de cette classe, Form2
. La classe TForm2
contient un bouton (CancelButton
, une instance de Vcl.StdCtrls.TButton) et un libellé (Label1
, une instance de Vcl.StdCtrls.TLabel). Vous ne pouvez le voir dans le code source, mais Label1
affiche un intitulé contenant le texte Hello world!
L'intitulé est défini dans le fichier fiche de Form2
, Unit2.dfm
.
TForm2
déclare et définit une méthode CancelButtonClick
qui est invoquée à l'exécution chaque fois que l'utilisateur appuie sur CancelButton
. Cette procédure (ainsi que TForm1.Button1Click
de Unit1
) est appelée gestionnaire d'événement, car elle répond à des événements se produisant lors de l'exécution du programme.
Les gestionnaires d'événement sont assignés à des événements spécifiques par les fichiers fiche deForm1
etForm2
.
Au démarrage du programme greeting, la fiche Form1 est affichée et la fiche Form2 est invisible. (Par défaut, seule la première fiche créée dans le fichier projet est visible à l'exécution. C'est ce qu'on appelle la fiche principale du projet.) Quand l'utilisateur choisit le bouton placé dans Form1
, Form2
affiche la salutation Hello world!
. Quand l'utilisateur clique sur CancelButton
ou sur le bouton Fermer
de la barre de titre, Form2
se ferme.