1 Présentation
Delphi est un langage de programmation inspiré de Pascal, fondé sur les notions d'événements et d'objets. Il permet de créer simplement de belles interfaces graphiques tout en disposant d'un puissant langage de
programmation.
En Delphi, on construit des projets. Un projet est constitué d'unités qui ressemblent à des programmes Pascal et de fiches qui définissent l'interface graphique correspondante. Dans un projet, une unité est associée à chaque fiche. Chaque unité et chaque fiche seront stockées dans des fichiers différents (extension PAS pour les unités, DFM pour les fiches ; le projet ayant l'extension DPR). Delphi engendre automatiquement d'autres fichiers qu'on ne détaillera pas. Chaque exercice va donner lieu à un projet différent, qui devra être stocké dans un répertoire spécifique. Avant de lancer Delphi, il est donc conseillé de créer les répertoires qui serviront par la suite. Si tous les fichiers correspondant à un projet ne sont pas dans un même répertoire, vous augmentez les risques de confusion, pour Delphi et pour vous.
Lancer Delphi à partir de la rubrique Programme du menu Démarrer. L'interface apparaît : elle est constituée d'une barre de menus, d'icônes de raccourcis (à gauche) et d'une palette de composants graphiques (icônes réparties dans des rubriques repérées par différents onglets, à droite).
Trois fenêtres sont également ouvertes :
une fenêtre unité appelée Unit1.pas, contenant déjà la structure de base indispensable d'un code écrit en Delphi. La syntaxe de ce code est similaire à celle du langage Pascal. C'est dans cette fenêtre que l'on écrira nos programmes.
une fenêtre fiche appelée Form1 (pour formulaire). Dans cette
fenêtre, on définira l'interface de nos programmes à l'aide d'objets tels que des boutons à cliquer, des messages, des zones de saisie...
une fenêtre appelée inspecteur d'objet qui permet de visualiser les propriétés de l'objet graphique sélectionné. A l'ouverture, le seul objet graphique présent est la fiche elle-même, dont on voit les propriétés.
Vérifiez en changeant certaines des valeurs de propriétés (par exemple, la hauteur, la largeur ou la couleur) que la fiche change d'aspect. Inversement, si vous modifiez la taille de la fiche avec la souris, ses propriétés sont modifiées dans l'inspecteur d'objet. La propriété Name désigne le nom de l'objet, tandis que la
propriété Caption désigne la légende qui est écrite sur l'objet.
Le Name de l'objet est très important : il permettra de faire référence à l'objet. Quand on modifie Name, le nouveau nom est
automatiquement mis à jour dans l'unité, où tous les objets utilisés doivent être déclarés. La propriété Hint d'un objet contient le texte de la bulle d'aide qui apparaît quand le curseur se pose sur cet objet, à condition que la propriété ShowHint vaille True.
Petit détail : les deux propriétés name et caption sont liées : quand elles ont la même valeur et qu'on change celle de Name, la
propriété Caption prend cette nouvelle valeur.
2 Premier projet
Renommez la fiche, appelez-la PremierPas.
Dans la palette des composants, cliquez sur l'icône Button : Sur la fiche, dessinez les contours du bouton avec la souris. Vérifiez en cliquant alternativement sur le bouton et sur la fiche que l'inspecteur d'objet présente les propriétés de l'objet sélectionné. Vérifiez aussi que l'objet bouton a été ajouté dans les déclarations de l'unité. Renommez-le (propriété Name) : BtFermer et écrivez le message Fermer sur ce bouton
(propriété Caption).
Dans l'inspecteur d'objet, sélectionnez l'onglet événement et dans la rubrique OnClick, écrivez BtFermerSurClic. Validez. Cela a pour effet la
définition d'une nouvelle procédure
appeléeTPremierPas.BtFermerSurClic dans l'unité : cette procédure doit
préciser quel traitement sera provoqué par le fait de cliquer sur le bouton. En double-cliquant en face de la propriété Onclick ou en double- cliquant directement sur le bouton, on aurait aussi provoqué la création d'une nouvelle procédure, mais son nom imposé aurait alors
été TPremierPas.BtFermerClick.
Écrivez l'instruction close ; dans cette procédure, de façon à obtenir le
procedure TPremierPas.BtFermerSurClic(Sender: TObject); begin
Close; end;
Pour sauvegarder tous les fichiers associés au projet en cours dans un de
vos répertoires, sélectionnez Tout Enregistrer. Cette commande enregistre la ou les unités (.pas) et la ou les fiches (.dfm), puis le fichier projet (.dpr). La commande Fichier-Enregistrer enregistre seulement l'unité (.pas) et la fiche (.dfm) en cours.
Dans le menu projet, sélectionnez Vérifier la syntaxe de....
Puis compilez et exécutez. Vérifiez le bon comportement du bouton.
On peut modifier les propriétés, lors de la conception, par l'intermédiaire de l'inspecteur d'objet. Nous allons maintenant voir comment on peut modifier des propriétés lors de l'exécution du programme.
Vérifiez que la couleur est une propriété des objets «formulaire» et
regardez les valeurs proposées dans la liste. Pour accéder à une propriété à l'intérieur d'un programme, on utilise la
syntaxeNomDeComposant.NomDePropriété. Par
exemple, FPrincip.Color désigne la propriété Color d'une fiche qui serait
nommée FPrincip. On peut ainsi utiliser les valeurs des propriétés dans les
programmes. Lorsqu'il s'agit de les modifier, elles apparaissent à gauche d'une affectation.
Vous allez maintenant créer un bouton qui change la propriété Color de la fiche lorsqu'on clique sur le bouton. Dessinez le bouton ; nommez
le BtJaune ; Créez et complétez la procédure BtJauneSurClic (en sachant
que le code du jaune est représenté par la constante ClYellow).
Recommencez pour qu'un deuxième bouton colorie la fiche en bleu.
Ajoutez un autre bouton pour que chaque clic change la couleur de la fiche : du rouge au bleu et du bleu au rouge. Essayez avec un changement sur trois couleurs.
Ajoutez à la fiche deux objets de type Edit : . Ce sont des zones d'édition, dans lesquelles on peut écrire ou lire une chaîne de caractères. La chaîne contenue dans ces zones correspond à la valeur de la
propriété Text.
On va créer un bouton pour transférer le texte d'une zone à une autre. Renommez les deux zones éditables : ZoneEntrée et ZoneSortie. Pour
expliquer à l'utilisateur à quoi sert un objet, il faut souvent placer des commentaires sur la fiche. Pour cela, on utilise les
objets Label (étiquette) dont la propriété Caption (légende) permet de préciser le commentaire à afficher.
Ajoutez des étiquettes qui expliquent à quoi servent les deux zones d'édition.
Ajoutez un bouton sur la fiche, et appelez-le BtTransfert et
écrivez transférer sur le bouton. Mettez dans les deux zones éditables un
texte vide. Puis écrivez un programme qui, quand on clique sur le
bouton BtTransfert, recopie ce qui est écrit de la première zone dans la
Pour terminer cette présentation, nous allons examiner les fichiers qui constituent une application Delphi. Le fichier principal qui représente le projet porte l'extension DPR. Ce fichier peut être visualisé avec un éditeur de texte mais il ne faut modifier ce fichier qu'avec précaution. Les unités sont sauvegardées avec l'extension PAS. Elles contiennent la définition de vos procédures et fonctions. Les fiches sont enregistrées avec le même nom que les unités, mais avec une extension DFM. Les fichiers DFM contiennent la représentation graphique de la fiche ; ils ne peuvent être manipulés qu'avec le logiciel Delphi. Enfin la compilation génère un fichier exécutable ayant l'extension EXE. En utilisant un éditeur de texte (par exemple bloc-notes), visualisez le fichier projet et le fichier unité de votre application.
3 Tête flottante
On veut créer une application disposant de quatre boutons qui
permettront de déplacer un objet dans la fenêtre. L'objet sera un label (une étiquette) sur lequel sera écrite la lettre J en police Wingdings
Les propriétés qui définissent la position d'un objet sont Left et Top ; celles qui définissent sa taille sont Width et Height. Pour une fiche, les
propriétés ClientWidth et ClientHeight définissent la largeur et la hauteur utilisable à l'intérieur de la fiche (à l'exclusion de la barre de titre, des barres de défilement...) Une première ébauche de l'application se contentera de déplacer la tête. Puis vous améliorerez votre application pour que la tête se déplace dans les limites de la fenêtre existante.
4 Convertisseur
Programmer un convertisseur Franc-Euro dans les deux sens, qui saisit une somme dans une des deux monnaies et permet, en cliquant sur un bouton, d'obtenir sa valeur dans l'autre monnaie.
On rappelle que le taux de conversion vaut 6,55957. Attention ! les zones d'édition (objet Edit) ne permettent pas des saisies directes de nombres réels. La propriété Text est de type chaîne de caractères qu'on doit
convertir en nombre réel. Il existe plusieurs façons de convertir des valeurs de type chaîne de caractères en valeurs de type numérique et
inversement.
4.1 La conversion de caractères en nombres
L'utilisation des procédures VAL et STR est certainement la plus efficace ; elle permet de gérer les éventuelles erreurs de conversion.
Val(TexteAConvertir : String ; var VariableResultat : Real ; var VariableDErreur : Integer)
Dans cette procédure, le premier paramètre représente la chaîne de caractères à convertir. Le deuxième paramètre est une variable de type réel (ou entier) qui va recevoir le résultat. Cette variable réelle (ou entière) doit être déclarée dans l'unité. Le troisième paramètre est une variable pour vérifier que la conversion s'est bien passée ; la variable doit être déclarée dans l'unité. Après exécution de la procédure, si aucune erreur ne s'est produite elle vaut 0, sinon elle vaut le rang du 1er caractère (par exemple : un caractère alphabétique) qui a empêché la conversion.
De même, pour convertir un nombre en chaîne, il faut utiliser la procédure :
Str(NombreAConvertir : real ; var VariableRésultat : string)
Cette fois, aucune erreur n'est à craindre et le 3ième paramètre n'est plus nécessaire. Pour afficher le réel avec 2 chiffres après la virgule et 10 caractères maximum en tout, écrire : Str(NombreAConvertir : 10 : 2, VariableChaîneRésultat)
Les fonctions IntToStr, FloatToStr, StrToInt, StrToFloat sont des fonctions de conversion dont le principe est très simple : une valeur d'un certain type en paramètre est transformée en une valeur d'un autre type en résultat ; exemple : StrToFloat('3.4') fournit la valeur numérique 3.4. La gestion de l'erreur est beaucoup plus difficile.
La variable globale DecimalSeparator définit le caractère qui doit être utilisé comme séparateur décimal. Il semble prudent d'écrire
l'instruction DecimalSeparator :='.' ; dans la partieInitialization de
l'unité.
5 Calculatrice
Programmer une petite calculatrice qui se présente comme ci-dessous : (voir l'exécutable PrCalcul.exe)
Pour utiliser cette calculatrice, il faut d'abord taper la valeur des deux opérandes (qui sont des nombres réels) puis cliquer sur le bouton
correspondant à l'opération à effectuer. Le résultat s'affiche alors dans la dernière zone.
6 Vidéo
Pour se détendre quelques minutes, nous allons voir que la gestion des fichiers multimédia ne pose aucune difficulté en Delphi. Placez sur la
fenêtre un composant MediaPlayer de la rubriqueSystème. Parmi les propriétés de ce composant, FileName permet de spécifier le nom du fichier son, vidéo... Associez au composant le fichier vidéo Open Space.mpg qui se trouve dans le répertoire Projets Delphi. Vérifiez que la
propriété AutoOpen a pour valeur True. Exécutez !
Remarque pour faire jouer un CD audio, il faudrait simplement mettre la valeur dtCDAudio dans la propriété Device Type (mais il faut avoir une carte son).
7 Calculatrice (amélioration)
On veut améliorer la calculatrice en lui ajoutant les fonctionnalités suivantes :
boutons d'édition pour les chiffres
enchaînement d'opérations (opérande opérateur opérande opérateur opérande opérateur...=)
La calculatrice aura l'aspect suivant :
7.1 Première étape :
Placez la zone d'édition. Nommez-la ZEdition.
Placez les boutons correspondant aux chiffres (ce n'est pas la peine de mettre les 10 chiffres).
Nommez ces boutons BChiffre1, BChiffre2, ...
Écrivez la procédure associée à l'événement OnClick qui ajoute le chiffre à la droite de la valeur déjà présente dans la zone d'édition.
Placez le bouton de séparateur décimal. Nommez-le BPoint.
Écrivez la procédure associée à l'événement OnClick qui ajoute le séparateur décimal à la droite de la valeur déjà présente dans la zone d'édition (s'il n'y a pas de séparateur pour l'instant).
7.2 Deuxième étape :
Placez la zone d'édition correspondant à la mémoire. Nommez-la ZMemoire.
Définissez-la en lecture seule (comment ??? cherchez un peu dans les propriétés).
7.3 Troisième étape :
Nous aurons besoin de mémoriser la dernière opération demandée.
Définissez le type énuméré TOperations=(plus,moins,mult,divi,aucune) et
définissez une variable Operation de ce type.
7.4 Quatrième étape :
Placez le bouton pour l'addition. Nommez-le BPlus.
Ecrivez la procédure associée à l'événement OnClick qui effectue l'opération en attente (s'il y a lieu), met le résultat en mémoire, vide la zone d'édition et mémorise l'addition comme étant la prochaine opération à effectuer.
Recommencez pour les autres opérations.
Placez un bouton pour effacer la mémoire et un pour terminer un cycle d'opérations (=).
7.5 Dernière étape : améliorations
Les procédures BPlusClick, BMoinsClick... ont la même structure avec une
partie commune qui est faire l'opération en attente. Définissez une procédure FaireOperationEnAttente et modifiez les
procédures BPlusClick, BMoinsClick... en conséquence.
Tous les boutons d'édition des chiffres fonctionnent de la même façon, il serait intéressant d'avoir une seule procédure pour tous ces boutons. Il faut utiliser le paramètre Sender et la propriété Tag(l'explication sera
donnée en cours).
8 Voyelles
Ecrire un projet qui permet de taper un mot dans une zone de saisie puis, quand on clique sur un bouton, affiche automatiquement en message le nombre d'occurrences de chacune des voyelles dans ce mot.
Par exemple, si le mot saisi est patate, on verra affiché :
nombre de 'a' : 2
nombre de 'e' : 1
nombre de 'i' : 0,
etc.
Réaliser au moins 2 versions de ce projet : une version utilisant
l'instruction Case ... of ...end ; et une version utilisant une unique fonction (paramètrée) pour compter le nombre d'occurrences de n'importe quel caractère dans un String quelconque.
Attention : réfléchissez afin d'utiliser une bonne structure de données pour représenter les lettres et les voyelles.
9 Jackpot
Ecrire un projet pour jouer au Jackpot.
Ce jeu inclut l'utilisation de 4 images distinctes (on en visualise trois sur l'exemple). Elles sont stockées respectivement sous les
noms zero.bpm, un.bpm, deux.bpm, trois.bpm dans le dossier ProjetsDelphi.
Commencez par les recopier dans votre dossier réservé à cet exercice.
Pour charger une image sur une fiche, il faut d'abord ajouter un composant Image (dans le menu Supplément) sur cette fiche. Le
chargement effectif de l'image se fait en changeant la propriétéPicture de cette image par la procédure prédéfinie suivante : LoadfromFile(nom-du-fichier image).
Ainsi, par exemple, l'instruction : Image1.Picture.LoadfromFile(deux.bpm) ; a pour effet de charger le fichier deux.bpm dans l'emplacement Image1.
Le fait de cliquer sur le bouton Jouer provoque un tirage aléatoire parmi les
4 images possibles pour chacun des 3 emplacements de type image prévus dans la fiche. Si les trois tirages sont identiques, on a gagné. Si en plus les 3 images identiques sont celles représentant le smiley souriant jaune sur
fond blanc (à droite dans l'exemple), c'est le Bingo ! Dans tous les autres cas, on a perdu. Un message affiche le résultat du tirage.
10 Feux Tricolores (voir l'exécutable PrFeux.exe)
Écrire une application qui simule les feux tricolores à un carrefour.
10.1 Étape 1
Simuler un seul feu périodique. Le feu passe du vert à l'orange, puis de l'orange au rouge, puis du rouge au vert ... en restant allumé 5 secondes pour chaque couleur.
Vous utiliserez un composant Timer qui permet de déclencher un événement avec une certaine périodicité.
Pour placer une image sur une fiche, utilisez un composant Image. Sa propriété Picture définit l'image à afficher. Ici il s'agira d'icônes
(Vert.ico, Orange.ico, Rouge.ico qui se trouvent
dansProfs\ProjetsDelphi\Feux) que vous aurez recopiées dans le dossier
de l'application.
Pour changer une image à l'exécution, il faut utiliser la méthode LoadFromFile. Exemple
: Image1.Picture.LoadFromFile('Vert.ico').
10.2 Étape 2
Un feu n'est pas périodique ; la durée du feu orange est plus courte que les autres, qui elles-mêmes ne sont pas égales.
Quelle est l'équation qui régit la durée des feux (dans un carrefour à deux routes) ?
Pour exécuter des actions avec des périodicités différentes, vous avez deux solutions : soit vous utilisez le Timer périodique avec une certaine unité de temps et vous comptez les événements déclenchés, soit vous utilisez
le Timer comme un chrono et vous changez la propriété Interval pour que l'événement suivant se déclenche après la durée que vous lui indiquez.
(en haut un feu tricolore, en bas deux feux synchronisés)
10.3 Étape 3
Synchronisez deux feux d'un croisement (quand l'un passe au rouge, l'autre passe au vert... et le orange ???).
Placez des icônes pour les passages piétons (RougPiet.ico, VertPiet.ico)
synchronisées avec les feux.
11 Soundex Code (à faire en cours, utilise plus d'algo
que d'interface Delphi)
Le Soundex Code sert à fabriquer des abréviations qui permettraient de retrouver le mot d'origine. Cela peut être utile pour nommer un fichier, une variable, un composant... Lorsque votre variable s'appelle cpt, vous savez qu'il s'agit d'un compteur.
Considérons un mot à abréger. Le Soundex Code est construit en prenant la première lettre de ce mot, suivie des trois premières consonnes du mot (s'il en a trois). On ne prend qu'une consonne lorsqu'il y a un doublement de consonnes.
Exemples :
Mandarine est abrégé en Mndr
Orange en Orng
Commande en Cmnd
Ananas en Anns
Pomme en Pm
Écrire une application qui demande un mot à l'utilisateur et fabrique le code correspondant.
12 Nombre mystère
12.1 La règle.Un nombre compris entre 0 et 100 est tiré au hasard par l'ordinateur. Le joueur doit le deviner en moins de 10 étapes. A chaque essai, l'ordinateur lui indique s'il est au-dessus, au-dessous ou s'il a trouvé la valeur cherchée.
12.2 Analyse.
Quelles sont les informations nécessaires ? Comment les représenter ?
Formulez la règle ci-dessus sous la forme d'une ébauche d'algorithme (actions contrôlées par des alternatives et des itérations).
Imaginez l'interface : quels genres de zones, de boutons... sont nécessaires ? Comment veut- on que les éléments de l'interface réagissent ?
Écrivez les procédures associées.
12.3 Remarques pour la réalisation.
La saisie d'une valeur numérique entière peut se faire par un
composant SpinEdit de la rubrique Exemples (propriétés importantes : MinValue, MaxValue, Value).
rubrique Win95 (propriétés importantes : Min, Max, Position).
Pour afficher des informations pour l'utilisateur, vous pouvez utiliser un composant Label (on modifie alors la légende de ce composant) ou utiliser des boîtes de message (procédure ShowMessage).
La fonction Random(n) fournit un nombre aléatoire entier compris entre 0 et
n-1 inclus. Le générateur de nombres aléatoire doit être initialisé par l'instruction Randomize.
13 Préparation au dessin des tours de Hanoi
Quelques informations pratiques sur le dessin en annexe C.
Réalisez une fiche qui contient cinq boutons. Le premier dessine un petit rectangle bleu.
Le deuxième dessine un grand rectangle rouge qui le recouvre. Le troisième efface tout. (placez ces trois boutons, faites des essais, modifiez les paramètres du crayon, de la brosse...)
Le quatrième bouton affiche des petits carrés de 10x10 à 5 points du bas de la fiche. Les carrés sont espacés de cinq points. Vous prévoirez le dessin pour que, même si l'utilisateur change la dimension de la fenêtre, les carrés s'affichent toujours au bas de la fiche et sur toute la largeur.
Le cinquième bouton dessine une pyramide de rectangles de taille
décroissante (rectangles de hauteur 10 pixels de largeur variant entre 200 et 10 points).
A Langage de programmation
A.1 Types de DonnéesA.1.1 Déclarations de types
Syntaxe : IdfType = Définition de type ;
A.1.2 Définition des types ordinaux
Les types ordinaux sont des ensembles finis totalement ordonnés. On peut utiliser les fonctions Ord, Pred et Succ ; les numéros d'ordre commencent à 0.
Type BOOLEAN
False < True Ord(False)=0
Types Entiers
SHORTINT -128 .. 127 Signé, 8 bits
SMALLINT -32768 .. 32767 Signé, 16 bits
LONGINT -2147483648 .. 2147483647 Signé, 32 bits
BYTE 0 .. 255 Non signé, 8 bits
WORD 0 .. 65535 Non signé, 16 bits
INTEGER -32768 .. 32767 Signé, 16 bits
INTEGER -2147483648 .. 2147483647 Signé, 32 bits
CARDINAL 0 .. 65535 Non signé, 16 bits
CARDINAL 0 .. 2147483647 Non signé, 32 bits
Type CHAR
Type Enuméré
définition du type par une énumération d'identifiant (Idf1,Idf2,....)
Type Intervalle
Un type intervalle est une série de valeurs de type ordinal appelé le type hôte. La définition d'un type intervalle spécifie la plus petite et la plus grande valeur de l'intervalle.
ConstMin..ConstMax
A.1.3 Types Réels
Type Portée Chiffres
significatifs Taille en octets REAL 2.9 * 10-39 .. 1.7 * 1038 11-12 6 SINGLE 1.5 * 10-45 .. 3.4 * 1038 7-8 4 DOUBLE 5.0 * 10-324 .. 1.7 * 10308 15-16 8 EXTENDE D 3.4 * 10 -4932 .. 1.1 * 104932 19-20 10 COMP -263+1 .. 263-1 19-20 8 CURRENC Y -922337203685477.5808..922337203685477.58 07 19-20 8
A.1.4 Types structurés
Type Tableau ARRAY[TypeIndiceOrdinal1,TypeIndiceOrdinal2,...] OF TypeElements ; Type Ensemble SET OF TypeOrdinal Types Fichier Type Enregistrement Type Class
A.1.5 Type Chaîne
STRING[LgMax]
A.1.6 Type Pointeur
A.2 Constantes et Variables
A.2.1 Déclaration de constantes
CONST Idf = ExpressionConstante ;
A.2.2 Déclaration de variables
VAR Idf1,Idf2,... : IdfType ;
A.2.3 Déclaration de constantes typées
CONST Idf : IdfType = ExpressionConstante ;
A.3 Instructions
A.3.1 Affectation
Idf := Expression
A.3.2 Appel de procédure
NomProcédure(ParamètresEffectifs)
A.3.3 Instruction WITH
WITH IdfEnregistrementOuObjet DO Instructions
A.5 Itérations
A.6 Procédures et fonctions
A.6.1 Syntaxe de la déclaration de procédure
A.6.2 Paramètres formels et paramètres effectifs
Les paramètres formels sont ceux utilisés pour définir la procédure. Les paramètres effectifs sont ceux utilisés à l'appel de la procédure.
A.6.3 Passage de paramètres par valeur ou par adresse Déclaration d'un paramètre passé par valeur Idf : IdfType
Déclaration d'un paramètre passé par adresse VAR Idf : IdfType
Quand vous déclarez un paramètre par valeur, l'appel de la procédure utilisera la valeur du paramètre effectif.
Quand vous déclarez un paramètre par adresse, l'appel de la procédure utilisera l'adresse du paramètre effectif donc pourra enregistrer des modification de valeur à cette adresse.
A.6.4 Syntaxe de la déclaration de fonction
Delphi permet l'affectation du résultat à la fonction par le mot clé RESULT.
A.7 Unités
Modules contenant types, variables, procédures et fonctions
A.7.1 Syntaxe de la déclaration d'unité
A.7.2 Syntaxe de la déclaration d'utilisation d'unité