Vous êtes sur la page 1sur 204

Delphi et KyliX : des descendants de Pascal

MIAGE 2me anne

Delphi et KyliX : des descendants de Pascal


I. EDI : lenvironnement de dveloppement intgr ......................................................................................................................10 La fentre principale ................................................................................................................................................................10 1. La barre de menus....................................................................................................................................................................10 2. La barre doutils .......................................................................................................................................................................10 3. La palette de composants ........................................................................................................................................................10 B. Lditeur de code......................................................................................................................................................................10 C. Le concepteur de fiches (ou de forms )...........................................................................................................................11 D. Linspecteur dobjets...............................................................................................................................................................11 E. Laide Delphi ............................................................................................................................................................................11 II. Prsentation gnrale ...................................................................................................................................................................12 A. Structure dun programme Pascal, Delphi ou Kylix..........................................................................................................12 B. Utiliser des units.....................................................................................................................................................................13 C. Crer des units ........................................................................................................................................................................14 D. Les projets .................................................................................................................................................................................14 E. Fichiers dun projet..................................................................................................................................................................15 III. lments de syntaxe .....................................................................................................................................................................15 A. Commentaires ...........................................................................................................................................................................15 B. Directive de compilation.........................................................................................................................................................16 C. Identificateurs ...........................................................................................................................................................................16 D. Identificateurs qualifis ...........................................................................................................................................................16 E. Affectation.................................................................................................................................................................................17 F. Sparateur dinstruction..........................................................................................................................................................17 G. Dclaration de Types, de constante et de variables............................................................................................................17 IV. Types et structure de donnes simples......................................................................................................................................17 A. Le type scalaire .........................................................................................................................................................................18 1. Dfinition...................................................................................................................................................................................18 2. Routines ordinales....................................................................................................................................................................18 3. Priorit des oprateurs.............................................................................................................................................................18 4. Le type boolen ........................................................................................................................................................................18 a) Dfinition ..............................................................................................................................................................................18 b) Oprateurs ........................................................................................................................................................................18 c) Procdure et fonctions........................................................................................................................................................19 d) Oprateurs relationnels ...................................................................................................................................................19 e) Exemples ...............................................................................................................................................................................19 5. Le type entier ............................................................................................................................................................................19 a) Dfinition ..............................................................................................................................................................................19 b) Oprateurs ........................................................................................................................................................................20 c) Procdure et fonctions........................................................................................................................................................20 d) Exemple ............................................................................................................................................................................21 6. Le type caractre ......................................................................................................................................................................21 a) Dfinition ..............................................................................................................................................................................21 b) Oprateurs ........................................................................................................................................................................21 c) Procdure et fonctions........................................................................................................................................................21 d) Exemples ..........................................................................................................................................................................21 7. Le type numr .......................................................................................................................................................................21 a) Dfinition ..............................................................................................................................................................................21 b) Exemples ..........................................................................................................................................................................22 8. Le type intervalle ......................................................................................................................................................................22 a) Dfinition ..............................................................................................................................................................................22 b) Exemples ..........................................................................................................................................................................22 B. Le type rel................................................................................................................................................................................22 1. Dfinition...................................................................................................................................................................................22 2. Oprateurs .................................................................................................................................................................................22 3. Routines arithmtiques............................................................................................................................................................22 4. Routines de nombres alatoires .............................................................................................................................................23 A.
Delphi et Kilix

D. Mailliet

MIAGE 2me anne

Exemples ...................................................................................................................................................................................23 Les types chanes .....................................................................................................................................................................23 1. Dfinition ..................................................................................................................................................................................23 2. Routines de gestion des chanes............................................................................................................................................23 3. Oprateurs de chane...............................................................................................................................................................24 4. Les chanes courtes ..................................................................................................................................................................24 a) Dfinition..............................................................................................................................................................................24 b) Exemples ..........................................................................................................................................................................24 5. Les chanes longues et tendues ............................................................................................................................................24 a) Dfinition..............................................................................................................................................................................24 b) Exemples ..........................................................................................................................................................................24 6. Les chanes AZT......................................................................................................................................................................25 a) Dfinition..............................................................................................................................................................................25 b) Oprateurs ........................................................................................................................................................................25 c) Procdure et fonctions........................................................................................................................................................25 d) Exemples ..........................................................................................................................................................................25 D. Chanes de format ....................................................................................................................................................................25 E. Le type pointeur.......................................................................................................................................................................27 1. Dfinition ..................................................................................................................................................................................27 2. Oprateurs .................................................................................................................................................................................27 3. routines d'adresses et de pointeurs........................................................................................................................................28 4. Routines d'allocation dynamique ..........................................................................................................................................28 5. Exemples ...................................................................................................................................................................................28 F. Autres pointeurs.......................................................................................................................................................................29 G. Le type Variant.........................................................................................................................................................................29 1. Dfinition ..................................................................................................................................................................................29 2. Oprateurs .................................................................................................................................................................................29 3. Routines de gestion des variants ...........................................................................................................................................29 H. Les types Ensemble .................................................................................................................................................................30 1. Dfinition ..................................................................................................................................................................................30 2. Oprateurs .................................................................................................................................................................................30 3. Exemples ...................................................................................................................................................................................30 I. Les tableaux..................................................................................................................................................................................30 1. Dfinition ..................................................................................................................................................................................30 2. Tableaux statiques ...................................................................................................................................................................30 a) Dfinition..............................................................................................................................................................................30 b) Exemples de tableaux 1 dimension...........................................................................................................................31 c) Exemples de tableaux plusieurs dimensions...............................................................................................................31 3. Tableaux dynamiques..............................................................................................................................................................31 a) Dfinition..............................................................................................................................................................................31 b) Fonctions et procdures .................................................................................................................................................31 c) Exemples ..............................................................................................................................................................................31 J. Le type record ...............................................................................................................................................................................32 1. Dfinition ..................................................................................................................................................................................32 2. Exemples ...................................................................................................................................................................................33 K. Enregistrements partie variable ..........................................................................................................................................33 L. Le type fichier ..........................................................................................................................................................................34 1. Dfinition ..................................................................................................................................................................................34 2. routines d'entres/sorties.........................................................................................................................................................34 3. Routines de fichiers texte .......................................................................................................................................................34 4. Routines de gestion de fichiers ..............................................................................................................................................34 5. Exemples ...................................................................................................................................................................................35 M. Les types procdure et fonction.............................................................................................................................................36 1. Dfinition ..................................................................................................................................................................................36 2. Exemple .....................................................................................................................................................................................36 N. Autres routines .........................................................................................................................................................................36 1. routines de gestionnaire de mmoire ....................................................................................................................................36 2. routines diverses.......................................................................................................................................................................36 3. Informations au niveau de l'application...............................................................................................................................37 4. Routines de conversion de type.............................................................................................................................................37 Delphi et Kilix D. Mailliet 3 C.

5.

MIAGE 2me anne

Routines de contrle de flux...................................................................................................................................................37 Utilitaires de ligne de commande..........................................................................................................................................37 Utilitaires com..........................................................................................................................................................................38 Routines de compatibilit descendante................................................................................................................................39 Informations au niveau de l'application. ..............................................................................................................................39 routines de gestion des exceptions....................................................................................................................................39 Utilitaires de flux.................................................................................................................................................................40 O. Constantes types / Variables initialises ............................................................................................................................40 1. dfinition....................................................................................................................................................................................40 2. exemples ....................................................................................................................................................................................41 P. Transtypage...............................................................................................................................................................................41 1. dfinition....................................................................................................................................................................................41 2. exemple ......................................................................................................................................................................................41 V. Les routines ...................................................................................................................................................................................42 A. Procdure ...................................................................................................................................................................................42 1. dfinition....................................................................................................................................................................................42 2. exemple ......................................................................................................................................................................................42 B. Fonctions ...................................................................................................................................................................................42 1. dfinition....................................................................................................................................................................................42 2. exemple ......................................................................................................................................................................................42 C. Paramtre donne variable ......................................................................................................................................................42 1. dfinition....................................................................................................................................................................................42 2. exemple ......................................................................................................................................................................................42 D. Paramtre Rsultat ...................................................................................................................................................................43 1. dfinition....................................................................................................................................................................................43 2. exemple ......................................................................................................................................................................................43 E. Paramtre Donne/rsultat......................................................................................................................................................43 1. dfinition....................................................................................................................................................................................43 2. exemple ......................................................................................................................................................................................43 F. Paramtre Donne Constante.................................................................................................................................................43 1. dfinition....................................................................................................................................................................................43 2. exemple ......................................................................................................................................................................................44 G. Paramtres facultatifs ou initialiss......................................................................................................................................44 1. dfinition....................................................................................................................................................................................44 2. exemple ......................................................................................................................................................................................44 H. Paramtres sans type................................................................................................................................................................44 1. dfinition....................................................................................................................................................................................44 2. exemples ....................................................................................................................................................................................44 I. Paramtres tableau ouvert ...........................................................................................................................................................45 1. dfinition....................................................................................................................................................................................45 2. Exemple .....................................................................................................................................................................................45 J. Paramtres tableau ouvert variant..............................................................................................................................................45 1. dfinition....................................................................................................................................................................................45 2. Exemple .....................................................................................................................................................................................46 K. Appel de procdure et de fonctions.......................................................................................................................................46 1. dfinition....................................................................................................................................................................................46 2. Exemple .....................................................................................................................................................................................46 L. Retour sur le type procdure ou fonction.............................................................................................................................47 1. dfinition....................................................................................................................................................................................47 2. Exemple .....................................................................................................................................................................................47 3. Exercice .....................................................................................................................................................................................48 VI. Structure de contrle ....................................................................................................................................................................48 A. La squence dinstructions et linstruction compose.......................................................................................................48 B. Linstruction Si .........................................................................................................................................................................49 1. dfinition....................................................................................................................................................................................49 C. Instructions Case......................................................................................................................................................................50 1. dfinition....................................................................................................................................................................................50 2. exemples ....................................................................................................................................................................................50 D. La boucle Rpter ....................................................................................................................................................................51 1. dfinition....................................................................................................................................................................................51 Delphi et Kilix D. Mailliet 4

5. 6. 7. 8. 9. 10. 11.

MIAGE 2me anne

exemples ....................................................................................................................................................................................51 La boucle tant-que ...................................................................................................................................................................51 1. dfinition ...................................................................................................................................................................................51 2. exemples ....................................................................................................................................................................................51 F. La boucle Pour..........................................................................................................................................................................52 1. dfinition ...................................................................................................................................................................................52 2. exemples ....................................................................................................................................................................................52 G. Break, Exit et Halt ..................................................................................................................................................................52 H. Boucles infinies ........................................................................................................................................................................53 I. Les Exceptions..............................................................................................................................................................................53 1. Instructions Try...except .........................................................................................................................................................53 2. Instructions try...finally ...........................................................................................................................................................55 J. Linstruction with.........................................................................................................................................................................56 K. Amlioration de la lisibilit....................................................................................................................................................57 L. Blocs et porte..........................................................................................................................................................................57 1. Blocs...........................................................................................................................................................................................57 2. Porte .........................................................................................................................................................................................58 3. Conflits de nom........................................................................................................................................................................58 4. Identificateurs qualifis...........................................................................................................................................................59 M. Exercice .....................................................................................................................................................................................59 VII. Surcharge des routines ................................................................................................................................................................59 1. dfinition ...................................................................................................................................................................................59 2. exemple ......................................................................................................................................................................................60 VIII. Exemples rcapitulatifs ...........................................................................................................................................................60 A. exemple 1 ..................................................................................................................................................................................60 B. exemple 2 ..................................................................................................................................................................................61 IX. Structure de donnes oriente objet..........................................................................................................................................62 A. Terminologie ............................................................................................................................................................................62 B. TObject et TClass....................................................................................................................................................................63 C. Exemple .....................................................................................................................................................................................64 D. Compatibilit des types classe...............................................................................................................................................64 E. Visibilit des membres de classes .........................................................................................................................................64 F. Constructeurs et destructeurs.................................................................................................................................................65 G. Exemple .....................................................................................................................................................................................65 H. Exemple dutilisation des objets prdfinis de delphi.......................................................................................................66 1. Exemple 1..................................................................................................................................................................................66 2. Exemple 2..................................................................................................................................................................................67 3. Exemple 3..................................................................................................................................................................................67 4. Exemple 4..................................................................................................................................................................................68 I. Constitution des fichiers DPR, DMF, PAS..............................................................................................................................68 X. Hirarchie des classes, hritage et surcharge..........................................................................................................................69 A. Dfinition ..................................................................................................................................................................................69 B. Exemple .....................................................................................................................................................................................70 C. Suite de lexemple ...................................................................................................................................................................70 D. Mthodes statiques, virtuelles et dynamiques ou abstraites .............................................................................................71 XI. La programmation visuelle : lEDI et la VCL.........................................................................................................................71 A. Utilisation..................................................................................................................................................................................71 B. Programme le plus simple avec lEDI..................................................................................................................................72 C. API Windows ...........................................................................................................................................................................72 XII. Composants usuels.......................................................................................................................................................................72 A. La fiche : Composant "Form" ................................................................................................................................................73 1. Caractristiques........................................................................................................................................................................73 2. Quelques vnements pour form ......................................................................................................................................73 3. Modales ou non ?.....................................................................................................................................................................77 B. Composant "MainMenu"........................................................................................................................................................77 C. Composant "TPopupMenu" ...................................................................................................................................................78 D. Composant "Label"..................................................................................................................................................................78 E. Composant "Edit"....................................................................................................................................................................79 F. Composant "Memo"................................................................................................................................................................80 G. Composant "Button"................................................................................................................................................................80 Delphi et Kilix D. Mailliet 5 E.

2.

MIAGE 2me anne

H. XIII. A. B. C. D. E.

Composant "CheckBox" .........................................................................................................................................................81 Programmation vnementielle et envoi de messages.......................................................................................................82 Dfinition...................................................................................................................................................................................82 Exemple .....................................................................................................................................................................................82 Rponse un vnement.........................................................................................................................................................82 Retour sur les fichiers DFM ...................................................................................................................................................83 Exemple pratique : bouton double fonctionnalit............................................................................................................83 1. 1 Bouton 1 vnement ........................................................................................................................................................84 2. 2 Boutons 2 vnements.....................................................................................................................................................84 3. 1 Bouton 2 vnements ......................................................................................................................................................85 4. Conclusion.................................................................................................................................................................................85 XIV. vnements et Envoi de messages ........................................................................................................................................85 A. Evnements utilisateur............................................................................................................................................................86 B. Evnements systme ................................................................................................................................................................86 XV. Exemple rcapitulatif ...................................................................................................................................................................88 XVI. Transtypage des objets : loprateur As et is .......................................................................................................................92 1. Exemple 1 ..................................................................................................................................................................................92 2. Exemple 2 ..................................................................................................................................................................................93 XVII. Les Bases de Donnes.............................................................................................................................................................93 A. Bases Paradox et DBase..........................................................................................................................................................94 B. Bases ODBC :...........................................................................................................................................................................94 C. Cration tables ..........................................................................................................................................................................94 D. Lister les champs......................................................................................................................................................................95 E. Ajout denregistrements..........................................................................................................................................................95 F. Lister les enregistrements .......................................................................................................................................................95 G. Supprimer 1 enregistrement ...................................................................................................................................................95 H. Base de donnes texte..............................................................................................................................................................96 I. Base de donnes et SQL :............................................................................................................................................................96 1. insertion .....................................................................................................................................................................................96 2. suppression................................................................................................................................................................................96 3. exploration.................................................................................................................................................................................97 J. Utilisation classique des TABLEs .............................................................................................................................................97 K. Composants BD........................................................................................................................................................................98 1. Fiche ...........................................................................................................................................................................................98 L. Tables Matre/dtail .................................................................................................................................................................98 M. BD Tables ..................................................................................................................................................................................98 N. Composant BD .........................................................................................................................................................................99 1. QUERY......................................................................................................................................................................................99 2. Amliorations de la prsentation des colonnes dune grille (DBGrid)...........................................................................99 3. Les filtres :...............................................................................................................................................................................100 O. Impressions de rapports.........................................................................................................................................................100 P. Complments sur les DBGrid et transtypage en DrawGrid ............................................................................................101 Q. Table XML..............................................................................................................................................................................101 1. Le programme .........................................................................................................................................................................101 2. Le rsultat................................................................................................................................................................................102 3. Amliorations : .......................................................................................................................................................................104 4. Remarques...............................................................................................................................................................................104 XVIII. Canvas : une proprit commune tous les composants ................................................................................................105 XIX. OLE, COM et Automation ...................................................................................................................................................106 A. Dfinitions...............................................................................................................................................................................106 B. OLE : Exemples .....................................................................................................................................................................106 C. OLE Excel...............................................................................................................................................................................107 D. OLE Word ...............................................................................................................................................................................107 E. OLE Internet Explorer...........................................................................................................................................................107 F. OLE Conclusion.....................................................................................................................................................................108 G. OLE Excel : complments....................................................................................................................................................108 XX. Cration dun serveur OLE.......................................................................................................................................................109 XXI. Cration dun client OLE......................................................................................................................................................111 XXII. Modification du client-Serveur OLE ..................................................................................................................................111 XXIII. Notions avances sur les objets ...........................................................................................................................................112 Delphi et Kilix D. Mailliet 6

MIAGE 2me anne

A. Compatibilit des classes......................................................................................................................................................112 B. Mthodes Virtuelles et dynamiques....................................................................................................................................113 C. Conclusion ..............................................................................................................................................................................113 XXIV. Mthodes abstraites ...............................................................................................................................................................114 XXV. Le type Interface ....................................................................................................................................................................114 A. Interface : rsolution de nom...............................................................................................................................................115 B. Utilisation de interfaces ........................................................................................................................................................115 XXVI. Mthodes de classes ..............................................................................................................................................................116 A. Utilisation des mthodes de classes ....................................................................................................................................116 XXVII. Cration de composants ...................................................................................................................................................118 A. Vrification de composants..................................................................................................................................................119 B. Installation du composants ...................................................................................................................................................120 XXVIII. Flux......................................................................................................................................................................................120 A. Flux chanes............................................................................................................................................................................120 B. Flux mmoire ..........................................................................................................................................................................121 C. Flux fichiers ............................................................................................................................................................................121 XXIX. tude de cas : butineur Web ................................................................................................................................................122 XXX. Annexe 1 : Le langage S Q L...............................................................................................................................................126 1. Introduction ............................................................................................................................................................................126 2. Les diffrents types de donnes du SQL.............................................................................................................................126 3. Les bases de donnes sous SQL ..........................................................................................................................................127 4. La manipulation des tables en SQL ....................................................................................................................................127 5. Le verbe SELECT et les clauses ..........................................................................................................................................128 6. Remarques sur le format DATE et les combinaison de CLAUSES:..............................................................................129 7. La clause WHERE et les PREDICATS ...............................................................................................................................129 8. Les fonctions SQL/DBASE IV ..............................................................................................................................................130 9. Les fontions Dbase 4 .............................................................................................................................................................131 10. Utilisation du verbe SELECT dans la commande INSERT INTO ............................................................................131 XXXI. Annexe 2 : Dploiement .......................................................................................................................................................131 A. Utilisation d'installShield......................................................................................................................................................131 B. Complments..........................................................................................................................................................................135 XXXII. Annexe 3 : Notion d interfaces hommes-machines ...................................................................................................137 A. Les grands principes..............................................................................................................................................................137 1. Compatibilit ..........................................................................................................................................................................137 2. Homognit...........................................................................................................................................................................138 3. Concision.................................................................................................................................................................................138 4. Flexibilit (souplesse)...........................................................................................................................................................138 5. Feedback et guidage..............................................................................................................................................................138 6. Charge informationnelle .......................................................................................................................................................138 7. Contrle explicite...................................................................................................................................................................138 8. Gestion des erreurs ................................................................................................................................................................138 B. Quelques exemples dergonomie ........................................................................................................................................139 1. Utilisation de la couleur........................................................................................................................................................139 2. Prsentation des textes ..........................................................................................................................................................139 C. Causes et consquences ........................................................................................................................................................139 D. Liens intressants ...................................................................................................................................................................140 1. Microsoft Windows...............................................................................................................................................................140 2. OSF/Motif...............................................................................................................................................................................140 3. Les recommandation Afnor..................................................................................................................................................140 XXXIII. Les TPs................................................................................................................................................................................141 A. TP1 DELPHI : Nos Premiers pas........................................................................................................................................141 1. Exemple 1................................................................................................................................................................................141 a) Lancer lexcution.............................................................................................................................................................141 b) Ajout de composant......................................................................................................................................................141 c) Modifier les proprits .....................................................................................................................................................141 d) Ajouter des ractions des vnements....................................................................................................................141 2. Exemple 2................................................................................................................................................................................142 B. TP2 DELPHI : Quelques composants standards..............................................................................................................144 1. Exemple 2................................................................................................................................................................................144 C. TP3 DELPHI : Quelques composants standards (suite)..................................................................................................146 Delphi et Kilix D. Mailliet 7

MIAGE 2me anne

Exemple 3 ................................................................................................................................................................................147 TP4 DELPHI : Les botes de dialogue...............................................................................................................................151 TP5 DELPHI : Visualisateur de forme ...............................................................................................................................153 1. Cration dune bote de dialogue.........................................................................................................................................154 2. Interagir avec la bote de dialogue ......................................................................................................................................155 3. Reprendre les donnes partir de la bote .........................................................................................................................156 4. Amlioration ...........................................................................................................................................................................156 F. TP 6-7 : Bases de donnes sous Delphi 3 ..........................................................................................................................157 1. Cration dune nouvelle table ..............................................................................................................................................157 a) Dfinition dun index........................................................................................................................................................158 b) Enregistrement...............................................................................................................................................................158 2. Manipulation dune table ......................................................................................................................................................158 3. Ajout et modification de donnes........................................................................................................................................159 4. Crer un nouveau projet........................................................................................................................................................159 5. Grer la base de donnes.......................................................................................................................................................160 1. Table des clients .....................................................................................................................................................................162 2. Table des contacts..................................................................................................................................................................163 a) Dfinition dun index secondaire....................................................................................................................................163 3. Table des appels .....................................................................................................................................................................164 4. Crer lapplication..................................................................................................................................................................165 5. Les pages multiples de contrles.........................................................................................................................................165 6. La page Contacts Clients ................................................................................................................................................165 7. Crer un lien entre les deux tables ......................................................................................................................................166 8. La page Appel Contacts....................................................................................................................................................167 a) Les contrles des bases de donnes................................................................................................................................167 b) Les composants Lookup............................................................................................................................................167 9. Utiliser un DBGrid comme une liste de positionnement..............................................................................................168 a) Grer les champs lexcution .......................................................................................................................................168 G. TP7 DELPHI : Le dessin et la souris .................................................................................................................................169 1. Crer un projet ........................................................................................................................................................................169 2. Ragir la souris ....................................................................................................................................................................169 H. TP 8 : Drag & Drop suite + Application Console Graphique.........................................................................................172 1. Drag et drop dans une stringgrid : le taquin torique.........................................................................................................172 2. Application Console / Graphique ........................................................................................................................................173 I. TP9 DELPHI : Communication OLE et DDE.......................................................................................................................176 1. DDE : Dynamic Data Exchange..........................................................................................................................................176 2. Le projet Serveur....................................................................................................................................................................176 3. Le projet Client .......................................................................................................................................................................177 4. Crer le projet .........................................................................................................................................................................177 5. Faire un lien avec le serveur DDE.......................................................................................................................................177 6. Cration de la base de donnes ............................................................................................................................................178 7. Le projet Delphi......................................................................................................................................................................179 a) Formulaire ...........................................................................................................................................................................179 b) Gestion des vnements...............................................................................................................................................179 (1) Exporter sous Word..................................................................................................................................................179 (2) Exporter toutes les factures.....................................................................................................................................180 J. TP10 DELPHI : Fioritureset amlioration des exemples ....................................................................................................181 1. Editeur de texte amlior ......................................................................................................................................................181 2. Crer des mthodes simples .................................................................................................................................................182 3. Crer des mthodes avec paramtres ..................................................................................................................................182 4. Paramtre sender....................................................................................................................................................................183 5. Proprit Tag...........................................................................................................................................................................183 6. Variable locale ........................................................................................................................................................................183 K. TP11 DELPHI : Applications SDI et MDI ........................................................................................................................188 1. Palette doutils ........................................................................................................................................................................188 a) Modification de la fiche ...................................................................................................................................................188 b) Dfinition du glisser-dplacer.....................................................................................................................................189 c) Applications MDI..............................................................................................................................................................190 (1) Crer un nouveau projet...........................................................................................................................................190 (2) Fentre principale MDI............................................................................................................................................190 Delphi et Kilix D. Mailliet 8 D. E.

1.

MIAGE 2me anne

(3) Crer une fentre fille ..............................................................................................................................................190 (4) Choisir la cration automatique ou non des fiches .............................................................................................190 L. TP 12 : Crer un composant.................................................................................................................................................193 1. Crer un nouveau composant...............................................................................................................................................193 2. Dclaration..............................................................................................................................................................................193 a) Evnements existants........................................................................................................................................................193 b) Evnement ajouts........................................................................................................................................................194 c) Proprits existantes .........................................................................................................................................................194 d) Proprits ajoutes........................................................................................................................................................194 3. Implmentation.......................................................................................................................................................................195 4. Grer son affichage................................................................................................................................................................198 a) Dclaration .........................................................................................................................................................................198 b) Implmentation..............................................................................................................................................................199 5. Grer les clics .........................................................................................................................................................................201 a) Dclaration .........................................................................................................................................................................201 b) Implmentation..............................................................................................................................................................202

Delphi et Kilix

D. Mailliet

MIAGE 2me anne

Delphi et KyliX : des descendants de Pascal

I.
A.

EDI : lenvironnement de dveloppement intgr


La fentre principale

LEDI est constitu de 4 fentres (seulement les 2 premires pour des applications consoles) .

Cette partie est elle-mme divise en trois parties : 1. La barre de menus

("File Edit Search..."),... - Les menus : il n'y a pas grand chose en dire. Je ne vais pas tous les passer en revue, les noms sont en gnral bien explicite et il y a l'aide si vraiment il y a peu de chose qui sert dans un premier temps. A part "New Application", "Run" (la flche jaune en icne) et "Program Reset" pour arrter l'excution d'un programme qui ne marche pas, c'est peu prs tout... 2. 3. La barre doutils La palette de composants Des boutons permettent daccder aux commandes les plus frquemment utilises. Les composants sont des bouts de programme qui ont dj t fait pour vous. Exemple... Si vous voulez mettre un bouton dans une fentre, vous avez juste prendre un bouton, et le poser sur votre fentre sans avoir besoin d'expliquer l'ordinateur ce qu'est un bouton, comment on clique dessus, ce qu'il se passe graphiquement quand on clique dessus, bref, c'est dj fait. Les plus couramment utiliss sont ceux de la palette de composants "Standard" : dans l'ordre, on peut y voir un menu droulant, une liste, un label (de l'criture, quoi...), une ligne d'dition ("edit box"), une zone de texte ("menu"), un bouton, une case cocher, etc... Tout les composants de base d'une fentre classique. Il existe des tonnes de composants, et ils sont souvent compatibles entre Delphi et C++ Builder. Vous en trouverez beaucoup de gratuit sur Internet, et aprs, vous les ferez vousmme! Une adresse utile pour trouver de nouveaux composants : http://www.developpez.com/ delphi/freewares.htm

B.

Lditeur de code

Il crit directement le minimum requis pour votre application et cre seul les fichiers associs. Par contre, le revers de la mdaille, il n'est pas conseill de modifier ce qu'il crit. Si vous voulez supprimer un bouton par
Delphi et Kilix

10

D. Mailliet

MIAGE 2me anne

exemple, ne l'effacez pas directement dans le code, mais effacez-le graphiquement : le compilateur s'occupera du reste. Nous verrons plus tard comment rajouter son programme...

C.

Le concepteur de fiches (ou de forms )

C'est la fentre que va voir l'utilisateur lorsqu'il lance le programme. Pour l'instant, elle est vide, mais c'est l qu'on peut rajouter les menus, les boutons et tout le reste... Vous pouvez, bien entendu, l'agrandir, la rduire, bref, faire tout ce que vous voulez sans taper une ligne de code...

D.

Linspecteur dobjets

C'est dans cette partie qu'on donne les caractristiques des composants que l'on place sur sa fentre ou les caractristiques de la fentre gnrale. Ici, on peut voir qu'il s'agit des caractristiques gnrales de la fentre car on voit " Form1: TForm1 ". "Form1" signifie qu'on regarde les caractristiques d'un composant de la fentre "Form1" (il peut en effet y avoir Form2, Form3, ou mme canard ou poisson, puisque vous donnez le nom que vous voulez chaque fentre...) et "TForm1" dsigne la fentre en gnral. Mme s'il est possible de changer le nom des composants ou des fentres, je vous conseille de laisser les noms par dfaut si vous n'avez pas l'intention de faire un programme norme avec 15 fentres diffrentes. Remarque : quand je parle de nom de la fentre, ne confondez pas avec ce qu'il y aura d'crit comme titre de fentre. Je parle du nom de la fentre pour le programme ("name" dans les "properties") et non pas du titre qui s'affiche l'cran ("caption" dans les "properties"). Ainsi, si vous placez un bouton sur votre fentre, vous changerez ce qu'il y a d'crit sur le bouton en changeant le "Button1" de "caption" par "quitter" ou "enregistrer" ou ce que vous voulez, mais le bouton s'appellera toujours "Button1" pour le programme , seul l'affichage changera lors de l'excution... Essayez de changer "caption" (la partie slectionne sur l'image) : le nom de la fentre change...

E.

Laide Delphi

Il ne faut pas hsiter consulter laide Delphi pour obtenir tous les complments ncessaires : en particulier les fonctions ne sont que dcrites et on ne donne pas la liste des paramtres employer, car ceci son dcrits dans laide en utilisant la touche F1 ou lindex ou rechercher .
Delphi et Kilix

11

D. Mailliet

II.
A.

Prsentation gnrale
Structure dun programme Pascal, Delphi ou Kylix

Cette structure ressemble fort celle des programmes des langages de haut niveau tels : ADA, C++,Visual basic, Java Le nom du programme doit tre le mme que le nom Le programme Program <nom_prog> ; du fichier qui le contient. Uses <liste des units spares par des virgules> ; Ces parties encadres sont Dclaration des objets et des outils du programme facultatives <Dclaration des constantes> <Dclaration des types> Il nest pas <Dclaration des variables> impratif de respecter lordre Dclaration des procdures indiqu ci-contre Procedure <nom_proc> ( <liste des Paramtres Formels avec leur type>) ; Remarquons que la structure des Dclaration des objets et des outils de la procdure dclarations des < Structure identique la dclaration des objets et des outils outils et des objets du programme > (cadres doubles) est Begin identique la Corps de la procdure structure qui les <Instructions> contient : un peu End ; la manire des poupes russes qui souvrent en 2 parties et qui Dclaration des autres procdures et des autres fonctions contiennent des < Identique la structure ci-dessus et ci-dessous> poupes russes qui souvrent en 2 parties et qui contiennent Dclaration des fonctions A la diffrence Function<nom_fonc>(<liste des P.F. avec leur type>) : <type du rsultat> ; des poupes russes , cette Dclaration des objets et des outils structure de < Structure identique la dclaration des objets et des outils dclarations peut du programme > contenir Begin rcursivement non Corps de la fonction pas une mais plusieurs structures <Instructions> contigus. result := <le rsultat de la fonction> End ; Une fonction BEGIN renvoie un rsultat Corps du programme par le biais de <Instructions> rsult END . Cette partie aussi est facultative En supprimant les parties facultatives, il reste le programme le plus simple que lon puisse crire. Il sagit dune application console, la plus simple possible que vous pouvez compiler et excuter depuis la ligne de commande program Kedal; {$APPTYPE CONSOLE} dclare un programme appel Kedal indique au compilateur que c'est une application console qui doit tre excute depuis la ligne de commande dclaration des constantes, des types, des classes, des variables, des

MIAGE 2me anne

procdures et des fonctions (ici aucune) begin dbut de lexcution du programme liste des instructions du programme (ici vide) fin de lexcution du programme end. Remarques : o Ce qui est entre accolades { } est un commentaire (et donc ignor du compilateur), mais o Sil y a un $ coll contre laccolade {$ } ceci devient une directive de compilation. o Ne pas oublier le point-virgule (il spare 2 instructions mais nest pas une fin de ligne comme en ada et en C) la fin de la premire ligne et le point final. Si Delphi est install et si votre chemin d'accs contient le rpertoire Delphi\Bin (o se trouvent les fichiers DCC32.EXE et DCC32.CFG), vous pouvez saisir ce programme dans un fichier appel Kedal.PAS ou mieux Kedal.DPR laide dun diteur texte (comme le bloc-notes de windows) puis le compiler en saisissant, dans une fentre dos, la ligne (il peut tre ncessaire dajouter les chemins): DCC32 Kedal sur la ligne de commande qui produira l'excutable rsultant (kedal.EXE) dont la taille est denviron 37 ko. On peut lexcuter en tapant sur la ligne de commande : Kedal Si lon double-clique sur kedal.EXE dans la fentre de lexplorateur, une fentre console va souvrir et se refermer immdiatement puisque ce programme ne fait rien (mais il le fait bien) dans la mesure o il ne contient aucune instruction. Ainsi, on peut bloquer lexcution en ajoutant linstruction readln qui attend que lutilis ateur ait tap sur des touches du clavier (ventuellement aucune) puis sur la touche entre. Il est dailleurs possible, avec readln(x), de mmoriser dans une variable x par exemple, ce que lutilisateur a tap. On aura dclar x avant le begin. On prviendra lutilisateur auparavant grce un message au moyen de writeln(Appuyez sur entre). Tout ceci donne : program Kedal; {$APPTYPE CONSOLE} begin writeln(Appuyez sur entre) ; readln end. Mis part sa simplicit, cet exemple diffre largement du type de programme que vous allez probablement crire avec Delphi. Tout d'abord, c'est une application console. Delphi est gnralement utilis pour crire des applications Windows ayant une interface graphique ; ainsi, dans une application Delphi vous ne devez normalement pas appeler Writeln. De plus, la totalit du programme exemple ( l'exception de Writeln) se trouve dans un seul fichier. Dans une application Delphi, l'en-tte du programme (la premire ligne de cet exemple) se trouve dans un fichier projet spar qui ne contient pas la logique relle de l'application sinon quelques appels aux mthodes dfinies dans les fichiers unit.

B.

Utiliser des units

Il est possible, selon la nature des applications, dutiliser ou non certaines bibliothques qui contiennent fonctions, procdures et autres objets divers et varis. Le noyau se situe dans une unit nomme system quil est inutile de dclarer : on aurait trs bien pu mettre : uses system ; dans le programme prcdent, a naurait rien chang). Writeln et readln font partie du noyau de delphi, alors que le programme : program Kedal; {$APPTYPE CONSOLE} uses dialogs; begin ShowMessage('Cliquez pour quitter) ; end. Le programme prcdent va, en plus de lapplication console, ouvrir une bote avec un message et un bouton. Lorsque lon clique sur le bouton, on ferme la boite message ce qui a pour effet de terminer lapplication puisque ShowMessage est la dernire instruction du programme.
Delphi et Kilix

13

D. Mailliet

MIAGE 2me anne

C.

Crer des units


Le nom de lunit doit tre le mme que le nom du fichier qui le contient.

Le programme Unit <nom_unit> ; Interface Uses <liste des units spares par des virgules> ; Dclaration des objets et des entte des outils partags par lunit <Section identique aux dclarations dans le programme> implementation Dclaration des objets et des outils locaux lunit <Section en tous points identique aux dclarations dans le programme> Dclaration des outils globaux de lunit <Section en tous points identique aux dclarations dans le programme> INITIALIZATION Corps du programme ralis a linitialisation <Instructions> FINALIZATION Corps du programme ralis au moment de quitter <Instructions> END .

objets et outils utilisables lextrieur de lunit

Partie facultative. Lordre nest pas respecter. On doit retrouver les mmes enttes des procdures et des fonctions dans la partie implmentation que dans la partie interface

Ces parties sont facultatives et rarement prsentes dans les units

D.

Les projets

L'exemple suivant propose un programme constitu de deux fichiers : un fichier projet et un fichier unit. Le fichier projet, que vous pouvez enregistrer sous le nom Kedal.DPR, a la forme suivante : program Kedal; unit Unitstop; {$APPTYPE CONSOLE} interface uses Unitstop; begin stop end. procedure stop; implementation procedure stop; begin writeln(Appuyez sur entre) ; readln end;

end. La premire ligne dclare un programme appel Kedal qui, encore une fois, est une application console. La clause uses UnitStop; spcifie au compilateur que Kedal inclut une unit appele UnitStop. Enfin le programme appelle la procdure
Delphi et Kilix

14

D. Mailliet

MIAGE 2me anne

Stop. Mais o se trouve la procdure Stop ? Elle est dfinie dans UnitStop. Le code source de UnitStop (colonne de droite) que vous devez enregistrer dans un fichier appel UNITSTOP.PAS UnitStop dfinit une procdure appele Stop. En Pascal, les routines qui ne renvoient pas de valeur sont appeles des procdures. Les routines qui renvoient une valeur sont appeles des fonctions. Remarquez la double dclaration de Stop dans UnitStop. La premire dclaration, aprs le mot rserv interface, rend Stop accessible aux modules (comme Kedal) qui utilisent UnitStop. Le seconde dclaration, place aprs le mot rserv implmentation, dfinit rellement Stop. Vous pouvez maintenant compiler Kedal depuis la ligne de commande en saisissant : DCC32 KEDAL Il n'est pas ncessaire d'inclure UnitStop comme argument de la ligne de commande. Quand le compilateur traite le fichier KEDAL.DPR, il recherche automatiquement les fichiers unit dont dpend le programme Kedal. L'excutable rsultant (KEDAL.EXE) fait la mme chose que le premier exemple : Rien de plus que dafficher un message et dattendre que lutilisateur appuie sur entre. Utiliser des units o vite au compilateur de recompiler une partie de code si le programmeur na pas modifi lunit correspondante o permet au programmeur de fournir un fichier .DCU (Unit Delphi Compile) et un mode demploi rendant cette unit parfaitement utilisable tout en protgeant son code.

E.

Fichiers dun projet

En gnral, on regroupe tous ces fichiers (il peut y avoir plus dune unit, et mme dautres fichiers ) dans un rpertoire le fichier dpr en faisant partie lui aussi. On y trouve notamment : Extension du fichier DPR PAS Description et Commentaires (Delphi PRoject) Contient l'unit principale du projet (PAS cal) Contient une unit crite en Pascal. Peut avoir un .DFM correspondant (Delphi ForM : fiche Delphi) Contient une fiche (une fentre). Le .PAS correspondant contient toutes les informations relatives au fonctionnement de cette fiche, tandis que le .DFM contient la structure de la fiche (ce qu'elle contient, sa taille, sa position, ). Sous Delphi 5, les .DFM deviennent des fichiers texte qu'il est possible de visualiser et de modifier. La mme manipulation est plus dlicate mais possible sous Delphi 2 4. (Delphi Compiled Unit : Unit compile Delphi) Forme compile et combine d'un .PAS et d'un .DFM optionnel Tous les fichiers dont l'extension commence par ~ sont des fichiers de sauvegarde, pouvant tre effacs pour faire place propre. Fichier excutable de l'application. Ce fichier est le rsultat final de la compilation et fonctionne sous Windows exclusivement. Pour distribuer le logiciel, copier ce fichier est souvent suffisant. (RES source) Fichier contenant les ressources de l'application, tel son icne. Ce fichier peut tre dit avec l'diteur d'images de Delphi. Ces notions seront abordes plus loin dans ce guide. Fichiers d'options : suivant les versions de Delphi, ces fichiers contiennent les options du projet, les options d'affichage de Delphi pour ce projet, ...

DFM

DCU ~??? EXE RES DOF DSK CFG

III. lments de syntaxe


A. Commentaires
15 D. Mailliet Les commentaires se placent entre accolades ou parenthses et toiles ou derrire 2 slaches:
Delphi et Kilix

MIAGE 2me anne

{ceci est un commentaire} (*ceci est un autre commentaire*) // tout ce qui suit et jusqu la fin de ligne est aussi un commentaire

B.

Directive de compilation

Comme les commentaires, elles se mettent entre { }, mais la premire accolade est suivie de $. Ce $ est lui-mme immdiatement suivi de la directive. Ce ne sont pas des instructions du langage, elles servent donner des instructions au compilateur, par exemple: Pour mettre au point un programme, on peut avoir besoin dajouter des instructions que lon effacera dans la version dfinitive.

{$Define test} ... {$IFDEF test} ... <Les instructions qui seront utilises uniquement pendant la phase de mise au point> {$ENDIF} On compile le programme de cette manire pendant les tests, puis il suffit dinsrer un espace avant le $ { $Define test} pour transformer cette ligne en commentaire et de ce fait inhiber la dfinition test et par consquent d valider les instructions comprises entre le {$IFDEF test} et {$ENDIF} Pour crire des programmes portables sous Windows et Linux : uses {$IFDEF WIN32} Windows, Messages, Graphics, Controls, Forms, Dialogs, Menus, StdCtrls, Buttons, ExtCtrls, MMSystem, ComCtrls, {$ENDIF} {$IFDEF LINUX} QGraphics, QControls, QForms, QDialogs, QMenus, QStdCtrls, QButtons, QExtCtrls, QComCtrls, {$ENDIF} SysUtils, Classes; WIN32 ou LINUX sont automatiquement dfinis selon le Systme dExploitation sous lequel on compile. Dans lexemple prcdent, les bibliothques correspondant au bon S.E. seront utilises. SysUtils et Classes tant communes aux 2 S.E. Pour forcer le compilateur effectuer ou non certaines vrifications. Ce sont des directives bascules. Par exemple: {$B+} Force lvaluation complte des boolens alors que {$B-} effectue lvaluation partielle (Voir le type boolen) {$R+} Vrifie le non-dbordement des tableaux. Alors que {$R-} permet de dfinir un tableau de 5 cellules et lcriture dune valeur dans la 6me ne dclenchera pas derreur (Mais aura pour consquence dcraser peut-tre dautres variables en mmoire). Il est clair que la vrification du non-dbordement une scurit dans le droulement du programme mais aussi gnre des instructions machines supplmentaires et donc ralentissent le droulement du programme. On peut cumules ces directives bascules et mme les commenter: {$B+,R-,S-} {$R- Dsactive la vrification des limites} On peut aussi utiliser ces directives dans la ligne de commande: (Ne pas oublier le /): DCC32 MonProg /$R-,I-,V-,U+ Pour les autres directives comme $I, $L etc., on se rfrera laide de Delphi. En utilisant LEDI, Ces directives sont gnres automatiquement et rassembles dans un fichier DOF, DSK CFG

C.

Identificateurs

Un identificateur commence obligatoirement par une lettre ou un trait-bas suivi de lettres, chiffres ou trait-bas lexclusion de tout autre caractre. Les caractres accentus sont aussi interdits. Comme en ADA et contrairement C et Java, il ny a pas de diffrence entre majuscule et minuscules.

D.

Identificateurs qualifis

Quand vous utilisez un identificateur qui a t dclar plusieurs endroits, il est parfois ncessaire de qualifier l'identificateur. On utilise un point entre les 2 identificateurs. La syntaxe d'un identificateur qualifi est : identificateur1.identificateur2 Delphi et Kilix D. Mailliet 16

MIAGE 2me anne

o identificateur1 qualifie identificateur2. Si, par exemple, deux units dclarent une variable appele MaVar, vous pouvez dsigner MaVar de Unit2 en crivant : Unit2.MaVar Il est possible de chaner les qualificateurs. Par exemple : Form1.Button1.Click Appelle la mthode Click de Button1 dans Form1. Si vous ne qualifiez pas un identificateur, son interprtation est dtermine par les rgles de porte dcrites dans Blocs et porte.

E.

Affectation

On utilise le symbole := pour donner une valeur une variable. Par exemple: a:=5; b:=Bonjour; Ou encore Pour permuter les valeurs des variables x et y : t:=x; x:=y; y:=t;

F.

Sparateur dinstruction.

Contrairement dautres langages (C, ADA, etc.) le Point-virgule nest pas une fin dinstruction mais un sparateur. Cest dire quil ne se place pas systmatiquement la fin dune instruction, mais entre 2 instructions. En particulier il ny a pas lieu de mettre un point-virgule avant un end mme si le compilateur le tolre alors que le point-virgule devant un else provoque une erreur de compilation

G.
Const

Dclaration de Types, de constante et de variables

On utilise Type Const et Var . ainsi que les symboles : et = (pas le symbole := ) lgmax=100; nl = #10{$IfNDef LINUX}#13{$end if} ; //Dfinition des caractres de contrles permettant un saut de ligne Type Ttableau = array [1..lgmax] of integer; // tableau de lgmax (=100) entiers Tchn32 = string[32]; // chaine dau plus 32 caractres Var i : integer; x : real; c : string [12]; c_32 : Tchn32; tb1 : array [1..5] of string [8]; tb2 : Ttableau; Remarquons le = pour les types et les constantes et le : pour les variables. Ainsi que les crochets pour les tableaux et les chanes, mais on y reviendra plus tard. Il peut y avoir des dclarations de variables de types et de constantes en plusieurs endroits du programme Dans la mesure o lutilisation ne peut se faire quaprs dclaration

IV. Types et structure de donnes simples


Les routines qui suivent sont donnes en vrac et correspondent la version 5 de Delphi : Il convient de vrifier dans laide : o si elles existent dans la version utilise o de quelle unit elles font partie (les principales font partie de lunit system unit par dfaut- mais pas toutes !) o quels sont les paramtres utiliss ainsi que leur type

Delphi et Kilix

17

D. Mailliet

MIAGE 2me anne

A.
1.

Le type scalaire
Dfinition

Un type scalaire dfinit un ensemble ordonn de valeurs dont chaque valeur, sauf la premire, a un prdcesseur unique et dont chaque valeur, sauf la dernire, a un successeur unique. Chaque valeur a un rang qui dtermine l'ordre du type. Pour les types entiers, le rang d'une valeur est la valeur mme ; pour tous les autres types scalaires l'exception des intervalles, la premire valeur a le rang 0, la valeur suivante a le rang 1, etc. Si une valeur a le rang n, son prdcesseur a le rang n 1 et son successeur a le rang n + 1. 2. Routines ordinales

Dec, procdure Inc, procdure Odd, fonction Ord, fonction Pred, fonction Succ, fonction High, fonction Low, fonction 3.

Dcrmente une variable de 1 ou de N Incrmente X de 1 ou de N Renvoie True si argument est un nombre impair Renvoie la valeur scalaire d'une expression de type scalaire Renvoie le prdcesseur de l'argument Renvoie le successeur de l'argument. Renvoie la plus grande valeur du type Renvoie la plus petite valeur du type

Priorit des oprateurs

Oprateurs Priorit @, not premire (maximum) *, /, div, Mod, and, shl , shr, as seconde +, , or, xor troisime =, <>, <, >, <=, >=, in, is quatrime (minimum) Un oprateur de priorit plus leve est valu avant un oprateur de priorit plus basse, les oprateurs de mme priorit tant valus partir de la gauche 4. Le type boolen a) Type Boolean ByteBool WordBool LongBool Quelques diffrences : Boolean False < True Ord(False) = 0 Ord(True) = 1 Succ(False) = True Pred(True) = False b) Oprateur not and or xor Table de vrit : A False B False Dfinition tendue True et False True et False True et False True et False ByteBool, WordBool, LongBool False <> True Ord(False) = 0 Ord(True) <> 0 Succ(False) = True Pred(False) = True Oprateurs Types d'oprande boolen boolen boolen boolen A and B False 18 Types du rsultat Boolean Boolean Boolean Boolean A xor B False D. Mailliet Exemple not (C in MySet) Done and (Total > 0) A or B A xor B Format 1 octet (8 bits) 1 octet 2 octets 4 octets

Opration ngation conjonction disjonction disjonction exclusive not A True A or B False

Delphi et Kilix

MIAGE 2me anne

False True True

True False True

True False False

True True True

False False True

True True False

Retour sur la directive de compilation $B+ : True or X donne True quelque soit la valeur de X, de mme False and X donne False quelque soit la valeur de X Dans une expression boolenne faisant intervenir un or, lorsque le premier oprande vaut True, il est inutile de calculer la valeur du second. Ceci pose un problme lorsque celui-ci est un prdicat (fonction rsultat boolen) et que cette fonction produit un effet de bord ( Modification de lenvironnement global) La seconde valuation ntant pas faite, leffet de bord na pas lieu. Il en va de mme lorsque le premier oprande dun and vaut faux c) Procdure et fonctions

Ce sont les routines ordinales valables pour tous les types scalaires d) Oprateurs relationnels

Les oprateurs relationnels sont utiliss pour comparer deux oprandes. Les oprateurs =, <>, <= et >= s'appliquent galement aux ensembles (voir Oprateurs d'ensembles) ; = et <> s'appliquent galement aux pointeurs (voir Oprateurs de pointeurs). Oprateur Opration Types d'oprande Type du Exemple rsultat = galit simple, classe, rfrence de classe, interface, Boolean I = Max chane, chane compacte <> diffrence simple, classe, rfrence de classe, interface, Boolean X <> Y chane, chane compacte < infrieur simple, chane, chane compacte, PChar Boolean X<Y > suprieur simple, chane, chane compacte, PChar Boolean Len > 0 <= infrieur ou gal simple, chane, chane compacte, PChar Boolean Cnt <= I >= Suprieur ou gal simple, chane, chane compacte, PChar Boolean I >= 1 in Membre de oprande gauche: tout type ordinal T, Boolean 5 in [3..9]; oprande droit: ensemble de base compatible 'K' in['a'..'z']; avec T. Dans la plupart des cas simples, la comparaison est vidente. Par exemple I = J vaut True uniquement si I et J ont la mme valeur, sinon I>J vaut True. Les rgles suivantes s'appliquent aux oprateurs de comparaison : Les oprandes doivent tre de types compatibles, sauf pour un rel et un entier qui peuvent tre compars. e) Exemples Selon la rgle des priorits des oprateurs : A>B or C<=D provoquera une erreur car B or C sera valu avant toute chose : Il faut donc systmatiquement mettre de parenthses pour modifier lordre dvaluation: (A>B) or (C<=D) 5. Le type entier a) Dfinition

Type tendue Format Integer 2147483648..2147483647 32 bits sign Cardinal 0..4294967295 32 bits non sign Shortint 128..127 8 bits sign Smallint 32768..32767 16 bits sign Longint 2147483648..2147483647 32 bits sign Int64 2^63..2^631 64 bits sign Byte 0..255 8 bits non sign Word 0..65535 16 bits non sign Longword 0..4294967295 32 bits non sign Par dfaut les entiers sont exprims en dcimal , mais il est possible de manipuler des nombres hexadcimaux : $FF vaut 255
Delphi et Kilix

19

D. Mailliet

MIAGE 2me anne

b)

Oprateurs

En plus des oprateurs relationnels dfinis plus haut, les oprateurs arithmtiques suivants attendent des oprandes rels ou entiers : +, , *, /, div et Mod. Oprateur + * / div Mod + (unaire) (unaire) not and or xor shl Opration Types d'oprande addition entier, rel soustraction entier, rel multiplication entier, rel division relle entier, rel division entire entier reste entier signe identit entier, rel signe ngation entier, rel ngation bit bit entier et bit bit entier ou bit bit entier ou exclusif bit bit entier rotation des bits vers entier la gauche shr rotation des bits vers entier la droite Les rgles suivantes s'appliquent aux oprateurs arithmtiques. Type du rsultat entier, rel entier, rel entier, rel rel entier entier entier, rel entier, rel entier entier entier entier entier entier Exemple X+Y Result - 1 P * InterestRate X/2 Total div UnitSize Y Mod 6 +7 -X

La valeur de x/y est de type Extended (voir type rel), indpendamment du type de x et y. Pour les autres oprateurs, le rsultat est de type Extended ds qu'au moins un des oprandes est de type rel ; sinon le rsultat est de type Int64 quand au moins un des oprandes est de type Int64 ; sinon le rsultat est de type Integer. Si le type d'un oprande est un sousintervalle d'un type entier, il est trait comme tant de ce type entier. La valeur de x div y est la valeur de x/y arrondi vers le bas l'entier le plus proche. L'oprateur Mod renvoie le reste obtenu par la division de ses oprandes. En d'autres termes : x Mod y = x (x div y) * y. Il y a une erreur d'excution si y vaut zro dans une expression de la forme x/y, x div y ou x Mod y. A 0 0 1 1 B 0 1 0 1 not A 1 1 0 0 A or B 0 1 1 1 A and B 0 0 0 1 A xor B 0 1 1 0

shl produit un dcalage des bits de lentier vers la gauche et ajoute un 0 donc multiplier par 10 en binaire (cest dire2 en dcimal). Shr produit un dcalage dans lautre sens cest dire diviser par 2. n shl p (dcalage de p bits a gauche avec introduction de p 0) donne n*2p . c) Procdure et fonctions

Fonction abs Valeur absolue Hi poids fort Lo poids faible odd test de parit Sqr carr du nombre On remarquera que la fonction puissance nest pas dfinie en standard : il faut utiliser lunit Math ou la fonction IntPower est dfinie
Delphi et Kilix

20

D. Mailliet

MIAGE 2me anne

d)

Exemple

compte tenu de la priorit des oprateurs: 5+ 3*2 donne 11 56 or 20 donne 60 56 and 20 donne 16 56 xor 20 donne 44 en binaire 56 scrit 00111000 et 20 scrit 00010100 56 shl 2 donne 224 dcaler 00111000 de 2 rangs gauche donne 11100000 6. Le type caractre a) Dfinition

Les types de caractre fondamentaux sont AnsiChar et WideChar. Les valeurs AnsiChar sont des caractres sur un octet (8 bits) ordonns selon le jeu de caractres ANSI tendu. Les valeurs WideChar sont des caractres sur un mot (16 bits) ordonns selon le jeu de caractres Unicode. Les 256 premiers caractres Unicode correspondent aux caractres ANSI. Le type de caractre gnrique Char est quivalent AnsiChar. Comme l'implmentation de Char est susceptible de changer, il est judicieux d'utiliser la fonction standard SizeOf plutt qu'une constante code en dur dans les programmes qui doivent grer des caractres de tailles diffrentes. Une constante chane de longueur 1, comme 'A', peut dsigner une valeur caractre. La fonction prdfinie Chr renvoie la valeur caractre pour tout entier dans l'tendue de AnsiChar ou de WideChar ; ainsi, Chr(65) renvoie la lettre (code ASCII 65). un entier prfix par # donne le caractre dont le code ASCII est cet entier. b) Les oprateurs relationnels c) Les routines ordinales et Fonction chr upcase donne le caractre correspondant au code ASCII convertit un caractre en majuscule si elle exis te et le conserve sinon. Attention aux caractres accentus d) Exemples Procdure et fonctions Oprateurs

Les valeurs de caractre, comme les entiers, bouclent quand elles sont dcrmentes ou incrmentes au-del du dbut ou de la fin de leur tendue ( moins que la vrification des limites ne soit active). Ainsi, une fois le code suivant excut var lettre : char; ... begin lettre :=High(char); // le caractre dont le code ASCII est 255 . Le code du suivant est 0 ..lettre:=High(lettre); // est quivalent la ligne prcdente inc(lettre,66); // caractre dont le code Ascii est 65 cest dire A ... lettre := #65; // est quivalent lettre := chr(65) pred(D) vaut C C<>c vaut True Chr(66) vaut B ord(B) vaut 66 7. Le type numr a) Dfinition

Un type numr dfinit une collection ordonne de valeurs simplement en numrant les identificateurs dsignant ces valeurs. Les valeurs n'ont pas de signification propre et leur rang suit l'ordre d'numration des identificateurs. Pour dclarer un type numr, utilisez la syntaxe suivante : type nomType = (val1, ..., valn) o nomType et les val sont des identificateurs valides.

Delphi et Kilix

21

D. Mailliet

MIAGE 2me anne

b) ... Type

Exemples

Tcartes = (_7,_8,_9,_10,Valet,Dame,Roi,As); // Remarquons le trait_bas pour le respect des rgles sur les identifiants i:= ord(carte); var writeln(i, ,_9<Dame, ,ord(_7)); // affichera carte : Tcartes; i : byte; 2 TRUE 0 BEGIN readln; // la tentative dafficher carte carte := _8; provoquerait une erreur inc(carte,2); END. carte := pred(carte); 8. Le type intervalle a) Dfinition

Un type intervalle reprsente un sous-ensemble de valeurs d'un autre type (appel le type de base). Toute construction de la forme Bas..Haut, o Bas et Haut sont des expressions constantes du mme type scalaire, Bas tant infrieur Haut, identifie un type intervalle qui inclut toutes les valeurs comprises entre Bas et Haut. b) Exemples

Type Tchiffres =0..9; Tminuscules = a..z; Tcartes = (_7,_8,_9,_10,Valet,Dame,Roi,As); // Cest un type numr pour dfinir le type suivant Tfigures = Valet..Roi; // qui lui est du type intervalle

B.
1.

Le type rel
Dfinition

Un type rel dfinit un ensemble de nombres pouvant tre reprsents par une notation virgule flottante. Le tableau suivant donne l'tendue et le format de stockage des types rels fondamentaux. Type tendue Chiffres significatifs Taille en octets Real48 2.9 x 10^39 .. 1.7 x 10^38 1112 6 Single 1.5 x 10^45 .. 3.4 x 10^38 78 4 Double 5.0 x 10^324 .. 1.7 x 10^308 1516 8 Real 5.0 x 10^324 .. 1.7 x 10^308 1516 8 Extended 3.6 x 10^4951 .. 1.1 x 10^4932 1920 10 Comp 2^63+1 .. 2^63 1 1920 8 Currency 922337203685477.5808.. 922337203685477.5807 1920 8 Le type gnrique Real est quivalent, dans son implmentation actuelle, au type Double. La notation classique avec le point dcimal est employe. La notation scientifique (E ou e, puis un exposant) se lit "puissance 10" Currency est un type de donnes virgule fixe qui limite les erreurs d'arrondi dans les calculs montaires. Il est possible de stocker un entier dans un rel mais pas linverse. 2. Oprateurs

Voir les oprateurs sur les entiers. 3. Routines arithmtiques Vrifier dans laide sil est ncessaire dutiliser lunit Math *Abs, fonction Ceil, fonction Exp, fonction Floor, fonction Frac, fonction Frexp, procdure
Delphi et Kilix

Renvoie une valeur absolue Arrondit des variables vers l'infini positif Renvoie la valeur exponentielle de X Arrondit les variables vers l'infini ngatif Renvoie la partie dcimale d'un rel Spare la mantisse et l'exposant de X 22

Log2, fonction LogN, fonction Max, fonction Min, fonction Pi, fonction Poly, fonction

Calcule le logarithme en base 2 Calcule le logarithme en base N Renvoie la plus leve des valeurs parmi deux valeurs numriques Renvoie la plus petite de deux valeurs numriques Renvoie 3.1415926535897932385 value une polynomiale uniforme D. Mailliet

MIAGE 2me anne

Int, fonction IntPower, fonction Ldexp, fonction Ln, fonction LnXP1, fonction Log10, fonction 4.

Renvoie la partie entire d'un nombre rel Calcule la puissance entire d'une valeur de base Calcule X * (2**P) Renvoie le logarithme naturel d'une expression relle Renvoie le logarithme naturel de (X+1) Calcule le logarithme en base 10

d'une variable la valeur X lve Base n'importe quelle puissance Round, fonction Renvoie la valeur de X arrondi au plus proche entier Sqr, fonction Renvoie le carr d'un nombre Sqrt, fonction Renvoie la racine carre de X Trunc, fonction Tronque un rel en entier. Power, fonction

Routines de nombres alatoires Gnre des nombres alatoires avec une distribution gaussienne RandSeed stocke la matrice du gnrateur de nombres alatoires Gnre des nombres alatoires dans une tendue spcifie Initialise le gnrateur interne de nombre alatoire avec une valeur alatoire. 7 x 10-2 et 12.25e+6 et 12.25e6 signifient 12.25 x 106 .

RandG, fonction RandSeed, variable Random, fonction Randomize, procdure 5. 7E-2 Exemples signifie

C.
1.

Les types chanes


Dfinition

Une chane reprsente une suite de caractres. Le Pascal Objet gre les types de chane prdfinis suivants. Type Longueur maximum Mmoire ncessaire Utilisation ShortString 255 caractres de 2 256 octets Compatibilit ascendante AnsiString ~2^31 caractres de 4 octets 2Go Caractre sur 8 bits (ANSI) WideString ~2^30 caractres de 4 octets 2Go Caractres Unicode; Le mot rserv string fonctionne comme un identificateur de type gnrique. Dans l'tat par dfaut {$H+}, le compilateur interprte string (quand il apparat sans tre suivi d'un crochet ouvrant) comme dsignant AnsiString. Utilisez la directive {$H} pour que string soit interprt comme dsignant ShortString. 2. Routines de gestion des chanes Standardise les caractres de fin de ligne en paires CR/LF Compare deux chanes bases sur le pilote de langue de Windows (les diffrences de majuscules/minuscules sont dtectes) Compare deux chanes bases sur le pilote de langue de Windows (les diffrences de majuscules/minuscules ne sont pas dtectes) Convertit une chane guillemete en une chane non guillemete Renvoie une chane, qui est une copie de la chane donne convertie en minuscules Trouve la position d'une sous-chane dans une chane Renvoie la version guillemete d'une chane Compare deux chanes bases sur le pilote de langue de Windows (les diffrences de majuscules/minuscules sont dtectes) Compare deux chanes bases sur le pilote de langue de Windows (les diffrences de majuscules/minuscules ne sont pas dtectes) Convertit une chane en majuscules Compare des chanes en tenant compte de la distinction minuscules/majuscules Compare des chanes par valeur scalaire sans tenir compte de la distinction minuscules/majuscules Concatne deux chanes ou plus Renvoie une sous-chane d'une chane ou un segment de tableau dynamique Supprime une sous-chane d'une chane s Insre une sous-chane dans une chane commenant au point spcifi Indique si un caractre spcifi dans une chane correspond un ensemble de dlimiteurs Renvoie l'index d'octet dans S du dernier caractre identique au caractre spcifi par la chane AnsiString Delimiters Renvoie le nombre de caractres dans une chane ou d'lments dans un tableau D. Mailliet 23 AdjustLineBreaks, fonction AnsiCompareStr, fonction AnsiCompareText, fonction AnsiExtractQuotedStr, fonction AnsiLowerCase, fonction AnsiPos, fonction AnsiQuotedStr, fonction AnsiSameStr, fonction AnsiSameText, fonction AnsiUpperCase, fonction CompareStr, fonction CompareText, fonction Concat, fonction Copy, fonction Delete, procdure Insert, procdure IsDelimiter, fonction LastDelimiter, fonction Length, fonction
Delphi et Kilix

MIAGE 2me anne

LowerCase, fonction NullStr, constante Pos, fonction QuotedStr, fonction SetLength, procdure SetString, procdure Str, procdure StringOfChar, fonction StringReplace, fonction Trim, fonction TrimLeft, fonction TrimRight, fonction UpperCase, fonction Val, procdure WrapText, fonction 3. Oprateurs de chane

Convertit une chane ASCII en minuscules Dclare un pointeur sur EmptyStr Renvoie la valeur d'index du premier caractre dans une sous-chane spcifie qui se trouve dans une chane Renvoie la version guillemete d'une chane Dfinit la taille d'une variable chane ou tableau dynamique Dfinit le contenu et la taille d'une chane Formate une chane et la renvoie dans une variable Renvoie une chane avec le nombre de caractres spcifi Renvoie une chane AnsiString dans laquelle des occurrences d'une sous-chane sont remplaces par une autre sous-chane Supprime les caractres de contrle et les espaces se trouvant en dbut et en fin de chane Supprime les caractres de contrle et les espaces se trouvant en dbut de chane Supprime les caractres de contrle et les espaces se trouvant en fin de chane Revoie une copie d'une chane en majuscules Convertit une chane en sa reprsentation numrique Dcompose une chane en plusieurs lignes quand sa longueur se rapproche d'une taille donne.

Oprateur Opration Types d'oprande Type du rsultat Exemple + concatnation chane, chane compacte, caractre chane S + '. ' Les rgles suivantes s'appliquent la concatnation de chane : Les oprateurs relationnels =, <>, <, >, <= et >= acceptent tous des oprandes chane (voir Oprateurs relationnels). L'oprateur + concatne deux chanes. Les oprandes pour l'oprateur + peuvent tre des chanes, des chanes compactes (des tableaux compacts de type Char) ou des caractres. Cependant, si un oprande est de type WideChar, l'autre oprande doit tre une chane longue. Le rsultat d'une opration + est compatible avec tout type de chane. Cependant, si les oprandes sont tous deux des chanes courtes ou des caractres, et si leur longueur cumule est suprieure 255, le rsultat est tronqu aux 255 premiers caractres. 4. Les chanes courtes a) Dfinition

Une variable de type chane ShortString est une squence de caractres de longueur variable au cours de l'excution et une taille prdfinie entre 1et 255. On peut prciser la longueur maxi entre crochets. b) Exemples Type Tch32 = string [32]; // ou Tch32 = ShortString[32] Var ch : Tch32 ; // Rserve 33 octets : ch[i] fait rfrence au i m e caractre de la chane. ch[0] fait rfrence sa longueur. ... ch:=#98#111#110#106o#117#114; // reprsente la chane bonjour ch := cest une chane // Lorsquune chane comporte une apostrophe, on doit la doubler. 5. Les chanes longues et tendues a) Dfinition

Les types AnsiString (caractres Ansi 8 bits) et WideString (caractres Unicodes 16 bits) ou string sans crochets sont des chanes alloues dynamiquement. (Ce sont en ralit des pointeurs.) La gestion de la mmoire est entirement automatique. A priori les diffrents types de chanes ne semblent pas prsenter de grosses diffrences : cest illusoire, nous y reviendrons lors de ltude du type fichier. b) Exemples Var Ch : string ; // ou Ch : AnsiString; ...
Delphi et Kilix

24

D. Mailliet

MIAGE 2me anne

Ch:=#98#111#110#106o#117#114; // reprsente la chane bonjour Ch := cest une chane // Lorsquune chane comporte une apostrophe, on doit la doubler. 6. Les chanes AZT a) Dfinition

Pour des raisons de compatibilit avec dautres langages (tel le C et C++), une chane zro terminal est un tableau de caractres d'indice de base zro et termin par NULL (#0). Comme le tableau n'a pas d'indicateur de longueur, le premier caractre NULL indique la fin de la chane. Le type Pchar est en ralit un pointeur Pour plus de prcision voir laide Delphi et le type pointeur ci-aprs. b) c) StrAlloc StrBufSize StrCat StrComp StrCopy StrDispose StrECopy StrEnd StrFmt StrIComp StrLCat StrLComp StrLCopy StrLen StrLFmt StrLIComp StrLower StrMove StrNew StrPCopy StrPLCopy StrPos StrRScan StrScan StrUpper Oprateurs Procdure et fonctions

Alloue sur le tas un tampon de caractres d'une taille donne. Renvoie la taille du tampon de caractres allou sur le tas en utilisant StrAlloc ou StrNew. Concatne deux chanes. Compare deux chanes. Copie une chane. Libre un tampon de caractres allou en utilisant StrAlloc ou StrNew. Copie une chane et renvoie un pointeur sur la fin de la chane. Renvoie un pointeur sur la fin de la chane. Formate une ou plusieurs valeurs dans une chane. Compare deux chanes sans tenir compte des diffrences majuscules/minuscules. Concatne deux chanes avec une longueur maximum donne pour la chane rsultante. Compare deux chanes sur une longueur maximum donne. Copie une chane jusqu' une longueur maximum donne. Renvoie la longueur d'une chane. Formate une ou plusieurs valeurs dans une chane avec une longueur maximum donne. Compare deux chanes sur une longueur maximum donne sans tenir compte des diffrences majuscules/minuscules. Convertit une chane en minuscules. Dplace un bloc de caractres d'une chane dans une autre. Alloue une chane sur le tas. Copie une chane Pascal dans une chane zro terminal. Copie une chane Pascal dans une chane zro terminal avec une longueur maximum donne. Renvoie un pointeur sur la premire occurrence d'une sous-chane donne dans une chane. Renvoie un pointeur sur la dernire occurrence d'un caractre donn dans une chane. Renvoie un pointeur sur la premire occurrence d'un caractre donn dans une chane. Convertit une chane en majuscules. d) Exemples

Var Ch : Pchar; ... Ch := bonjour; // L encore la gestion de mmoire est transparente pour le programmeur.

D.

Chanes de format

Les chanes de format transmises aux routines de dfinition de format de chanes contiennent deux types d'objets : les caractres simples et les spcificateurs de format. Les caractres simples sont copis tels quels dans la chane rsultante. Les spcificateurs de format rcuprent les arguments dans la liste des arguments en y appliquant un format. Les spcificateurs de format ont la forme suivante : "%" [index ":"] ["-"] [width] ["." prec] type Un spcificateur de format commence par un caractre %. Ce qui suit % est, dans l'ordre : Le spcificateur facultatif d'indice de l'argument, [index ":"]
Delphi et Kilix

25

D. Mailliet

MIAGE 2me anne

L'indicateur facultatif d'alignement gauche, ["-"] Le spcificateur facultatif de taille, [width] Le spcificateur facultatif de prcision, ["." prec] Le caractre de type de conversion, type Le tableau suivant rsume les valeurs possibles de type : d Dcimal. L'argument doit tre une valeur entire. La valeur est convertie en chane de chiffres dcimaux. Si la chane de format contient un spcificateur de prcision, la chane rsultante doit contenir au moins le nombre indiqu de chiffres ; si cela n'est pas le cas, des caractres zro de remplissage sont rajouts dans la partie gauche de la chane. u Dcimal sans signe. Comme 'd' mais sans signe en sortie.

e Scientifique. L'argument doit tre une valeur virgule flottante. La valeur est convertie en une chane de la forme "-d.ddd...E+ddd". La chane rsultante dbute par un signe moins si le nombre est ngatif. Un chiffre prcde toujours le sparateur dcimal. Le nombre total de chiffres dans la chane rsultante (y compris celui qui prcde la virgule) est donn par le spcificateur de prcision dans la chane de format. Si celui-ci est omis, une prcision de 15 est prise en compte par dfaut. Le caractre "E" dans la chane rsultante est toujours suivi d'un signe plus ou moins, puis de trois chiffres au moins. f Fixe. L'argument doit tre une valeur virgule flottante. La valeur est convertie en une chane de la forme "ddd.ddd...". La chane rsultante dbute par un signe moins si le nombre est ngatif.Le nombre de chiffres aprs la virgule est fourni par le spcificateur de prcision de la chane de format ; 2 dcimales sont prises en compte par dfaut si le spcificateur de prcision est omis. g Gnral L'argument doit tre une valeur virgule flottante. La valeur est convertie en une chane la plus courte possible en utilisant le format fixe ou scientifique. Le nombre de chiffres significatifs dans la chane rsultante est fourni par le spcificateur de prcision dans la chane de format : une prcision par dfaut de 15 est prise en compte si le spcificateur de prcision est omis. Les caractres zro sont supprims de la fin de la chane rsultante et le sparateur dcimal n'apparat que s'il est ncessaire. La chane rsultante utilise le format fixe si le nombre de chiffres gauche de la virgule est infrieur ou gal la prcision indique et si la valeur est suprieure ou gale 0,00001. Sinon, la chane rsultante fait appel au format scientifique. n Numrique L'argument doit tre une valeur virgule flottante. La valeur est convertie en une chane de la forme "-d,ddd,ddd.ddd...". Le format "n" correspond au format "f", sauf que la chane rsultante contient le sparateur des milliers. m Montaire. L'argument doit tre une valeur virgule flottante. La valeur est convertie en une chane reprsentant un montant montaire. La conversion est contrle par les variables globales CurrencyString, CurrencyFormat, NegCurrFormat, ThousandSeparator, DecimalSeparator et CurrencyDecimals. Si la chane de format contient un spcificateur de prcision, il remplace la valeur envoye par la variable globale CurrencyDecimals. p Pointeur. L'argument doit tre une valeur de type pointeur. La valeur est convertie en une chane de 8 caractres qui reprsente des valeurs de pointeur en hexadcimal. s Chane. L'argument doit tre un caractre, une chane ou une valeur PChar. La chane ou le caractre est insr la place du spcificateur de format. Le spcificateur de prcision, s'il est dfini dans la chane de format, indique la taille maximale de la chane rsultante. Si l'argument est une chane de taille suprieure, celle-ci est tronque. x Hexadcimal. L'argument doit tre une valeur entire. La valeur est convertie en une chane de chiffres hexadcimaux. Si la chane de format contient un spcificateur de prcis ion, ce dernier spcifie que la chane doit contenir au moins le nombre indiqu de chiffres ; si cela n'est pas le cas, des caractres zro de remplissage sont rajouts dans la partie gauche de la chane. Les caractres de conversion peuvent tre indiqus indiffremment en majuscules ou en minuscules : le rsultat obtenu est le mme. Quel que soit le format flottant, les deux caractres utiliss comme sparateur dcimal et sparateur des milliers sont respectivement dfinis par les variables globales DecimalSeparator et ThousandSeparator. Les spcificateurs d'indice, de taille et de prcision peuvent tre directement spcifis en utilisant des chanes contenant des chiffres dcimaux (par exemple "%10d") ou indirectement, en utilisant le caractre astrisque (par exemple "%*.*f").
Delphi et Kilix

26

D. Mailliet

MIAGE 2me anne

Lorsque vous utilisez l'astrisque, l'argument suivant dans la liste (qui doit tre obligatoirement une valeur entire) devient la valeur effectivement utilise. Par exemple : Format('%*.*f', [8, 2, 123.456]) quivaut Format('%8.2f', [123.456]). Un spcificateur de taille dfinit la taille minimale du champ lors de la conversion. Si la chane rsultante est de taille infrieure la taille minimale dfinie, elle est comble par des espaces afin d'accrotre la taille du champ. Par dfaut, le rsultat est align droite en faisant prcder la valeur d'espaces, mais si le spcificateur de format contient un indicateur d'alignement gauche (un caractre "-" prcdant le spcificateur de taille), le rsultat est align gauche par l'ajout d'espaces aprs la valeur. Un spcificateur d'indice dfinit la valeur courante de l'indice de la liste. L'indice du premier argument dans la liste est 0. A l'aide du spcificateur d'indice, vous pouvez formater un mme argument plusieurs fois de suite. Par exemple "Format('%d %d %0:d %1:d', [10, 20])" produit la chane '10 20 10 20'. Remarque : La dfinition du spcificateur d'indice affecte les formatages ultrieurs. Par exemple, Format('%d %d %d %0:d %d', [1, 2, 3, 4]) renvoie '1 2 3 1 2', et pas '1 2 3 1 4'. Pour obtenir ce dernier rsultat, vous devez utiliser Format('%d %d %d %0:d %3:d', [1, 2, 3, 4]).

E.
1.

Le type pointeur
Dfinition

Un pointeur est une variable qui dsigne une adresse mmoire. Quand un pointeur contient l'adresse d'une autre variable, on dit qu'il pointe sur l'emplacement en mmoire de cette variable ou sur les donnes qui y sont stockes. Dans le cas d'un tableau ou d'un type structur, un pointeur contient l'adresse du premier lment de la structure. Les pointeurs sont typs afin d'indiquer le type de donnes stockes l'adresse qu'ils contiennent. Le type gnral Pointer peut reprsenter un pointeur sur tous les types de donnes alors que d'autres pointeurs, plus spcialiss, ne pointent que sur des types de donnes spcifiques. Les pointeurs occupent quatre octets en mmoire. Le mot rserv nil est une constante spciale qui peut tre affecte tout pointeur. Quand la valeur nil est affecte un pointeur, le pointeur ne dsigne plus rien. Supposons que lon ait dclar une variable b de type byte (var b : byte;)et que 5 lui soit affect (b:=5;) : Le systme trouve une place en mmoire de 1 octet pour stocker cette valeur supposons que ladresse trouve soit 135. Voici une reprsentation partielle de la mmoire: Adresse ... 134 135 136 ... Contenu ... ... 5 ... ... b

supposons dautre part que lon ait aussi dclar un pointeur doctet (var p : ^byte) laffectation: p := @b ; // p vaut (pour notre exemple) 135 et p^ vaut 5 cest dire la valeur de b. 2. Oprateurs

Oprateur + ^ = <>
Delphi et Kilix

Opration addition de pointeurs soustraction de pointeurs drfrencement de pointeur galit ingalit

Types d'oprande pChar, entier pChar, entier pointeur pointeur pointeur 27

Type du rsultat pChar pChar, entier type de base du pointeur Boolean Boolean

Exemple P+I P-Q P^ P=Q P <> Q D. Mailliet

MIAGE 2me anne

L'oprateur ^ drfrence un pointeur. Son oprande peut tre un pointeur de type quelconque sauf un pointeur gnrique (Pointer) qui doit tre transtyp avant d'tre drfrenc. Le symbole ^ a deux fonctions, toutes deux illustres dans l'exemple plus bas. Quand il apparat avant un identificateur de type : ^nomType il dsigne un type qui reprsente des pointeurs sur des variables de type nomType. Quand il apparat aprs une variable pointeur : pointeur^ P = Q vaut True si P et Q pointent sur la mme adresse ; sinon, P <> Q est True. L'oprateur @ renvoie l'adresse d'une variable, d'une fonction, d'une procdure ou d'une mthode ; @ construit un pointeur sur son oprande. Pour davantage d'informations sur les pointeurs, voir Pointeurs et types de pointeurs. 3. routines d'adresses et de pointeurs Renvoie un pointeur sur un objet spcifique Convertit l'adresse spcifie en pointeur

Addr, fonction. Ptr, fonction 4.

Routines d'allocation dynamique Libre la mmoire alloue une variable dynamique Dsinitialise une variable alloue dynamiquement Libre une variable dynamique d'une taille donne Cre une variable dynamique et un pointeur sur l'adresse du bloc Initialise une variable alloue dynamiquement Cre une nouvelle variable dynamique et initialise P de telle faon qu'il pointe dessus.

Dispose, procdure Finalize, procdure FreeMem, procdure GetMem, procdure Initialize, procdure New, procdure 5. Exemples

Var pb:^byte; // un pointeur doctet (8 bits) pw:^word; // un pointeur de mots(16 bits) p:pointer; // un pointeur non typ j:word; // un mot (16 bits) ... j:=$10FF; // j reoit la valeur 4351 pw:=@j; // pw pointe sur ladresse o est stock j { pb:=pw; // provoque une erreur pour mlange de types} pb:=@j; // alors que quici : pas de problme p:=pw; // pas plus que l pb:=p; // ni l writeln(j,' = ',pw^); // pw est ladresse de j, pw^ reprsente la valeur situe cette adresse soit j ! writeln(pb^); // Affiche 255 ($FF) les descendants du 8086 stockent les poids faibles avant les poids forts! pb:=pointer(longint(pb)+1); // Il est ncessaire de transtyper, Delphi accepte pb := pb+1 uniquement pour les pChar (voir plus loin) writeln(pb^); // affichage des poids faibles : 16 ($10) essayer writeln((pb+1)^); Autre exemple : var p : ^byte ; // rserve 4 octets pour stocker la valeur dune adresse; Mais PAS le contenu de ce que lon veut stocker ... new(p); // Rservation dun emplacement mmoire capable de mmoriser un byte (soit 1 octet) p^ := 17; // stockage de la valeur 17 ladresse trouve ci-dessus. Il aura donc fallu 5 octets pour mmoriser la valeur 17 : 4 pour ladresse mmoire et 1 pour la valeur. Alors que : var b : byte;
Delphi et Kilix

28

D. Mailliet

MIAGE 2me anne

... b:=17; ne require quun octet . Remarque @b (ou addr(b) ) est cod sur 4 octets.

F.

Autres pointeurs

Le type pointer est une adresse mmoire. ^montype est un pointeur sur un type montype Il existe aussi des pointeurs implicites tels que Pchar ou ansiString vus plus haut ou encore des tableaux dynamiques (que lon verra plus bas) quil ne faut pas drfrencer (^ ). Il existe aussi bien dautres pointeurs . Pour plus dinformations voir laide Delphi.

G.
1.

Le type Variant
Dfinition

Il est parfois ncessaire de manipuler des donnes dont le type change ou est inconnu lors de la compilation. Dans ce cas, une des solutions consiste utiliser des variables et des paramtres de type Variant qui reprsentent des valeurs dont le type peut changer l'excution. Les variants offrent une plus grande flexibilit que les variables standard mais consomment davantage de mmoire. De plus les oprations o les variants sont utiliss sont plus lentes que celles portant sur des types associs statiquement. Enfin, les oprations illgales portant sur des variants provoquent frquemment des erreurs d'excution, alors que les mmes erreurs avec des variables normales sont dtectes la compilation. lexception du type Int64, les variants peuvent tout contenir sauf les types structurs et les pointeurs. Un variant occupe 16 octets de mmoire, il est constitu d'un code de type et d'une valeur ou d'un pointeur sur une valeur ayant le type spcifi par le code. Tous les variants sont initialiss la cration avec une valeur spciale Unassigned. La valeur spciale Null indique des donnes inconnues ou manquantes. La fonction standard VarType renvoie le code de type d'un variant. 2. Oprateurs

ceux du type de base 3. Routines de gestion des variants Null reprsente le variant null Utilise pour indiquer qu'une variable Variant n'a pas encore t affecte d'une valeur Cre un tableau de variants Renvoie le nombre de dimensions d'un tableau de variants Renvoie la limite suprieure de la dimension donne du tableau de variants Ferme le tableau de variants et renvoie un pointeur sur les donnes Renvoie la limite infrieure de la dimension donne du tableau de variants Cre et remplit un tableau de variants unidimensionnel Redimensionne un tableau de variants Renvoie une rfrence au tableau de variants spcifi Dverrouille un tableau de variants Convertit un variant et le met dans le type spcifi Convertit un variant dans le type spcifi et stocke le rsultat dans une variable Efface le variant spcifi afin qu'il ne soit pas affect Copie un Variant Renvoie un variant contenant la date-heure spcifie Indique si le Variant spcifi est un tableau Indique si le Variant spcifi est Unassigned Indique si le Variant spcifi est Null Convertit le variant spcifi en une valeur TDateTime Convertit un variant en chane Renvoie le code du type du variant spcifi Renvoie la valeur du type de champ qui correspond le plus prcisment un type Variant.

Null, variable Unassigned, constante VarArrayCreate, fonction VarArrayDimCount, fonction VarArrayHighBound, fonction VarArrayLock, fonction VarArrayLowBound, fonction VarArrayOf, fonction VarArrayRedim, procdure VarArrayRef, fonction VarArrayUnlock, procdure VarAsType, fonction VarCast, procdure VarClear, procdure VarCopy, procdure VarFromDateTime, fonction VarIsArray, fonction VarIsEmpty, fonction VarIsNull, fonction VarToDateTime, fonction VarToStr, fonction VarType, fonction VarTypeToDataType, fonction

Delphi et Kilix

29

D. Mailliet

MIAGE 2me anne

H.
1.

Les types Ensemble


Dfinition

Un ensemble est une collection de valeurs ayant le mme type scalaire. Les valeurs n'ont pas d'ordre intrinsque, une mme valeur ne peut donc pas apparatre deux fois dans un ensemble. Les valeurs possibles du type ensemble sont tous les sous-ensembles du type de base, y compris l'ensemble vide. Le type de base ne peut avoir plus de 256 valeurs possibles et leur rang doit tre compris entre 0 et 255. Toute construction de la forme : set of <typeBase> o <typeBase> est un type scalaire appropri, identifie un type ensemble. En raison des limitations de taille des types de base, les types ensemble sont gnralement dfinis avec des intervalles. 2. Oprateurs Opration union diffrence intersection sous-ensemble sur-ensemble galit diffrence inclusion Types d'oprande ensemble ensemble ensemble ensemble ensemble ensemble ensemble scalaire, ensemble Type du rsultat ensemble ensemble ensemble Boolean Boolean Boolean Boolean Boolean Exemple ens1 + ens2 S-T S*T Q <= MonEns S1 >= S2 S2 = MonEns MonEns <> S1 A in ens1

Oprateur + * <= >= = <> in 3.

Exemples

Type tlettres='a'..'z'; Elettres= set of Tlettres ; var lettres,voyelles ,consonnes, vide,v2: Elettres; begin voyelles := ['a','e','i','o','u','y']; v2:=['u','o','u','i','a','e']; // Le u est rpt 2 fois mais les doublons seront limins et il manque le y par rapport voyelles lettres := ['a'..'z']; consonnes := lettres - voyelles; vide := consonnes * voyelles; // les 2 ensembles sont disjoints : leur intersection est vide writeln('f' in voyelles); // FALSE { writeln(voyelles); provoque une erreur } writeln(vide = [ ]); // TRUE { writeln(v2 in voyelles); // provoque une erreur } writeln(v2+['y']=voyelles); // TRUE

I.
1.

Les tableaux
Dfinition

Un tableau reprsente une collection indice d'lments de mme type (appel le type de base). Comme chaque lment a un indice unique, les tableaux ( la diffrence des ensembles) peuvent, sans ambiguts, contenir plusieurs fois la mme valeur. Il est possible d'allouer des tableaux de manire statique ou dynamique. 2. Tableaux statiques a) Dfinition

Les tableaux statiques sont dsigns par des constructions de la forme : array[typeIndex1, ..., typeIndexn] of typeBase o chaque typeIndex est un type scalaire dont l'tendue de doit pas dpasser 2 Go. Comme les typeIndex indicent le tableau, le nombre d'lments que le tableau peut contenir est limit par le produit de la taille des typeIndex. Pratiquement, les typeIndex sont en gnral des intervalles d'entiers.
Delphi et Kilix

30

D. Mailliet

MIAGE 2me anne

Dans le cas le plus simple d'un tableau une dimension, il n'y a qu'un seul typeIndex.

b)

Exemples de tableaux 1 dimension

t3[TRUE]:= 'salut'; Type Tlettres='a'..'z'; t4[o]:='R'; Ttbl = array [boolean] of string [6]; Exemple 2 Tvoy=(a,e,o,i,u,y); // na rien voir avec Type Tindice = (x,y); // Type numr pour viter lensemble des voyelles ci-dessus var les apostrophes voir t2 ci-dessus t1: array [byte] of Tlettres; Tpoint = array [x..y] of real; t2 : array [tlettres] of byte; Var t3 : tTbl; P1: Tpoint; t4 : array [Tvoy] of char; ... ... P1[x] := 5.9; t1[19]:='e'; P1[y] := 3; t2['k']:= 11; c) Exemples de tableaux plusieurs dimensions Type Tvecteur = array [1..3] of real; Tmat1 = array [1..4] of Tvecteur; Tmat2 = array [1..4] of array [1..3] of real; Tmat3 = array [1..4,1..3] of real; var m1: Tmat1; m2: Tmat2; m3: Tmat3; v : Tvecteur; m4 :array [1..4,1..3] of real; ... 3. Tableaux dynamiques a) Dfinition m1[2] := v; { m2[1]:= v; m3[1]:= v; // Provoquent une erreur } { m2 := m1; m3 := m1; m4 := m1; m4 := m3; // Provoquent une erreur } m1[3][1] :=7.2 m1[3,2] := 5.1; m2[3][1] :=7.2; m2[3,2] := 5.1; m3[3][1] :=7.2; m3[3,2] := 5.1;

Les tableaux dynamiques n'ont pas de taille ou de longueur fixe. La mmoire d'un tableau dynamique est ralloue quand vous affectez une valeur au tableau ou quand vous le transmettez la procdure SetLength. Les types de tableau dynamique sont dsigns par des constructions de la forme : array of <typeBase> Si X et Y sont des variables du mme type de tableau dynamique, X := Y fait pointer X sur le mme tableau que Y. (Il n'est pas ncessaire d'allouer de la mmoire X avant d'effectuer cette opration.) A la diffrence des chanes ou des tableaux statiques, les tableaux dynamiques ne sont pas copis quand ils vont tre modifis. Donc, b) Routines copy (Fonctions) high(Fonctions) Fonctions et procdures

Tronque une partie dun tableau dynamique renvoie l'indice le plus lev du tableau (c'est--dire Length 1) . Dans le cas d'un tableau de longueur nulle, High renvoie 1 (avec cette anomalie que High < Low). length (Fonctions) renvoie le nombre d'lments du tableau, low(Fonctions) renvoie 0 setLength (procdure) Rserve de la mmoire c) Exemple 1 t1 : array of byte;
Delphi et Kilix

Exemples

31

D. Mailliet

MIAGE 2me anne

t2 : array of array of real; ... setLength(t1,3); setLength(t2,4,3); t1[2}:=17; t2[3,1] := 3.6; Exemple2 var t : array of array of Byte; ... setLength(t,4); setlength(t[0],1); setlength(t[1],2); setlength(t[2],3); setlength(t[3],4); t[0,0] := 1; t[1,0] := 1; t[1,1] := 1; t[2,0] := 1; t[2,1] := 2; t[2,2] := 1; t[3,0] := 1; // Et ainsi de suite. Ceci pourrait constituer le dbut du triangle de pascal. Exemple3 Aprs l'excution du code suivant : var A, B: array of Integer; begin SetLength(A, 1); A[0] := 1; B := A; B[0] := 2; end; La valeur de A[0] est 2. Si A et B taient des tableaux statiques, A[0] vaudrait toujours 1. L'affectation d'un indice d'un tableau dynamique (par exemple, MonTableauFlexible[2] := 7) ne ralloue pas le tableau. Les indices hors des bornes ne sont pas dtects la compilation.

J.

Le type record

Le mot enregistrement est souvent employ et peut prter confusion : Il ne sagit pas denregistrer quoi que ce soit sur disque 1. Dfinition

Un record ou enregistrement (appel aussi structure ou fiches dans certains langages) reprsente un ensemble de donnes htrognes. Chaque lment est appel un champ ; la dclaration d'un type enregistrement spcifie le nom et le type de chaque champ. Une dclaration dune variable de type enregistrement a la syntaxe suivante : Var nomVarEnregistrement = record Champ1: type1; ... Champn: typen; end o nomVarEnregistrement est un identificateur valide, o chaque type dsigne un type, et chaque listeChamp est un identificateur valide ou une liste d'identificateurs dlimite par des virgules. Le point-virgule final est facultatif.
Delphi et Kilix

32

D. Mailliet

MIAGE 2me anne

Pour accder au champ chanpi de lenregistrement , on utilise la notation des identificateurs qualifis:( voir page 16) nomVarEnregistrement.champi 2. Exemples Exemple1: type TDate = record Jour: 1..31; Mois: (Jan, Fev, Mar, Avr, Mai, Jun, Juil, Aou, Sep, Oct, Nov, Dec); Annee: Word; end; Var D1,D2 : Tdate; ... D1.Jour := 10; D1.Mois := Mai; D1.annee := 2002; D2 := D1 Exemple 2 : A comp arer avec lquivalent Tableau ci-dessus. La rgle veut que lon utilise un tableau pour une collection dlments de mme type et des records pour une collection dlments de types diffrents. Nanmoins : Var P2: Record x,y : Real; end; ... P2.x := 5.9; P2.y := 3; Exemple 3 : listes chanes: deb^.svt := p_cour; Type TptListe = ^Tliste; p_cour^.valr := 15; Tliste = record p_cour^.svt := nil ; // inutile ici car un pointeur valr : byte; non allou est automatiquement nil svt : TptListe // Parcours end; p_cour := deb; writeln(p_cour^.valr); var deb,p_cour : TptListe; p_cour := p_cour^.svt; writeln(p_cour^.valr); BEGIN // initialisation // Libration de la mmoire new (p_cour); dispose(deb^.svt); p_cour^.valr := 43; dispose(deb); deb := p_cour; END. new (p_cour); Ce programme cre un chanage de ce style : deb 43 15 nil dispose(deb^.svt^.svt) permettrait de librer un 3me chanon qui ici na pas t cr (il y a nil sa place) . Dans cet exemple, cette instruction provoquerait une erreur dexcution (et non de compilation car elle est correcte)

K.

Enregistrements partie variable

Voir laide de Delphi

Delphi et Kilix

33

D. Mailliet

MIAGE 2me anne

L.
1.

Le type fichier
Dfinition

Un fichier est un ensemble ordonn d'lments du mme type. Les routines standard d'Entres/Sorties utilisent les types prdfinis TextFile et Text qui reprsentent un fichier contenant des caractres organiss en lignes. Pour davantage d'informations sur les entres et sorties de fichier, voir Routines standard et d'E/S. Pour dclarer un type fichier, utilisez la syntaxe : type <nomTypeFichier> = file of <type> o nom<TypeFichier> est un identificateur valide et type un type de taille fixe. Les types pointeur, implicites ou explicites ne sont pas permis. Un fichier ne peut donc pas contenir des tableaux dynamiques, des chanes longues, des classes, des objets, des pointeurs, des variants, d'autres fichiers ou des types structurs en contenant. 2. routines d'entres/sorties Prpare un fichier exis tant pour l'ajout de texte Lit un ou plusieurs enregistrements d'un fichier ouvert et les place dans une variable crit un ou plusieurs enregistrements d'une variable mmoire dans un fichier ouvert La fonction Eof dtermine si la position en cours du pointeur se trouve en fin de fichier Dtermine le mode d'accs utiliser lorsque des fichiers typs ou non typs sont ouverts avec la classe Reset Renvoie la position en cours dans un fichier Renvoie la taille d'un fichier (en octets) ou le nombre d'enregistrements dans le fichier Renvoie l'tat de la dernire opration d'E/S Spcifie un fichier en lecture seule associe un priphrique d'entre standard du systme d'exploitation Cre un nouveau rpertoire Spcifie un fichier en criture seulement associ une sortie standard, gnralement l'affichage Renomme un fichier externe Ouvre un fichier existant Cre puis ouvre un nouveau fichier Supprime un sous-rpertoire vide Dplace la position en cours dans un fichier vers le composant spcifi Efface tous les enregistrements situs aprs la position en cours dans le fichier crit dans un fichier typ. Affecte une variable fichier texte l'imprimante Eoln dtermine si la position en cours du pointeur se trouve en fin de ligne d'un fichier texte Supprime un fichier externe Efface le tampon associ un fichier texte ouvert en criture Read lit les donnes d'un fichier Lit une ligne de texte dans un fichier Renvoie l'tat de fin d'un fichier Renvoie l'tat de fin de ligne d'un fichier Affecte un tampon d'E/S un fichier texte crit dans un fichier texte Place une marque de fin de ligne dans un fichier texte. Associe le nom d'un fichier externe une variable fichier Change le rpertoire en cours Ferme l'association entre une variable fichier et un fichier disque externe (Delphi) D. Mailliet 34

Append, procdure BlockRead, procdure BlockWrite, procdure Eof, fonction FileMode, variable FilePos, fonction FileSize, fonction IOResult, fonction Input, variable MkDir, procdure Output, variable Rename, procdure Reset, procdure Rewrite, procdure RmDir, procdure Seek, procdure Truncate, procdure Write, procdure (for typed files) 3. Routines de fichiers texte AssignPrn, procdure Eoln, fonction Erase, procdure Flush, procdure Read, procdure Readln, procdure SeekEof, fonction SeekEoln, fonction SetTextBuf, procdure Write, procdure (for text files) Writeln, procdure 4. AssignFile, procdure ChDir, procdure CloseFile, procdure
Delphi et Kilix

Routines de gestion de fichiers

MIAGE 2me anne

Constantes en mode ouverture de fichier Constantes mode de fichier CreateDir, fonction DeleteFile, fonction DiskFree, fonction DiskSize, fonction FileClose, procdure FileDateToDateTime, fonction FileExists, fonction FileGetAttr, fonction FileGetDate, fonction FileOpen, fonction FileRead, fonction FileSearch, fonction FileSeek, fonction FileSetAttr, fonction FileSetDate, fonction FileWrite, fonction FindClose, procdure FindFirst, fonction FindNext, fonction GetCurrentDir, fonction GetDir, procdure RemoveDir, fonction RenameFile, fonction SetCurrentDir, fonction 5. Exemples

Les constantes de mode d'ouverture de fichier sont utilises pour contrler le mode d'accs au fichier ou au flux Les constantes mode de fichier sont utilises pour ouvrir et fermer des fichiers disque Cre un nouveau rpertoire Supprime un fichier du disque Renvoie le nombre d'octets disponibles sur le lecteur spcifi Renvoie la taille en octets du disque spcifi Ferme le fichier spcifi Convertit une valeur date ou heure DOS en valeur au format TDateTime Teste si le fichier spcifi existe. Renvoie les attributs du fichier FileName Renvoie la date et l'heure DOS du fichier spcifi Ouvre un fichier en utilisant le mode d'accs spcifi Lit le nombre d'octets spcifi dans un fichier Recherche un fichier dans le chemin DOS spcifi Positionne le pointeur d'un fichier pralablement ouvert Dfinit les attributs du fichier spcifi Dfinit la marque horaire du fichier DOS spcifi Ecrit le contenu du tampon l'emplacement en cours dans un fichier Libre la mmoire alloue par FindFirst Cherche la premire occurrence d'un fichier avec un ensemble d'attributs prcis dans un rpertoire spcifi. Renvoie l'entre suivante correspondant au nom et aux attributs spcifis dans un prcdent appel FindFirst Renvoie le nom du rpertoire en cours Renvoie le rpertoire en cours sur le lecteur spcifi Efface un rpertoire vide existant Renomme un fichier Dfinit le rpertoire en cours.

Const Max=100; type TDonnees=record Nom, Prenom : string [50]; // ne pas utiliser des string, ansiString ou Pchar !! adresse: string [150]; cdPostl:integer; end; TBase= record item:Array [1..Max] of TDonnees; nbitem :integer; end;

var fic : file of tBase; ATTENTION: Il serait trs tentant dutiliser: type TDonnees=record Nom,Prenom, adresse:string ; cdPostl:integer; end; la place de la dclaration ci-dessus. Cela viterait de tronquer les chanes ou de les surdimensionn (pour viter un encombrement inutile de la mmoire). Il ny aurait aucune diffrence de comportement (apparent) pour tout ce qui est stockage des donnes en mmoire. Le problme apparatrait lors de linstruction: write (fic,montb);
Delphi et Kilix

nomtb : tbase ... // Pour enregistrer la base de donnes sur disque assignfile(fic,'toto.tab'); rewrite(fic); write(fic,montb); closefile(fic); ... // Pour rcuprer la base de donnes du disque assignfile(fic,'toto.tab'); reset(fic); read(fic,montb); closefile(fic);

35

D. Mailliet

MIAGE 2me anne

en effet, on nenregistrerait pas les valeurs des Nom,Prenom, adresse mais des pointeurs rfrenant les adresses de ces valeurs. Ce qui naurait aucun intrt, puisque la cration est dynamique et quune autre excution sur le mme ordinateur ne donnerait pas les mmes adresses pour ces valeurs. Ne parlons pas dune excution sur une autre machine! Et le compilateur sen rend compte (et cest heureux) et il le signale par une erreur la compilation.

M.
1.

Les types procdure et fonction


Dfinition

Quand une variable procdurale se trouve dans la partie gauche d'une instruction d'affectation, le compilateur attend galement une valeur procdurale droite. L'affectation fait de la variable place gauche un pointeur sur la fonction ou la procdure indique droite de l'affectation. Nanmoins, dans d'autres contextes, l'utilisation d'une variable procdurale produit un appel de la procdure ou de la fonction rfrence. Vous pouvez mme utiliser une variable procdurale pour transmettre des paramtres. Nous aurons loccasion dy revenir aprs avoir dfini les procdures et fonctions 2. Exemple var F: function (X: Integer): Integer;

N.
1.

Autres routines
routines de gestionnaire de mmoire Alloue un bloc mmoire et initialise chaque octet zro Reprsente la taille totale des blocs de mmoire allous dans une application Reprsente la taille totale des blocs de mmoire allous Renvoie l'tat actuel du gestionnaire de mmoire Renvoie les points d'entre du gestionnaire de mmoire install Indicateurs spcifiant comment le gestionnaire de mmoire obtient la mmoire depuis le systme d'exploitation Indique si le gestionnaire de mmoire a t surcharg en utilisant la procdure SetMemoryManager Ralloue une variable dynamique Dfinit les points d'entre du gestionnaire de mmoire Libre la mmoire sur laquelle pointe le pointeur spcifi Alloue un nombre spcifi d'octets et leur renvoie un pointeur Renvoie un pointeur sur le nombre d'octets spcifi, prservant les valeurs pointes par le paramtre Pointer.

AllocMem, fonction AllocMemCount, variable AllocMemSize, variable GetHeapStatus, fonction GetMemoryManager, procdure HeapAllocFlags, variable IsMemoryManagerSet, fonction ReallocMem, procdure SetMemoryManager, procdure SysFreeMem, fonction SysGetMem, fonction SysReallocMem, fonction

2.

routines diverses Teste la validit d'une expression boolenne Teste un pointeur nil (non affect) ou une variable procdurale Gnre un bip standard sur le haut-parleur Renvoie le caractre correspondant une valeur ASCII Compare le contenu de deux collections Effectue une comparaison binaire de deux images mmoire Pointe sur une procdure dclenche par un point d'entre d'une DLL Default 8087 est le mot de contrle par dfaut Remplit une succession d'octets avec la valeur spcifie Renvoie une chane formate l'aide d'un masque d'dition Libre une rfrence d'objet et la remplace par nil Renvoie l'octet de poids fort de X comme valeur non signe Renvoie la plus grande valeur dans l'tendue d'un argument Gnre l'image HTML d'un ensemble de donnes l'aide des proprits et des vnements d'un objet gnrateur de tableau Indique si un caractre particulier est un caractre acclrateur (ou touche de raccourci) l'intrieur d'un menu donn ou d'une autre chane de texte Teste un identificateur Pascal Renvoie l'octet de poids faible de l'argument X Renvoie la valeur la moins leve d'une tendue d'arguments Valeur maximale du type de donnes Integer 36 D. Mailliet

Assert, procdure Assigned, fonction Beep, procdure Chr, fonction CollectionsEqual, fonction CompareMem, fonction DLLProc, variable Default8087CW, variable FillChar, procdure FormatMaskText, fonction FreeAndNil, procdure Hi, fonction High, fonction HtmlTable, fonction IsAccel, fonction IsValidIdent, fonction Lo, fonction Low, fonction MaxInt, constante
Delphi et Kilix

MIAGE 2me anne

MaxLongint, constante Move, procdure Printer, fonction Set8087CW, procdure SizeOf, fonction Slice, fonction UniqueString, procdure UpCase, fonction ValidParentForm, fonction 3.

Valeur maximale du type de donnes Longint Copie des octets de la source vers la destination Renvoie une instance globale d'un TPrinter pour grer l'interaction avec l'imprimante Dfinit la fois le mot de contrle dans l'unit virgule flottante et la variable Default8087CW dclare dans l'unit System renvoie le nombre d'octets occups par une variable ou un type Renvoie une sous-section d'un tableau Vrifie qu'une chane donne a un compteur de rfrence 1 Convertit un caractre en majuscules Renvoie la fiche ou la page de proprits qui contient le contrle spcifi.

Informations au niveau de l'application. Reprsente les informations au niveau de l'application CmdShow est transmise la routine ShowWindow de l'API Windows Indique le handle fourni par Windows pour une application ou bibliothque Indique la classe de la fentre utilise pour l'affichage des conseils d'aide Indique si le module a t compil en tant qu'application console Indique si le module est une DLL Contrle lorsque le dbogueur juste temps est appel numre les localisations pour lesquelles le support est disponible Le handle Instance pour l'excutable principal Le handle Instance pour le thread d'excution principal des modules en cours Contrle si l'application affiche un message d'erreur lorsqu'une erreur d'excution se produit Fournit une gestion centralise des messages Windows adresss des menus droulants Reprsente un priphrique cran Spcifie l'identificateur de la plate-forme Win32.

Application, variable (pour les applications standard) CmdShow, variable HInstance, variable HintWindowClass, variable IsConsole, variable IsLibrary, variable JITEnable, variable Languages, fonction MainInstance, variable MainThreadID, variable NoErrMsg, variable PopupList, variable Screen, variable Win32Platform, variable 4.

Routines de conversion de type Convertit une valeur dcimale code binaire (BCD) en la valeur montaire correspondante Renvoie le TRect d'un rectangle de dimensions donnes Convertit une valeur Comp en une valeur Currency Convertit une valeur en une valeur double Convertit une valeur montaire en la valeur dcimale code binaire (BCD) correspondante CurrencyToComp convertit une valeur Currency en Comp Cre une structure point Windows avec un couple de coordonnes Cre une structure TRect partir de coordonnes fournies Convertit en nombre une chane AnsiString qui reprsente un entier (dcimal ou hexadcimal) Convertit en nombre une chane qui reprsente un entier (dcimal ou hexadcimal) Convertit en nombre une chane qui reprsente un entier (dcimal ou hexadcimal) Convertit en nombre une chane qui reprsente un entier (dcimal ou hexadcimal).

BCDToCurr, fonction Bounds, fonction CompToCurrency, fonction CompToDouble, fonction CurrToBCD, fonction CurrencyToComp, procdure Point, fonction Rect, fonction StrToInt, fonction StrToInt64, fonction StrToInt64Def, fonction StrToIntDef, fonction 5.

Routines de contrle de flux Permet de sortir d'un chemin d'excution sans signaler d'erreur La procdure Break provoque l'interruption d'une boucle for , while ou repeat Continue provoque le passage du contrle de l'excution l'itration suivante dans une instruction for , while ou repeat Quitte la procdure en cours Excute une fin anormale d'un programme Interrompt l'excution et gnre une erreur d'excution.

Abort, procdure Break, procdure Continue, procdure Exit, procdure Halt, procdure RunError, procdure 6.

Utilitaires de ligne de commande CmdLine est un pointeur sur les arguments de la ligne de commande spcifi 37 D. Mailliet

CmdLine, variable
Delphi et Kilix

MIAGE 2me anne

FindCmdLineSwitch, fonction ParamCount, fonction ParamStr, fonction 7. Utilitaires com

quand une application est appele Dtermine si une chane de caractres a t transmise l'application en tant qu'argument de la ligne de commande Renvoie le nombre de paramtres passs dans la ligne de commande Renvoie le paramtre spcifi depuis la ligne de commande.

ClassIDToProgID, fonction CoInitFlags, variable ComClassManager, fonction ComServer, variable CreateClassID, fonction CreateComObject, fonction CreateOleObject, fonction CreateRegKey, procdure CreateRemoteComObject, fonction DeleteRegKey, procdure DllGetClassObject, fonction DllRegisterServer, fonction EmptyParam, variable EnumDispatchProperties, procdure FontToOleFont, fonction GUIDToString, fonction GetActiveOleObject, fonction GetDispatchPropValue, fonction GetOleFont, procdure GetOlePicture, procdure GetOleStrings, procdure GetRegStringValue, fonction InterfaceConnect, procdure InterfaceDisconnect, procdure OleCheck, procdure OleError, procdure OleFontToFont, procdure OleStrToStrVar, procdure OleStrToString, fonction ParkingWindow, fonction ProgIDToClassID, fonction RegisterAsService, procdure RegisterComServer, procdure SetDispatchPropValue, procdure SetOleFont, procdure SetOlePicture, procdure SetOleStrings, procdure StringToGUID, fonction
Delphi et Kilix

Renvoie le PROGID d'un ID de classe (CLSID) spcifi Indique le niveau de gestion de threads requis pour un serveur .EXE COM Renvoie un objet TComClassManager Fournit des informations sur la classe et le registre pour des objets serveur CreateClassID gnre un nouveau GUID et le renvoie sous forme de chane de caractres Instancie une instance unique d'un objet COM Instancie une instance unique d'un objet Automation Cre ou ouvre une cl de base de registres qui est la cl secondaire de HKEY_CLASSES_ROOT Cre un objet COM sur une autre machine et renvoie une interface IUnknown pour cet objet Supprime une cl secondaire de HKEY_CLASSES_ROOT de la base de registres Utilise pour obtenir un fabricant de classe pour un objet ActiveX lorsque l'objet ActiveX rside dans un serveur ActiveX en processus (DLL) Recense un serveur ActiveX en processus du module en cours dans la base des registres Indique qu'un paramtre facultatif sur une interface double n'est pas utilis Remplit un TstringList avec les noms de toutes les proprits et les DispID d'une interface IDispatch spcifie Renvoie un Variant contenant une interface IFontDispatch reprsentant un objet TFont Convertit un GUID identificateur de classes en chane Transmet une rfrence une interface IDispatch un objet COM actif et recens Renvoie la valeur d'une proprit sur une interface IDispatch Cre un objet police OLE directement mapp un TFont natif Cre un objet image OLE directement mapp un TPicture natif Implmente un objet TStrings en tant qu'interface IStrings utilisable par des objets OLE Supprime une valeur stocke sous une cl secondaire de HKEY_CLASSES_ROOT de la base de registres Connecte une interface IConnectionPoint Dconnecte une interface IConnectionPoint prcdemment connecte par la procdure InterfaceConnect Dclenche une exception EOleSysError si le code de rsultat indique une erreur Dclenche une exception EOleSysError Remplit une structure TFont pour reprsenter un IFontDispatch Copie une chane de sa reprsentation COM dans une chane Pascal existante Copie les donnes reues d'une interface COM dans une chane Propose une fentre parent temporaire pour les contrles activeX lorsque le conteneur n'est pas prt agir comme un parent Renvoie l'ID de classe (le CLSID) correspondant la chane spcifie dans le paramtre ProgID Recense un objet COM comme un service NT RegisterComServer recense un serveur COM en processus avec le systme d'exploitation Dfinit la valeur d'une proprit sur une interface IDispatch Connecte un objet police OLE un objet TFont et copie ses proprits vers TFont Connecte un objet image OLE un objet TPicture et copie ses proprits vers TPicture Utilise une interface IStrings pour attribuer le contenu d'un objet TStrings Convertit une chane en GUID 38 D. Mailliet

MIAGE 2me anne

StringToOleStr, fonction Supports, fonction

Alloue de la mmoire et copie une chane vers le format OLE Indique si un objet donn ou l'interface Iunknown supporte une interface spcifie.

8.

Routines de compatibilit descendante N'existe que pour des raisons de compatibilit descendante Ajoute une chane alloue dynamiquement une chane existante Affecte une nouvelle chane alloue dynamiquement au pointeur spcifi Ferme l'association entre une variable fichier et un fichier externe (Pascal) Libre un pointeur chane ayant t allou avec NewStr Contient le code de sortie de l'application (fourni pour assurer une compatibilit descendante) Charge une chane depuis le fichier excutable de l'application Alloue une chane sur le tas Alloue un tampon pour une chane zro terminal et renvoie un pointeur sur son premier caractre Renvoie le nombre de caractres maximum pouvant tre plac dans un tampon allou par StrAlloc Libre une chane Alloue de l'espace sur et copie une chane dans le tas, renvoyant un pointeur sur la chane Convertit une chane termine par le caractre Null en une chane Pascal Inverse les octets de poids fort avec les octets de poids faible d'un entier ou d'un mot.

AddExitProc, procdure AppendStr, procdure AssignStr, procdure Close, procdure DisposeStr, procdure ExitCode, variable LoadStr, fonction NewStr, fonction StrAlloc, fonction StrBufSize, fonction StrDispose, procdure StrNew, fonction StrPas, fonction Swap, fonction 9.

Informations au niveau de l'application. Reprsente les informations au niveau de l'application CmdShow est transmise la routine ShowWindow de l'API Windows Indique le handle fourni par Windows pour une application ou bibliothque Indique la classe de la fentre utilise pour l'affichage des conseils d'aide Indique si le module a t compil en tant qu'application console Indique si le module est une DLL Contrle lorsque le dbogueur juste temps est appel numre les localisations pour lesquelles le support est disponible Le handle Instance pour l'excutable principal Le handle Instance pour le thread d'excution principal des modules en cours Contrle si l'application affiche un message d'erreur lorsqu'une erreur d'excution se produit Fournit une gestion centralise des messages Windows adresss des menus droulants Reprsente un priphrique cran Spcifie l'identificateur de la plate-forme Win32.

Application, variable (pour les applications standard) CmdShow, variable HInstance, variable HintWindowClass, variable IsConsole, variable IsLibrary, variable JITEnable, variable Languages, fonction MainInstance, variable MainThreadID, variable NoErrMsg, variable PopupList, variable Screen, variable Win32Platform, variable

10.

routines de gestion des exceptions Cre et dclenche une exception EDatabaseError Cre et dclenche une exception EDatabaseError avec un message d'erreur format Contient l'adresse d'une instruction qui a provoqu une erreur d'excution Pointe sur le gestionnaire d'erreur d'excution RTL Renvoie l'adresse laquelle l'exception en cours a t dclenche Renvoie une rfrence l'objet associ l'exception en cours Pointe sur le gestionnaire d'exception RTL de niveau le plus bas Formate un message d'erreur standard Dclenche une exception EOutOfMemory Dclenche une exception pour la dernire erreur Win32 Remplace le gestionnaire d'exceptions concernant les messages d'erreur obtenus par une connexion de socket Windows Affiche un message d'exception et son adresse physique Convertit des codes d'erreur d'API Win32 en chanes 39 D. Mailliet

DatabaseError, procdure DatabaseErrorFmt, procdure ErrorAddr, variable ErrorProc, variable ExceptAddr, fonction ExceptObject, fonction ExceptProc, variable ExceptionErrorMessage, fonction OutOfMemoryError, procdure RaiseLastWin32Error, procdure SetErrorProc, fonction ShowExc eption, procdure SysErrorMessage, fonction
Delphi et Kilix

MIAGE 2me anne

Win32Check, fonction

Vrifie la valeur renvoye par un appel d'API Windows et dclenche ventuellement une exception.

11.

Utilitaires de flux

FindClass, fonction FindClassHInstance, fonction

Trouve et renvoie une classe drive de TPersistent Renvoie le handle d'instance du module dans lequel un type de classe est dfini FindGlobalComponent, variable Renvoie un composant conteneur du niveau le plus lev FindHInstance, fonction Renvoie le handle d'instance du module contenant l'adresse spcifie FindResourceHInstance, fonction Renvoie le handle d'instance du module ressource associ un HINSTANCE spcifi GetClass, fonction Renvoie une classe persistante recense partir de son nom de classe ObjectBinaryToText, procdure Convertit la reprsentation binaire d'un objet en un texte lecture plus facile ObjectResourceToText, procdure Convertit la reprsentation binaire d'une ressource en un texte lecture plus facile ObjectTextToBinary, procdure Convertit une reprsentation littrale symbolique d'un objet en une version binaire utilisable pour enregistrer l'objet dans un flux fichier ou mmoire ObjectTextToResource, procdure Convertit une reprsentation texte symbolique d'un objet en sa reprsentation binaire interne ReadComponentRes, fonction Lit des composants et leurs proprits dans la ressource Windows spcifie ReadComponentResEx, fonction Lit un composant dans une ressource ReadComponentResFile, fonction Lit des composants et leurs proprits dans le fichier de ressources Windows spcifi RegisterClass, procdure Recense une classe d'objet persistant pour que le type de classe puisse tre retrouv RegisterClassAlias, procdure Recense une classe qui est identique une autre classe, l'exception du nom RegisterClasses, procdure Recense un ensemble de classes RegisterIntegerConsts, procdure Recense les fonctions de conversion pour les identificateurs de chanes qui reprsentent des valeurs de types TypeInfo, fonction Renvoie un pointeur sur les informations de type pour un identificateur de type UnregisterClass, procdure Drecense une classe objet UnregisterClasses, procdure Drecense un ensemble de classes UnregisterModuleClasses, procdure Drecense toutes les classes dfinies dans le module spcifi WriteComponentResFile, procdure Place des composants et leur proprits dans un fichier, dans un format de ressource Windows. est valu avant un oprateur de priorit plus basse, les oprateurs de mme priorit tant valus partir de la gauche.

O.
1.

Constantes types / Variables initialises


dfinition

Les constantes types, la diffrences des vraies constantes, peuvent contenir des valeurs de type tableau, enregistrement, procdure ou pointeur. Les constantes types ne peuvent intervenir dans des expressions constantes. Dans l'tat par dfaut du compilateur {$J+}, il est mme possible d'affecter de nouvelles valeurs des constantes types : elles se comportent alors essentiellement comme des variables initialises. Mais si la directive de compilation {$J} est active, il n'est pas possible l'excution de modifier la valeur des constantes types ; en effet ce sont alors des variables en lecture seule. Dclarez une constante type de la manire suivante : const identificateur: type = valeur

Delphi et Kilix

40

D. Mailliet

MIAGE 2me anne

o identificateur est un identificateur valide, type est un type quelconque (sauf un type fichier ou variant) et valeur est une expression de type type. 2. exemples

const Max: Integer = 100; const Chiffres: array [0..9] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); type TCube = array [0..1, 0..1, 0..1] of Integer; const Labyrinthe : TCube = (((0, 1), (2, 3)), ((4, 5), (6,7))); cre un tableau appel Labyrinthe ou : Labyrinthe[0,0,0] Labyrinthe[0,0,1] Labyrinthe[0,1,0] Labyrinthe[0,1,1] = = = = 0 1 2 3 Labyrinthe[1,0,0] Labyrinthe[1,0,1] Labyrinthe[1,1,0] Labyrinthe[1,1,1] = = = = 4 5 6 7

type TPoint = record X, Y: Single; end; TVecteur = array [0..1] of TPoint; TMois = (Jan, Fev, Mar, Avr, Mai, Jun, Jul, Aou, Sep, Oct, Nov, Dec); TDate = record J: 1..31;

M: TMois; A: 1900..1999; end; const Origine: TPoint = (X: 0.0; Y: 0.0); Ligne: TVecteur = ((X: -3.1; Y: 1.5), (X: 5.8; Y: 3.0)); UnJour: TDate = (J: 2; M: Dec; A: 1960);

P.
1.

Transtypage
dfinition

Il est parfois utile de traiter une expression ayant un type donn comme si elle tait d'un type diffrent. Le transtypage permet de le faire en modifiant, temporairement, le type d'une expression. Par exemple, Integer('A') transtype le caractre A en un entier. La syntaxe du transtypage est : IdentificateurType(expression) Le transtypage de variable peut apparatre des deux cts d'une affectation. 2. exemple Boolean(0) // vaut FALSE Color(2) // la 3me couleur si color est un type numr I := Integer('A'); // affecte 65 la variable I Char(I) Boolean(Compteur) TUnTypeDefini(MaVariable) var MonCar: char; ... Shortint(MonCar) := 122; // affecte le caractre z (ASCII 122) MonCar.

Delphi et Kilix

41

D. Mailliet

MIAGE 2me anne

V.
A.
1.

Les routines
Procdure
dfinition

Dclaration des procdures Procedure <nom_proc> ( <liste des Paramtres Formels avec leur type>) ; <Dclaration des objets et des outils de la procdure Structure identique la dclaration des objets et des outils du programme > Begin <Instructions du corps de la procdure > End ; 2. exemple procedure stop; begin writeln(Appuyez sur entre) ; readln end; ... stop; // Appel de la procdure stop dfinie dans la zone des dclarations.

B.
1.

Fonctions
dfinition

Dclaration des fonctions Function<nom_fonc>(<liste des P.F. avec leur type>) : <type du rsultat> ; <Dclaration des objets et des outils Structure identique la dclaration des objets et des outils du programme > Begin <Instructions Corps de la fonction> result := <le rsultat de la fonction> End ; 2. exemple

function f(x : real) : real; Begin result := x*x+2; // on aurait pu crire f := x*x +2 Mais on prfrera utiliser la variable locale implicite result (impossible en turbo pascal) End; Var y : real; ... y := f(3);

C.
1.

Paramtre donne variable


dfinition

Il sagit dun passage de paramtres par valeur. On ne prcde le nom du paramtre daucun mot (ni var, ni const ni out). Le paramtre peut avoir une valeur avant lappel, sa valeur peut tre modifie dans la procdure, la modification nest pas transmise au retour. 2. exemple 42 D. Mailliet procedure essai (x,y : byte);
Delphi et Kilix

MIAGE 2me anne

begin y := x // y prend la valeur de x end; Var a,b : byte: ... a:= 3; b:= 2; essai (a,b); // a et b conservent leurs valeurs

D.
1.

Paramtre Rsultat
dfinition

On prcde le nom du paramtre du mot out. Le paramtre ne doit pas avoir une valeur avant lappel, sa valeur doit tre donne dans la procdure, la modification est transmise au retour. 2. exemple procedure essai (x:byte; out y : byte); begin y := x // y prend la valeur de x end; Var a,b : byte: ... a:= 3; b:= 2; essai (a,b); // a et b valent 3 mais la valeur initiale de b ( 2 ) na pas t transmise y!

E.
1.

Paramtre Donne/rsultat
dfinition

Il sagit dun passage de paramtres par adresse. On prcde le nom du paramtre du mot var. Le paramtre peut avoir une valeur avant lappel, sa valeur peut tre modifie dans la procdure, la modification est transmise au retour.

2.

exemple

procedure essai (x:byte; var y : byte); begin y := x // y prend la valeur de x end; Var a,b : byte: ... a:= 3; b:= 2; essai (a,b); // a et b valent 3 et la valeur initiale de b ( 2 ) a t transmise y!

F.
1.

Paramtre Donne Constante


dfinition

On prcde le nom du paramtre du mot Const. Le paramtre doit avoir une valeur avant lappel, sa valeur ne peut pas tre modifie dans la procdure, et par consquent la modification nest pas transmise au retour.
Delphi et Kilix

43

D. Mailliet

MIAGE 2me anne

2.

exemple

procedure essai (x:byte; Const y : byte); begin y := x // provoquera une erreur : il est impossible de modifier la valeur dun paramtre constant end;

G.
1.

Paramtres facultatifs ou initialiss


dfinition

Il est possible de dfinir des routines (procdures et fonctions) avec n paramtres formels et de les utiliser avec p(<n) paramtres effectifs. Les n-p sont utiliss avec une valeur par dfaut!; Cest par exemple le cas de la fonction prdfinies inc qui sutilise avec 1 ou 2 paramtres : inc(i) quivaut i:=i+1 alors que inc(i,4) quivaut i:=i+4 . Il faut remarquer que lutilisation de inc vite le double calcul dadresse de i et le code gnr est donc plus efficace. Pour dfinir la valeur par dfaut dun paramtre, il suffit de faire suivre le type du paramtre par = suivi de sa valeur par dfaut 2. exemple Si la procdure inc ntait pas prdfinie en delphi, on pourrait lcrire comme ceci :

procedure incr (var n : byte;increment : byte = 1); Begin n:= n+ incrment End; Remarque : bien entendu, la routine prdfinie est plus performante et a surtout lavantage dadmettre les types scalaires.

H.
1.

Paramtres sans type


dfinition

Dans le corps d'une procdure ou d'une fonction, les paramtres sans type sont incompatibles avec tous les types. Pour agir sur un paramtre sans type, vous devez le transtyper. En gnral, le compilateur ne peut vrifier si les oprations effectues sur les paramtres sans type sont lgales. 2. exemples function Egal(var Source, Dest; Taille: Integer): Boolean; type TOctets = array [0..MaxInt - 1] of Byte; // dfinition dun type permettant le transtypage var N: Integer; begin N := 0; while (N < Taille) and (TOctets(Dest)[N] = TOctets(Source)[N]) do Inc(N); Egal := N = Taille; end; type TVecteur = array [1..10] of Integer; TPoint = record X, Y: Integer; end; var
Delphi et Kilix

44

D. Mailliet

MIAGE 2me anne

Vec1, Vec2: TVecteur; N: Integer; P: TPoint; ... Egal(Vec1, Vec2, SizeOf(TVecteur)) // compare Vec1 et Vec2 Egal(Vec1, Vec2, SizeOf(Integer) * N) // compare les N premiers lments de Vec1 et Vec2 Egal(Vec1[1], Vec1[6], SizeOf(Integer) * 5) // compare les 5 premiers lments aux 5 derniers lments de Vec1 Egal(Vec1[1], P, 4) // compare Vec1[1] P.X et Vec1[2] P.Y Exemple 2 ... procedure permute( var a,b;taille:word); var c : pointer; begin getmem(c,taille); move(a,c^,taille); move(b,a,taille); // a:=b dclanche une erreur! move(c^,b,taille); freemem(c,taille) end; var ch1,ch2 : string [20]; x,y:real; BEGIN ch1:='bonjour'; ch2:='salut'; x:=3;y:=5.9; writeln(ch1,ch2,x,y); permute(x,y,sizeof(real)); permute(ch1,ch2,21); writeln(ch1,ch2,x,y); END.

I.
1.

Paramtres tableau ouvert


dfinition

Les paramtres tableau ouvert permettent de transmettre des tableaux de tailles diffrentes la mme routine. Pour dfinir une routine ayant un paramtre tableau ouvert, utilisez la syntaxe array of type (au lieu de array[X..Y] of type) dans la dclaration du paramtre 2. Exemple function Somme( const A: array of Real): Real; var I: Integer; S: Real; begin S := 0; for I := 0 to High(A) do S := S + A[I]; Somme := S; end;

J.
1.

Paramtres tableau ouvert variant


dfinition

Les paramtres tableau ouvert variant permettent de transmettre un tableau d'expressions de types diffrents, une seule routine. Pour dfinir une routine utilisant un paramtre tableau ouvert variant, spcifiez array of const comme type du paramtre. Ainsi : Delphi et Kilix D. Mailliet 45

MIAGE 2me anne

procedure FaireQuelquechose(A: array of const); dclare une procdure appele FaireQuelquechose qui peut agir sur des tableaux de donnes htrognes. La construction array of const est quivalente array of TVarRec. TVarRec, dclar dans l'unit System, reprsente un enregistrement avec une partie variable qui peut contenir des valeurs de type entier, boolen, caractre, rel, chane, pointeur, classe, rfrence de classe, interface et variant. Le champ VType de TVarRec indique le type de chaque lment du tableau. Certains types sont transmis comme pointeur et non comme valeur ; en particulier les chanes longues sont transmises comme Pointer et doivent tre transtypes en string . 2. Exemple L'exemple suivant utilise un paramtre tableau ouvert variant dans une fonction qui cre une reprsentation sous forme de chane de chaque lment transmis et concatne le rsultat dans une seule chane. Les routines de manipulation de chanes utilises dans cette function sont dfinies dans l'unit SysUtils. function MakeStr(const Args: array of const): string ; const BoolChars: array [Boolean] of Char = ('F', 'T'); var I: Integer; begin Result := ''; for I := 0 to High(Args) do with Args[I] do case VType of vtInteger: Result := Result + IntToStr(VInteger); vtBoolean: Result := Result + BoolChars[VBoolean]; vtChar: Result := Result + VChar; vtExtended: Result := Result + FloatToStr(VExtended^); vtString: Result := Result + VString^; vtPChar: Result := Result + VPChar; vtObject: Result := Result + VObject.ClassName; vtClass: Result := Result + VClass.ClassName; vtAnsiString: Result := Result + string (VAnsiString); vtCurrency: Result := Result + CurrToStr(VCurrency^); vtVariant: Result := Result + string (VVariant^); vtInt64: Result := Result + IntToStr(VInt64^); end; end; ... MakeStr(['test', 100, ' ', True, 3.14159, Tform]) ; // renvoie la chane "test100 T3.14159TForm".

K.

Appel de procdure et de fonctions

1. dfinition Lappel (utilisation) dune procdure seffectue comme pour toute instruction en indiquant le nom de la procdure Par dfaut, Sauf directive de compilation, il est possible dignorer le rsultat dune fonction. Cest le cas de fausses procdures :les fonctions effet de bord et qui donne un compte rendu boolen (ou autre) 2. Exemple function exemple : boolean; begin // le corps de la procdure rsult := true; // la procdure sest bien droule end; var tst : boolean;
Delphi et Kilix

46

D. Mailliet

MIAGE 2me anne

... tst := exemple ; // utilisation normale dun prdicat .. ..exemple ;// il est possible dutiliser la fonction comme une procdure si lon ne souhaite pas tenir compte du compte-rendu Exemples : procedure P1 (ch : string [20]); // erreur de syntaxe procedure P2 (ch : Array [1..20] of byte); // erreur de syntaxe procedure P3 (ch : string ); // pas derreur de syntaxe procedure P4 (ch : Array of byte); // pas derreur de syntaxe Type Tch20 = string [20; Ttab = Array [1..20] of byte; procedure P1 (ch : Tch20); // pas derreur de syntaxe procedure P2 (ch : Ttab); // pas derreur de syntaxe Exemple pratique : Var t : array [1..2] of byte; som : byte; function Somme( const A: array of Real): Real; var I: Integer; S: Real; begin S := 0; for I := 0 to High(A) do S := S + A[I]; Somme := S; end; ... t[1] := 5;t[2] := 11; som := somme(t); ... som := somme([3,8,9,6]);

L.
1.

Retour sur le type procdure ou fonction


dfinition

Comme en LISP ou en Scheme, les routines sont des types comme les autres et peuvent donc tre affects ou passs en paramtres.

2.

Exemple function somprod(tb : Ttab; oper : Toper):integer; var i:integer; Begin result:=oper(1,1); for i:=low(tb) to high(tb) do result:=oper(result,tb[i]); somprod:= result; End; function som(tb: Ttab):integer; Begin result:=somprod(tb,plus)-1 End; 47 D. Mailliet

{$F+} function plus( a : integer; b : integer):integer; Begin result := a+b End; function fois( m : integer; n : integer):integer; Begin result:= m*n End; type Toper = function (x : integer; y : integer):integer; Ttab = array [1..5] of byte;
Delphi et Kilix

MIAGE 2me anne

function prod(tb: Ttab):integer; Begin result:=somprod(tb,fois) End; Const 3. Exercice

t:Ttab=(3,6,7,2,3); BEGIN writeln(som(t)); writeln(prod(t)); readln END.

Exercice sur les paramtres de type fonction qui peut tre trait mme sans comprendre le fonctionnement de lalgorithme qui lui pourra tre tudi aprs le paragraphe : Structure de contrle Soit le programme: program QSort; {$apptype console} const Max = 1000; type List = array [1..Max] of Integer; var Data: List; I: Integer; procedure QuickSort(var A: List; Bas, Haut: Integer); procedure Sort(l, r: Integer); var i, j, x, y: integer; Begin i := l; j := r; x := a[(l+r) DIV 2]; repeat while a[i] < x do i := i + 1; while x < a[j] do j := j - 1; if i <= j then begin y := a[i]; a[i] := a[j]; a[j] := y; i := i + 1; j := j - 1; end; until i > j; if l < j then Sort(l, j); if i < r then Sort(i, r); End{Sort}; Begin {QuickSort}; Sort(Bas,Haut); End{QuickSort}; BEGIN {QSort} Write('Generation de 1000 nombres alatoires...'); Randomize; for i := 1 to Max do Data[i] := Random(30000); Writeln; Write('Tri de ces nombres...'); QuickSort(Data, 1, Max); Writeln; for i := 1 to 1000 do Write(Data[i]:8); readln; END.

{ Ce programme gnre une liste de 1000 nombres alatoires entre 0 et 29999, puis les trie en utilisant l'algorithme du TRI-RAPIDE. Finalement affiche le rsultat du tri l'cran. } { QUICKSORT trie les lments d'un tableau A d'indices entre Bas et Haut (bornes inclues) et ce de faon rcursive. L'algorithme consiste choisir un lment (appel pivot) de la liste et d e placer avant lui, tous ceux qui sont plus petits et aprs tous ceux qui sont plus grands. Cet lment se retrouvera donc sa place. On recommence avec le sous-tableau devant cet lment et le sous tableau aprs. On peut choisir au hasard le pivot (premier, dernier, alatoirement...) mais une optimisation consiste utiliser la mthode ci-dessous} Il est simple de transformer la procdure QUICKSORT en lui ajoutant un paramtre fonction qui est en fait une relation dordre que lon utilisera la place de <.

VI. Structure de contrle


A. La squence dinstructions et linstruction compose
Les instructions sont excutes les unes la suite des autres en squence. Elles sont spares par des points-virgules.
Delphi et Kilix

48

D. Mailliet

MIAGE 2me anne

Pour obtenir une instruction compose de plusieurs instructions, il faut les encadrer dun begin et dun end ( la manire dun parenthsage en mathmatiques) ce qui est utile pour les structures de test ou de boucles qui ne ralisent quune instruction simple ou compose.

B.
1.

Linstruction Si
dfinition

L'instruction si a deux formes : if...then et if...then...else. La syntaxe de l'instruction if...then est : if expression then instruction o expression renvoie une valeur boolenne. Si expression vaut True, alors instruction est excute ; sinon elle ne l'est pas. Par exemple : if J <> 0 then Resultat := I/J; La syntaxe de l'instruction if...then...else est : if expression then instruction1 else instruction2 o expression renvoie une valeur boolenne. Si expression vaut True, alors instruction1 est excute ; sinon instruction2 est excute. Par exemple : if J = 0 then Exit else Resultat := I/J; Les clauses then et else contiennent une seule instruction chacune, mais ce peut tre une instruction structure.Par exemple : if J <> 0 then begin Resultat := I/J; Compteur := Compteur + 1; end else if Compteur = Fin then Arret := True else Exit; Remarquez qu'il n'y a jamais de point-virgule entre la clause then et le mot else. Vous pouvez placer un point-virgule aprs une instruction if pour la sparer de l'instruction suivante du bloc mais les clauses then et else ne ncessitent rien d'autre qu'un espace ou un passage la ligne entre elles. Le fait de placer un point-virgule immdiatement avant le else (dans une instruction if) est une erreur de programmation courante. Un problme particulier se prsente quand des instructions if sont imbriques. Le problme se pose car certaines instructions if ont une clause else alors que d'autres ne l'ont pas, mais la syntaxe des deux varits de l'instruction est pour le reste la mme. Dans une srie de conditions imbriques o il y a moins de clauses else que d'instructions if, il n'est pas toujours vident de savoir quel if une clause else est rattache. Soit une instruction de la forme if expression1 then if expression2 then instruction1 else instruction2; Il y a deux manires d'analyser cette instruction : if expression1 then [ if expression2 then instruction1 else instruction2 ]; if expression1 then [ if expression2 then instruction1 ] else instruction2; Le compilateur analyse toujours de la premire manire. C'est--dire que dans du vritable code, l'instruction : est quivalent : if ... { expression1 } then begin if ... { expression2 } then ... { instruction1 } else ... { instruction2 } end;

if ... { expression1 } then if ... { expression2 } then ... { instruction1 } else ... { instruction2 } ;

Delphi et Kilix

49

D. Mailliet

MIAGE 2me anne

La rgle veut que les conditions imbriques sont analyses en partant de la condition la plus interne, chaque else tant li au plus proche if disponible sa gauche. Pour forcer le compilateur lire notre exemple de la deuxime manire, vous devez l'crire explicitement de la manire suivante : if ... { expression1 } then begin if ... { expression2 } then ... { instruction1 } end else ... { instruction2 } ;

C.
1.

Instructions Case
dfinition

L'instruction case propose une alternative plus lisible l'utilisation de conditions if imbriques complexes. Une instruction case a la forme case expressionSelection of listeCas1: instruction1; ... listeCasn: instructionn; end o expressionSelection est une expression de type scalaire (les types chane sont interdits) et chaque listeCas est l'un des lments suivants : Un nombre, une constante dclare ou une expression que le compilateur peut valuer sans excuter le programme. Ce doit tre une valeur de type scalaire compatible avec expressionSelection. Ainsi 7, True, 4 + 5 * 3, 'A', et Integer('A') peuvent tre utiliss comme listeCas, mais les variables et la plupart des appels de fonctions ne peuvent tre utiliss. Un intervalle de la forme Premier..Dernier, o Premier et Dernier respectent tous les deux les critres prcdents et o Premier est infrieur ou gal Dernier. Une liste de la forme lment1, ..., lmentn, o chaque lment respecte l'un des critres prcdents. Chaque valeur reprsente par une listeCas doit tre unique dans l'instruction case ; les intervalles et les listes ne peuvent se chevaucher. Une instruction case peut avoir une clause else finale : case expressionSelection of listeCas1: instruction1; ... listeCasn: instructionn; else instruction; end Le premier listeCas dont la valeur est gale celle de expressionSelection dtermine l'instruction utiliser. Si aucun des listeCas n'a la mme valeur que expressionSelection, alors c'est l'instruction de la clause else (si elle existe) qui est excute. 2. exemples est quivalent la condition imbrique suivante : if I in [1..5] then Caption := 'Bas' else if I in [6..10] then Caption := 'Haut' else if (I = 0) or (I in [10..99]) then Caption := 'Hors de l''intervalle' else Caption := ''; i:=3; case i of 50 D. Mailliet L'instruction case : case I of 1..5: Caption := 'Bas'; 6..9: Caption := 'Baut'; 0, 10..99: Caption := 'Hors de l''intervalle'; else Caption := ''; end;

Attention : var i,x :byte; ..


Delphi et Kilix

MIAGE 2me anne

2..5 : x:=2; 1..4 : x:=1; end; // ici x vaut 2 bien que 3 appartienne aussi lintervalle 1..4, alors que i:=3; Voici d'autres exemples d'instructions case : case MaCouleur of Rouge: X := 1; Vert: X := 2; Bleu: X := 3; Jaune, Orange, Noir: X := 0; end;

case i of 1..4 : x:=1; 2..5 : x:=2; end; // ici x vaut 1 bien que 3 appartienne aussi lintervalle 2..5, seule le premier test valide compte ! case Selection of Fin: Form1.Close; Calcul: CalculTotal(CourUnit, Quant); else Beep; end;

D.
1.

La boucle Rpter
dfinition

L'instruction repeat a la syntaxe suivante : repeat instruction1; ...; instructionn; until expression o expression renvoie une valeur boolenne. Le dernier point-virgule avant until est facultatif. L'instruction repeat excute rptitivement la squence d'instructions qu'elle contient en testant expression chaque itration. Quand expression renvoie True, l'instruction repeat s'arrte. La squence est toujours excute au moins une fois car expression n'est value qu'aprs la premire itration. 2. exemples repeat Write('Entrez une valeur (0..9): '); Readln(I); until (I >= 0) and (I <= 9); repeat K := I Mod J; I := J; J := K; until J = 0;

E.
1.

La boucle tant-que
dfinition

Une instruction while est similaire l'instruction repeat cette diffrence prs que la condition de contrle est value avant la premire itration de la squence d'instructions. Donc si la condition est fausse, la squence d'instructions n'est jamais excute. L'instruction while a la syntaxe suivante : while expression do instruction o expression renvoie une valeur boolenne et instruction peut tre une instruction compose. L'instruction while excute rptitivement son instruction, en testant expression avant chaque itration. Tant que expression renvoie True, l'excution se poursuit. 2. exemples while not Eof(FicSource) do begin Readln(FicSource, Ligne); Process(Ligne); end; while Data[I] <> X do I := I + 1; while I > 0 do begin if Odd(I) then Z := Z * X; I := I div 2; X := Sqr(X); end;

Delphi et Kilix

51

D. Mailliet

MIAGE 2me anne

F.
1.

La boucle Pour
dfinition

Une instruction for , la diffrence des instructions repeat et while, ncessite la spcification explicite du nombre d'itrations que la boucle doit effectuer. L'instruction for a la syntaxe suivante : for compteur := valeurInitiale to valeurFinale do instruction ou for compteur := valeurInitiale downto valeurFinale do instruction o compteur est une variable locale (dclare dans le bloc c ontenant l'instruction for ) de type scalaire sans aucun qualificateur. valeurInitiale et valeurFinale sont des expressions compatibles pour l'affectation avec compteur. instruction est une instruction simple ou structure qui ne modifie pas la valeur de compteur. L'instruction for affecte la valeur valeurInitiale compteur, puis excute rptitivement instruction, en incrmentant ou en dcrmentant compteur aprs chaque itration. La syntaxe for ...to incrmente compteur alors que la syntaxe for ...downto le dcrmente. Quand compteur renvoie la mme valeur que valeurFinale, l'instruction est excute une dernire fois puis l'instruction for s'arrte. En d'autres termes, instruction est excute une fois pour chaque valeur de l'intervalle allant de valeurInitiale valeurFinale. Si valeurInitiale est gale valeurFinale, instruction est excute une seule fois. Si valeurInitiale est suprieure valeurFinale dans une instruction for ...to ou infrieure ou gale valeurFinale dans une instruction for ...downto, alors l'instruction n'est jamais excute. Aprs l'arrt de l'instruction for , la valeur de compteur est non dfinie. Afin de contrler l'excution de la boucle, la valeur des expressions valeurInitiale et valeurFinale n'est value qu'une seule fois, avant le commencement de la boucle. Donc, une instruction for ...to est presque identique la construction while suivante : begin compteur := valeurInitiale; while compteur <= valeurFinale do begin instruction; compteur := Succ(compteur); end; end La diffrence entre cette construction et l'instruction for ...to est que la boucle while rvalue valeurFinale avant chaque itration. Cela peut rduire la vitesse d'excution de manire sensible si valeurFinale est une expression complexe. De plus, cela signifie qu'une modification de la valeur valeurFinale dans instruction peut affecter l'excution de la boucle. 2. exemples for I := 2 to 63 do if Donnees[I] > Max then Max := Donnees[I]; for I := ListBox1.Items.Count - 1 downto 0 do ListBox1.Items[I] := UpperCase(ListBox1.Items[I]); for I := 1 to 10 do for J := 1 to 10 do begin X := 0; for K := 1 to 10 do X := X + Mat1[I, K] * Mat2[K, J]; Mat[I, J] := X; end; for C := Red to Blue do Verif(C);

G.

Break, Exit et Halt

Halt : Interrompt l'excution du programme et rend le contrle au systme d'exploitation. Exit : : Lorsque Exit est appele dans un sous-programme (procdure ou fonction), elle induit un retour immdiat l'appelant. Quand elle est appele en tant qu'instruction du corps de programme principal, elle provoque la fin de l'excution du programme. 52 D. Mailliet

Delphi et Kilix

MIAGE 2me anne

Break : Provoque la fin immdiate d'une boucle FOR, WHILE ou REPEAT Continue : permet de reprendre un boucle interrompue.

H.

Boucles infinies

Il va de soi que si les instructions du corps de boucles ne modifie pas le test de boucle, on obtiendra une boucle infinie Pour raliser volontairement une boucle Infinie, on peut utiliser lune des structures: Repeat // instructions if <test> then break // instructions until FALSE ou encore: While TRUE do begin // instructions if <test> then break // instructions end {while}

I.

Les Exceptions

Une exception est dclenche quand une erreur ou un autre vnement interrompt le droulement normal d'un programme. L'exception transfre le contrle un gestionnaire d'exceptions, ce qui vous permet de sparer la logique normale d'excution du programme de la gestion des erreurs. Comme les exceptions sont des objets, elles peuvent tre regroupes en hirarchies en utilisant l'hritage et de nouvelles exceptions peuvent tre ajoutes sans affecter le code existant. Une exception peut vhiculer des informations, par exemple un message d'erreur, depuis le point o elle est dclenche jusqu'au point o elle est gre. Quand une application utilise l'unit SysUtils, toutes les erreurs d'excution sont automatiquement converties en exceptions. Les erreurs qui autrement provoqueraient l'arrt d'une application (mmoire insuffisante, division par zro, erreurs de protection gnrales) peuvent ainsi tre interceptes et gres.

1.

Instructions Try...except

Les exceptions sont gres dans des instructions try...except . Par exemple : try X := Y/Z; except on EZeroDivide do GereDivisionParZero; end; Cette instruction tente de diviser Y par Z mais appelle la routine appele GereDivisionParZero si une exception EZeroDivide est dclenche. L'instruction try...except a la syntaxe suivante : try instructions except blocException end o instructions est une suite d'instructions, dlimite par des points-virgule et blocException est : une autre suite d'instruction ou une suite de gestionnaires d'exceptions, ventuellement suivie par : else instructions Un gestionnaire d'exception a la forme : on identificateur: type do instruction o identificateur: est facultatif (si identificateur est prcis, ce doit tre un identificateur valide), type est le type utilis pour reprsenter les exceptions et instruction est une instruction quelconque. Une instruction try...except excute les instructions dans la lis te initiale instructions. Si aucune exception n'est dclenche, le bloc exception (blocException) n'est pas pris en compte et le contrle passe l'instruction suivante du programme. Si une exception est dclenche lors de l'excution de la liste instructions initiale, que ce soit par une instruction raise dans la liste instructions ou par une procdure ou une fonction appele dans la liste instructions, il va y avoir une tentative de "gestion" de l'exception : Si un des gestionnaires du bloc exception ne correspond l'exception, le contrle passe au premier d'entre eux. Un gestionnaire d'exceptions "correspond" une exception si le type du gestionnaire est la classe de l'exception ou un anctre de cette classe. Si aucun gestionnaire correspondant n'est trouv, le contrle passe l'instruction de la clause else si elle est dfinie.
Delphi et Kilix

53

D. Mailliet

MIAGE 2me anne

Si le bloc d'exception est simplement une suite d'instructions sans gestionnaire d'exception, le contrle passe la premire instruction de la liste. Si aucune de ces conditions n'est respecte, la recherche continue dans le bloc exception de l'avant-dernire instruction try...except dans laquelle le flux du programme est entr et n'est pas encore sorti. Si, l encore, il n'y ni gestionnaire appropri, ni clause else, ni liste d'instructions, la recherche se propage l'instruction en cours try...except prcdente, etc. Si l'instruction try...except la plus loigne est atteinte sans que l'exception soit gre, le programme s'interrompt. Quand l'exception est gre, le pointeur de la pile est ramen en arrire jusqu' la procdure ou la fonction contenant l'instruction try...except o la gestion a lieu et le contrle d'excution passe au gestionnaire d'exception excut, la clause else ou la liste d'instructions. Ce processus efface tous les appels de procdure ou de fonction effectus partir de l'entre dans l'instruction try...except o l'exception est gre. L'objet exception est alors automatiquement dtruit par un appel de son destructeur Destroy et le contrle revient l'instruction suivant l'instruction try...except . Si un appel des procdures standard Exit, Break ou Continue force la sortie du gestionnaire d'exception, l'objet exception est quand mme dtruit automatiquement. Dans l'exemple suivant, le premier gestionnaire d'exceptions gre les exceptions division-par-zro, le second gre les exceptions de dbordement et le dernier gre toutes les autres exceptions mathmatiques. EMathError apparat en dernier dans le bloc exception car c'est l'anctre des deux autres classes d'exception : s'il apparat en premier, les deux autres gestionnaires ne sont jamais utiliss. try ... except on EZeroDivide do GereDivisionParZero; on EOverflow do GereDebordement; on EMathError do GereErreurMath; end; Un gestionnaire d'exceptions peut spcifier un identificateur avant le nom de la classe exception. Cela dclare l'identificateur reprsentant l'objet exception pendant l'excution de l'instruction suivant on...do. La porte de l'identificateur est limite celle de l'instruction. Par exemple : try ... except on E: Exception do ErrorDialog(E.Message, E.HelpContext); end; Si le bloc exception spcifie une clause else, la clause else gre toutes les exceptions qui ne sont pas gres par les gestionnaires du bloc. Par exemple : try ... except on EZeroDivide do GereDivisionParZero; on EOverflow do GereDebordement; on EMathError do GereErreurMath; else GereLesAutres; end; Ici la clause else gre toutes les exceptions qui ne sont pas des erreurs mathmatiques (EMathError). Si le bloc exception ne contient pas de gestionnaires d'exceptions mais une liste d'instructions, cette liste gre toutes les exceptions. Par exemple : try ... except GereException; end; Ici la routine GereException gre toutes les exceptions se produis ant lors de l'excution des instructions comprises entre try et except . Redclenchement d'exceptions Quand le mot rserv raise apparat dans un bloc exception sans tre suivi d'une rfrence d'objet, il dclenche l'exception qui tait gre par le bloc. Cela permet un gestionnaire d'exception de rpondre une erreur d'une manire partielle, puis de redclencher l'exception. Cela est pratique quand une procdure ou une fonction doit "faire le mnage" aprs le dclenchement d'une exception sans pouvoir grer compltement l'exception.
Delphi et Kilix

54

D. Mailliet

MIAGE 2me anne

Par exemple, la fonction GetFileList alloue un objet TStringList et le remplit avec les noms de fichiers correspondant au chemin de recherche spcifi : function GetFileList(const Path: string ): TStringList; var I: Integer; SearchRec: TSearchRec; begin Result := TStringList.Create; try I := FindFirst(Path, 0, SearchRec); while I = 0 do begin Result.Add(SearchRec.Name); I := FindNext(SearchRec); end; except Result.Free; raise; end; end; GetFileList cre un objet TStringList puis utilise les fonctions FindFirst et FindNext (dfinies dans SysUtils) pour l'initialiser. Si l'initialisation choue (car le chemin d'initialisation est incorrect ou parce qu'il n'y a pas assez de mmoire pour remplir la liste de chanes), c'est GetFileList qui doit librer la nouvelle liste de chanes car l'appelant ne connat mme pas son existence. C'est pour cela que l'initialisation de la liste de chanes se fait dans une instruction try...except . Si une exception a lieu, le bloc exception de l'instruction libre la liste de chanes puis redclenche l'exception. Exceptions imbriques Le code excut dans un gestionnaire d'exceptions peut lui aussi dclencher et grer des exceptions. Tant que ces exceptions sont galement gres dans le gestionnaire d'exceptions, elles n'affectent pas l'exception initiale. Par contre, si une exception dclenche dans un gestionnaire d'exceptions commence se propager au-del du gestionnaire, l'exception d'origine est perdue. Ce phnomne est illustr par la fonction Tan suivante. type ETrigError = class(EMathError); function Tan(X: Extended): Extended; begin try Result := Sin(X) / Cos(X); except on EMathError do raise ETrigError.Create('Argument incorrect pour Tan'); end; end; Si une exception EMathError se produit lors de l'excution de Tan, le gestionnaire d'exceptions dclenche une exception ETrigError. Comme Tan ne dispose pas de gestionnaire pour ETrigError, l'exception se propage au-del du gestionnaire d'exceptions initial, ce qui provoque la destruction de l'objet exception EMathError. Ainsi, pour l'appelant, tout se passe comme si la fonction Tan avait dclench une exception ETrigError. 2. Instructions try...finally Dans certains cas, il est indispensable que certaines parties d'une opration s'effectuent, que l'opration soit ou non interrompue par une exception. Si, par exemple, une routine prend le contrle d'une ressource, il est souvent important que cette ressource soit libre quelle que soit la manire dont la routine s'achve. Vous pouvez, dans ce genre de situations, utiliser une instruction try...finally. L'exemple suivant illustre comment du code qui ouvre et traite un fichier peut garantir que le fichier est ferm, mme s'il y a une erreur l'excution. Reset(F); try ... // traiter le fichier F finally CloseFile(F); end; Une instruction try...finally a la syntaxe suivante : try listeInstruction1 finally listeInstruction2 end o chaque listeInstruction est une suite d'instructions dlimites par des points-virgule. L'instruction try...finally excute les instructions de listeInstruction1 (la clause try). Si listeInstruction1 se termine sans dclencher d'exception, listeInstruction2 (la clause finally) est excute. Si une exception est dclenche lors de l'excution de listeInstruction1, le
Delphi et Kilix

55

D. Mailliet

MIAGE 2me anne

contrle est transfr listeInstruction2 ; quand listeInstruction2 a fini de s'excuter, l'exception est redclenche. Si un appel des procdures Exit, Break ou Continue force la sortie de listeInstruction1, listeInstruction2 est excute automatiquement. Ainsi, la clause finally est toujours excute quelle que soit la manire dont se termine l'excution de la clause try. Si une exception est dclenche sans tre gre par la clause finally, cette exception se propage hors de l'instruction try...finally et toute exception dj dclenche dans la clause try est perdue. La clause finally doit donc grer toutes les exceptions dclenches localement afin de ne pas perturber la propagation des autres exceptions. Classes et routines standard des exceptions L'unit SysUtils dclare plusieurs routines standard de gestion d'exceptions, dont ExceptObject, ExceptAddr et ShowException. SysUtils et d'autres units de la VCL contiennent galement de nombreuses classes d'exceptions qui drivent toutes (sauf OutlineError) de Exception. La classe Exception contient les proprits Message et HelpContext qui peuvent tre utilises pour transmettre une description de l'erreur et un identificateur de contexte pour une aide contextuelle. Elle dfinit galement divers constructeurs qui permettent de spcifier la description et l'identificateur de contexte de diffrentes manires. Pour davantage d'informations, voir l'aide en ligne.

J.

Linstruction with

Une instruction with est un raccourci permettant de rfrencer les champs d'un enregistrement ou les proprits et mthodes d'un objet. L'instruction with a la syntaxe suivante with obj do instruction ou with obj1, ..., objn do instruction o obj est une rfrence de variable dsignant un objet ou un enregistrement et instruction est une instruction simple ou structure. A l'intrieur de instruction, vous pouvez faire rfrence aux champs, proprits et mthodes de obj en utilisant seulement leur identificateur, sans utiliser de qualificateur. Par exemple, tant donn les dclarations suivantes : type TDate = record Jour: Integer; Mois: Integer; Annee: Integer; end; var DateCommande: TDate; Vous pouvez crire l'instruction with suivante : with DateCommande do if Mois = 12 then begin Mois := 1; Annee := Annee + 1; End else Mois := Mois + 1; Qui est quivalente if DateCommande.Mois = 12 then begin DateCommande.Mois := 1; DateCommande.Annee := DateCommande.Annee + 1; end else DateCommande.Mois := DateCommande.Mois + 1; Si l'interprtation de obj suppose des indices de tableau ou le drfrencement de pointeurs, ces actions ne sont effectues qu'une seule fois, avant l'excution de l'instruction. Cela rend les instructions with aussi efficaces que concises. Mais cela signifie galement que les affectations d'une variable l'intrieur de l'instruction ne peuvent changer l'interprtation de obj pendant l'excution en cours de l'instruction with. Chaque rfrence de variable ou nom de mthode d'une instruction with est interprt, si c'est possible, comme un membre de l'objet ou de l'enregistrement spcifi. Pour dsigner une autre variable ou mthode portant le mme nom que celui auquel vous accdez avec l'instruction with, vous devez le prfixer avec un qualificateur comme dans l'exemple suivant : with DateCommande do begin Annee := Unit1.Annee ... end;
Delphi et Kilix

56

D. Mailliet

MIAGE 2me anne

Quand plusieurs objets ou enregistrements apparaissent aprs le mot rserv with, l'instruction est trait comme une srie d'instructions with imbrique. Ainsi with obj1, obj2, ..., objn do instruction est quivalent with obj1 do with obj2 do ... with objn do instruction Dans ce cas, chaque rfrence de variable ou nom de mthode de instruction est interprt, si c'est possible, comme un membre de objn ; sinon, il est interprt, si c'est possible, comme un membre de objn1; et ainsi de suite. La mme rgle s'applique pour l'interprtation mme des objs : si objn est un membre de obj1 et de obj2, il est interprt comme obj2.objn.

K.

Amlioration de la lisibilit

Afin de les rendre plus lisible, on sinspirera des programmes ADA en terminant les structures par un commentaire de fin de structure : Function toto ... end {toto} ; if ... begin ... end{if} ; case ... end {case} ; With ... end{with}; while ... end{while} ; for k... end{for k}; record toto ... end{record}; // ou end{toto};

L.

Blocs et porte

Les dclarations et les instructions sont organises en blocs qui dfinissent des noms de domaine locaux (ou portes) pour les labels et les identificateurs. Les blocs permettent un mme identificateur, par exemple un nom de variable, d'avoir des significations diffrentes dans diffrentes parties d'un programme. Chaque bloc fait partie de la dclaration d'un programme, d'une fonction ou d'une procdure ; la dclaration de chaque programme, fonction ou procdure est compose d'un seul bloc. 1. Blocs Un bloc est compos d'une srie de dclarations suivies d'une instruction compose. Toutes les dclarations doivent se trouver rassembles au dbut du bloc. Un bloc a donc la forme suivante : dclarations begin instructions end La section dclarations peut contenir, dans un ordre quelconque, des dclarations de variables, de constantes (y compris des chanes de ressource), de types, de procdures, de fonctions et de labels. Dans un bloc de programme, la section dclarations peut galement contenir une ou plusieurs clauses exports (voir Bibliothques de liaison dynamique et paquets). Par exemple, dans la dclaration de fonction suivante : function Majuscule (const S: string ): string ; var Ch: Char; L: Integer; Source, Dest: PChar; begin ... end;
Delphi et Kilix

57

D. Mailliet

MIAGE 2me anne

La premire ligne de la dclaration est l'en-tte de fonction et toutes les lignes suivantes constituent le bloc de la fonction. Ch, L, Source et Dest sont des variables locales ; leur dclaration n'est valable que dans le bloc de la fonction Majuscule et redfinit (uniquement dans ce bloc) toute dclaration des mmes identificateurs faite dans le bloc du programme ou dans les sections interface ou implmentation d'une unit. 2. Porte Un identificateur, par exemple une variable ou un nom de fonction, ne peut tre utilis qu' l'intrieur de la porte de sa dclaration. L'emplacement d'une dclaration dtermine sa porte. La porte d'un identificateur dclar dans la dclaration d'un programme, d'une fonction ou d'une procdure est limite au bloc dans lequel il a t dclar. Un identificateur dclar dans la section interface d'une unit a une porte qui inclut toutes les autres units et programmes utilisant l'unit o cette dclaration est faite. Les identificateurs ayant une porte plus restreinte (en particulier les identificateurs dclars dans les fonctions et procdures) sont parfois dits locaux alors que les identificateurs ayant une porte plus tendue sont appele globaux. Les rgles dterminant la porte d'un identificateur sont rsumes ci-dessous : Si l'identificateur est dclar dans ... Sa porte s'tend ... La dclaration d'un programme, d'une Depuis le point o il a t dclar jusqu' la fin du bloc en cours, y fonction ou d'une procdure. compris tous les blocs inclus dans cette porte. La section interface d'une unit. Depuis le point o il a t dclar jusqu' la fin de l'unit et dans toutes les units ou programmes utilisant cette unit. Voir Programmes et units.) La section implmentation d'une unit Depuis le point o il a t dclar jusqu' la fin de la section mais hors du bloc d'une fonction ou d'une implmentation. L'identificateur est disponible dans toutes les procdure. fonctions et procdures de la section implmentation. La dfinition d'un type enregistrement Depuis le point o il a t dclar jusqu' la fin de la dfinition du (c'est--dire que l'identificateur est le type de champ. Voir Enregistrements.) nom d'un champ de l'enregistrement). La dfinition d'une classe (c'est--dire Depuis le point o il a t dclar jusqu' la fin de la dfinition du que l'identificateur est le nom d'une type classe et galement dans les dfinitions des descendants de la proprit ou d'une mthode de la classe). classe et les blocs de toutes les mthodes de la classe et de ses descendants. Voir Classes et objets. 3. Conflits de nom

Quand un bloc en comprend un autre, le premier est appel bloc extrieur et l'autre est appel bloc intrieur. Si un identificateur dclar dans le bloc extrieur est redclar dans le bloc intrieur, la dclaration intrieure redfinit l'extrieure et dtermine la signification de l'identificateur pour la dure du bloc intrieur. Si, par exemple, vous avez dclar une variable appele ValeurMax dans la section interface d'une unit, puis si vous dclarez une autre variable de mme nom dans une dclaration de fonction de cette unit, toute occurrence non qualifie de ValeurMax dans le bloc de la fonction est rgit par la deuxime dfinition, celle qui est locale. De mme, une fonction dclare l'intrieur d'une autre fonction cre une nouvelle porte interne dans laquelle les identificateurs utiliss par la fonction externe peuvent tre localement redfinis. L'utilisation de plusieurs units complique davantage la dfinition de porte. Chaque unit numre dans une clause uses impose une nouvelle porte qui inclut les units restantes utilises et le programme ou l'unit contenant la clause uses . La premire unit d'une clause uses reprsente la porte la plus externe, et chaque unit successive reprsente une nouvelle porte interne la prcdente. Si plusieurs units dclarent le mme identificateur dans leur section interface, une rfrence sans qualificateur l'identificateur slectionne la dclaration effectue dans la porte la plus externe, c'est--dire dans l'unit o la rfrence est faite, ou, si cette unit ne dclare pas l'identificateur dans la dernire unit de la clause uses qui dclare cet identificateur. L'unit System est utilise automatiquement par chaque programme et unit. Les dclarations de System ainsi que les types prdfinis, les routines et les constantes reconnues automatiquement par le compilateur ont toujours la porte la plus extrieure. Vous pouvez redfinir ces rgles de porte et court-circuiter une dclaration intrieure en utilisant un identificateur qualifi (voir Identificateurs qualifis) ou une instruction with (voir Instructions with).

Delphi et Kilix

58

D. Mailliet

MIAGE 2me anne

4.

Identificateurs qualifis

Quand vous utilisez un identificateur qui a t dclar plusieurs endroits, il est parfois ncessaire de qualifier l'identificateur. La syntaxe d'un identificateur qualifi est : identificateur1.identificateur2 o identificateur1 q ualifie identificateur2. Si, par exemple, deux units dclarent une variable appele ValeurEnCours, vous pouvez dsigner ValeurEnCours de Unit2 en crivant : Unit2.ValeurEncours Il est possible de chaner les qualificateurs. Par exemple : Form1.Button1.Click Appelle la mthode Click de Button1 dans Form1. Si vous ne qualifiez pas un identificateur, son interprtation est dtermine par les rgles de porte dcrites dans Blocs et porte.

M.

Exercice

Reprendre ltude de lalgorithme du tri rapide page 48

VII. Surcharge des routines


1. dfinition Il est possible de redclarer plusieurs fois une routine dans la mme porte sous le mme nom. C'est ce que l'on appelle la redfinition (ou surcharge). Les routines redfinies doivent tre redclares avec la directive overload et doivent utiliser une liste de paramtres diffrente. Soit, par exemple, les dclarations : function Diviser(X, Y: Real): Real; overload; begin Result := X/Y; end; function Diviser(X, Y: Integer): Integer; overload; begin Result := X div Y; end; Ces dclarations crent deux fonctions appeles toutes les deux Diviser qui attendent des paramtres de types diffrents. Quand vous appelez Diviser, le compilateur dtermine la fonction utiliser en examinant les paramtres effectivement transmis dans l'appel. Ainsi, Diviser(6.0, 3.0) appelle la premire fonction Diviser car ses arguments sont des valeurs relles. Lorsqu'une routine est redfinie, vous pouvez transmettre des paramtres qui ne sont pas de mmes types que ceux des dclarations de la routine, mais qui sont compatibles pour l'affectation avec les paramtres de plus d'une dclaration. Par exemple, cela se produit trs frquement lorsqu'une routine est surcharge avec des types d'entiers diffrents ou des types de rels diffrents. procedure Store(X: Longint); overload; procedure Store(X: Shortint); overload; Dans ces cas, lorsque cela est possible sans ambigut, le compilateur invoque la routine dont le type des paramtres a l'tendue la plus courte supportant les paramtres rels passs dans l'appel. (Souvenez-vous que les expressions constantes de valeur relle sont toujours de type Extended.) Les routines redfinies doivent pouvoir se distinguer par le nombre ou le type de leurs paramtres. Ainsi, la paire de dclarations suivante dclenche une erreur de compilation : function Maj(S: string ): string ; overload; ... procedure Maj(var Str: string ); overload; ... Alors que les dclarations : function Fonc(X: Real; Y: Integer): Real; overload; ... function Fonc(X: Integer; Y: Real): Real; overload;
Delphi et Kilix

59

D. Mailliet

MIAGE 2me anne

... sont lgales. Quand une routine redfinie est dclare dans une dclaration forward ou d'interface, la dclaration de dfinition doit obligatoirement rpter la liste des paramtres de la routine. Si vous utilisez des paramtres par dfaut dans des routines redfinies, mfiez-vous des signatures de paramtres ambigus. Pour davantage d'informations, voir Paramtres par dfaut et routines redfinies. Vous pouvez limiter les effets potentiels de la redfinition en qualifiant le nom d'une routine lors de son appel. Par exemple, Unit1.MaProcedure(X, Y) n'appelle que les routines dclares dans Unit1 ; si aucune routine de Unit1 ne correspond au nom et la liste des paramtres, il y a une erreur de compilation. Pour des informations sur la distribution de mthodes redfinies dans une hirarchie de classes, voir Redfinition de mthodes. Pour plus d'informations sur l'exportation depuis une DLL de routines redfinies, voir La clause exports de laide Delphi. 2. exemple

//Surcharge de la procdure val de l'unit system function val(chn:string ):real ; overload; var err:integer ; begin system.val(chn,result,err); // rcupration de la // procdure d'origine. Val seulement ferait //rfrence (rcursive) la fonction end;

VIII. Exemples rcapitulatifs


Ces 2 exemples traitent une liste de chanes de caractres

A.

exemple 1

Ce premier exemple utilise une variable globale (la liste)

program strlst1; {$APPTYPE CONSOLE} uses dialogs; Const nl=#10#13; max=100; var nb:word; item:array [1..max] of string ; procedure clear; Begin nb := 0 End; procedure add (chn:string ); Begin inc(nb); item[nb]:=chn; End; procedure delete (num:word);
Delphi et Kilix

var i :word; Begin for i:= num to nb do item[i]:=item[i+1]; dec(nb); End; procedure insert (num:word;chn:string ); var i :word; Begin inc(nb); for i:= nb downto num do item[i]:=item[i-1]; item[num]:= chn; End; procedure exchange (pos1,pos2:word); var tmp: string ; Begin tmp := item[pos1]; item[pos1]:= item[pos2]; item[pos2]:= tmp; End; 60 D. Mailliet

MIAGE 2me anne

function getItem(Const Index: Integer): string ; Begin result := item[Index]; End ; function toutTexte : string ; var indx : word; Begin result:=''; for indx:=1 to nb do result := result+nl+item[indx]; End ; function Find(const S: string ; var Index: Integer): Boolean;

{ Fonction qui recherche une chane S dans le tableau T la fonction renvoie - Vrai si S est dans T et la paramtre rsultat Index contient l'adresse - Faux sinon et index contient n'importe quoi} var i : word ; Begin // A crire ... End ; procedure sort() ; // ou procedure sort; {Trie les chanes du tableau en ordre croissant} Begin // A crire ... revoir le Qsort page 48 End;

BEGIN clear(); // ou plus simplement clear ; Add('premire ligne'); Add('deuxime ligne'); Add('toisime ligne'); ShowMessage('utilisation de la fonction :'+nl+nl+toutTexte); writeln( 'utilisation du champ : chane d''indice 1:'+nl+nl+item[1]); writeln; writeln('remarquer les lettres accentues en mode console et fentr'); ShowMessage('utilisation de la fonction :chane d''indice 1'+nl+nl+GetItem(1)); insert(3,'ligne 2 bis',maListe); ShowMessage('utilisation de la fonction :'+nl+nl+toutTexte()); END.

B.

exemple 2

Ce second exemple est une modification du prcdent utilisant un record et un passage de paramtres pae adresse :

program strlst2; {$APPTYPE CONSOLE} uses dialogs; Const nl=#10#13; max=100; type TtabStr =record nb:word; item:array [1..max] of string ; end{record}; procedure clear (var t: TtabStr); Begin with t do nb:=0 // ou plus simplement t.nb := 0 End; procedure add (chn:string ; var t: TtabStr); Begin
Delphi et Kilix

with t do begin // On pourrait ne pas utiliser with et inc(nb); // qualifier chaque champ : inc(t.nb); item[nb]:=chn;// t.item[t.nb] := chn end; {with} End{add}; procedure delete (num:word;var t: TtabStr); var i :word; Begin with t do begin for i:= num to nb do item[i]:=item[i+1]; dec(nb); end{with}; End; {delete} procedure insert (num:word;chn:string ; var t: TtabStr); var i :word; 61 D. Mailliet

MIAGE 2me anne

Begin with t do begin inc(nb); for i:= nb downto num do item[i]:=item[i-1]; item[num]:= chn; end{with}; End; {insert} procedure exchange (pos1,pos2:word;var : TtabStr); var tmp: string ; Begin with t do begin tmp := item[pos1]; item[pos1]:= item[pos2]; item[pos2]:= tmp; end{with}; End; {exchange} function getItem(Const Index: Integer; Const t: TtabStr): string ; Begin with t do result := item[Index] // ou plus simplement : result := t.item[Index]; End {getItem}; var maListe: TtabStr;

function toutTexte( Const t: TtabStr): string; var indx : word; Begin result:=''; with t do for indx:=1 to nb do result := result+nl+item[indx]; End{toutTexte} ; function Find(const S: string ; Const T: TtabStr; var Index: Integer): Boolean; { Fonction qui recherche une chane S dans le tableau T la fonction renvoie Vrai si S est dans T et la paramtre rsultat Index contient l'adresse Faux sinon et index contient n'importe quoi} var i : word ; Begin // A crire ... End ; procedure sort (var t: TtabStr); {Trie les chaines du tableau en ordre croissant} Begin // A crire ... revoir le Qsort page 48 End;

BEGIN { strlst2} clear(maListe); Add('premire ligne',maListe); Add('deuxime ligne',maListe); Add('toisime ligne',maListe); ShowMessage('utilisation de la fonction :'+nl+nl+toutTexte(maListe)); writeln( 'utilisation du champ : chane d''indice 1:'+nl+nl+maListe.item[1]); writeln; writeln('remarquer les lettres accentues en mode console et fentr'); ShowMessage('utilisation de la fonction :chane d''indice 1'+nl+nl+GetItem(1,maListe)); insert(3,'ligne 2 bis',maListe); ShowMessage('utilisation de la fonction :'+nl+nl+toutTexte(maListe)); END.

IX. Structure de donnes oriente objet


A. Terminologie
Une classe (un type classe) dfinit une structure compose de champs, de mthodes et de proprits. Les instances d'un type classe sont appeles des objets. Les champs, mthodes et proprits d'une classe sont appels ses composants ou ses membres. Un champ est essentiellement une variable faisant partie d'un objet. Comme les champs d'un enregistrement, un champ de classe reprsente des lments de donnes qui existent dans chaque instance de la classe. Une mthode est une procdure ou une fonction associe la classe. La plupart des mthodes portent sur des objets, c'est-dire sur des instances d'une classe. Certaines mthodes, appeles mthodes de classe, portent sur les types classe mme. Delphi et Kilix D. Mailliet 62

MIAGE 2me anne

Une proprit est une interface avec les donnes associes un objet (souvent stockes dans un champ). Les proprits ont des spcificateurs d'accs qui dterminent comment leurs donnes sont lues et modifies. Pour le reste d'un programme (hors de l'objet mme), une proprit apparat bien des points de vue comme un champ. Les objets sont des blocs de mmoire allous dynamiquement dont la structure est dtermine par leur type de classe. Chaque objet dtient une copie unique de chaque champ dfini dans la classe. Par contre, toutes les instances d'une classe partagent les mmes mthodes. Les objets sont crs et dtruits par des mthodes spciales appeles constructeurs et destructeurs. Une variable de type classe est en fait un pointeur qui rfrence un objet. Plusieurs variables peuvent donc dsigner le mme objet. Comme les autres pointeurs, les variables de type classe peuvent contenir la valeur nil. Cependant, il n'est pas ncessaire de drfrencer explicitement une variable de type classe pour accder l'objet qu'elle dsigne. Par exemple, UnObjet.Taille := 100 affecte la valeur 100 la proprit Taille de l'objet rfrenc, UnObjet ; vous ne devez pas l'crire sous la forme UnObjet^.Taille := 100. Un type classe doit tre dclar et nomm avant de pouvoir tre instanci. Il n'est donc pas possible de dfinir un type classe dans une dclaration de variable. Dclarez les classes uniquement dans la porte la plus large d'un programme ou d'une unit, mais pas dans une dclaration de procdure ou de fonction. La dclaration d'un type classe a la forme suivante : type nomClasse = class (classeAnctre) listeMembre end; o nomClasse est un identificateur valide, (classeAnctre) est facultatif et listeMembre dclare les membres (les champs, mthodes et proprits) de la classe. Si vous omettez (classeAnctre), la nouvelle classe hrite directement de la classe prdfinie TObject. Si vous prcisez (classeAnctre) en laissant vide listeMembre, vous pouvez omettre le end final. Une dclaration de type classe peut galement contenir une liste des interfaces implmentes par la classe ; voir Implmentation des interfaces. Les mthodes apparaissent dans une dclaration de classe sous la forme d'en-tte de fonction ou de procdure sans le corps. La dclaration de dfinition de chaque mthode est faite ailleurs dans le programme. Quand vous dclarez une classe, vous pouvez spcifier son anctre immdiat. Par exemple : type TUnControle = class (TWinControl); dclare une classe appele TUnControle qui descend (drive) de TWinControl. Un type classe hrite automatiquement de tous les membres de son anctre immdiat. Chaque classe peut dclarer de nouveaux membres et redfinir les membres hrits. Par contre, une classe ne peut supprimer des membres dfinis dans son anctre. Ainsi TUnControle contient tous les membres dfinis dans TWinControl et dans chacun des anctres de TWinControl. La porte de l'identificateur d'un membre commence l'endroit o le membre est dclar et se poursuit jusqu' la fin de la dclaration de la classe et s'tend tous les descendants de la classe et les blocs de toutes les mthodes dfinies dans la classe et ses descendants.

B.

TObject et TClass

La classe TObject, dclare dans l'unit System, est l'anctre ultime de toutes les autres classes. TObject dfinit seulement quelques mthodes, dont un constructeur et un destructeur de base. Outre la classe TObject, l'unit System dclare le type rfrence de classe TClass : TClass = class of TObject; Quand la dclaration d'un type classe ne spcifie pas d'anctre, la classe hrite directement de TObject. Donc : type TMaClasse = class ... end; est quivalent :
Delphi et Kilix

63

D. Mailliet

MIAGE 2me anne

type TMaClasse = class(TObject) ... end;

C.

Exemple

Reprenons lexemple page 61 des listes de chanes utilisant un record et changeons ce mot en class (les seuls changements apparaissent en gras):

program strlst3; {$APPTYPE CONSOLE} uses dialogs; Const nl=#10#13; max=100; type TtabStr =class nb:word; Remarques

item:array [1..max] of string ; end{class}; // Idem strlst2 BEGIN maListe:= TtabStr.create; // instancions lobjet clear(maListe); // Idem strlst2 maListe.destroy // librons la mmoire END.

Dans lexemple prcdent on utilise le constructeur create des Tobject create est toujours qualifi par une classe et non par lobjet alors que destroy est qualifi par lobjet

D.

Compatibilit des types classe

Un type classe est compatible pour l'affectation avec ses anctres. Une variable d'un type classe peut donc rfrencer une instance de tout type descendant. Par exemple, tant donn la dclaration : type TFigure = class(TObject); TRectangle = class(TFigure); TCarre = class(TRectangle); var Fig: TFigure; il est possible d'affecter la variable Fig des valeurs de type TFigure, TRectangle TCarre.

E.

Visibilit des membres de classes

Chaque membre d'une classe a un attribut appel visibilit, indiqu par l'un des mots rservs suivants : private , protected, public, published ou automated. Par exemple : published property Couleur: TColor read LitCouleur write EcritCouleur; dclare une proprit publie appele Couleur. La visibilit dtermine o et comment il est possible d'accder un membre : private (prive) reprsente l'accs minimum, ==> Ne sont accessibles que par les instances de la classe elle-mme. protected (protge) reprsente un niveau intermdiaire d'accs, ==> Sont accessibles par les instances de la classe ellemme et par les instances des classes drives de la classe en question. public (publique), published (publie) ==> Sont accessibles par toutes les instances de les toutes classes automated (automatise) reprsentant l'accs le plus large. ==> Sont accessibles par toutes les instances de les toutes classes et par linspecteur dobjet.

Delphi et Kilix

64

D. Mailliet

MIAGE 2me anne

Si la dclaration d'un membre ne spcifie pas sa visibilit, le membre a la mme visibilit que celui qui le prcde. Les membres au dbut de la dclaration d'une classe dont la visibilit n'est pas spcifie sont par dfaut publis si la classe a t compile dans l'tat {$M+} ou si elle drive d'une classe compile l'tat {$M+} ; sinon ces membres sont publics. Dans un souci de lisibilit, il est prfrable d'organiser la dclaration d'une classe en fonction de la visibilit, en plaant tous les membres privs ensemble, suivis de tous les membres protgs, etc. De cette manire, chaque mot rserv spcifiant la visibilit apparat au maximum une fois et marque le dbut d'une nouvelle "section" de la dclaration. Une dclaration de classe standard doit donc avoir la forme : type TMaClasse = class(TControl) private ... { dclarations prives} protected ... { dclarations protges } public ... { dclarations publiques } published ... { dclarations publies } end; Vous pouvez augmenter la visibilit d'un membre dans une classe drive en le redclarant, mais il n'est pas possible de rduire sa visibilit. Par exemple, une proprit protge peut tre rendue publique dans un descendant mais pas prive. De plus, les membres publis ne peuvent devenir publics dans une classe drive. Pour davantage d'informations, voir Surcharge et redclaration de proprits.

F.

Constructeurs et destructeurs

Comme pour les objets, la mmoire est alloue dynamiquement. Pour les pointeurs, on utilise linstruction new ou getmem lorsque lon veut allouer de la mmoire et dispose ou freemem pour la librer. Pour les objets, on utilise des mthodes spciales que lon appelle constructeur (que lon nomme gnralement create) et destructeur (que lon nomme gnralement destroy). Et au lieu de procedure et function comme pour les autres mthodes, on utilise constructor et destructor.

G.

Exemple

Revenons sur lexemple de la liste de chanes (page 61) avec une version objet

program strlst5; {$APPTYPE CONSOLE} uses dialogs;

Const nl=#10#13; max=100; type TtabStr =class nb:word; item:array [1..max] of string ; constructor Create ; procedure clear ; procedure add (chn:string ); procedure delete (num:word); procedure insert (num:word;chn:string ); procedure exchange (pos1,pos2:word); function getItem(Const Index: Integer): string ; function toutTexte : string ;
Delphi et Kilix

function Find(const S: string ; var Index: Integer): Boolean; procedure sort (); // les () sont facultatives comme pour end; // create et clear constructor TtabStr.Create () ; Begin Inherited Create; clear; End; procedure TtabStr.clear; Begin nb:=0 End; procedure TtabStr.add (chn:string ); Begin inc(nb); item[nb]:=chn; D. Mailliet

65

MIAGE 2me anne

End; procedure TtabStr.delete (num:word); var i :word; Begin for i:= num to nb do item[i]:=item[i+1]; dec(nb); End; procedure TtabStr.insert (num:word;chn:string ); var i :word; Begin inc(nb); for i:= nb downto num do item[i]:=item[i-1]; item[num]:= chn; End; procedure TtabStr.exchange (pos1,pos2:word); var tmp: string ; Begin tmp := item[pos1]; item[pos1]:= item[pos2]; item[pos2]:= tmp; End; function TtabStr.getItem(Const Index: Integer): string ; Begin result := item[Index]; End ; function TtabStr.toutTexte: string ; var indx : word; Begin result:=''; for indx:=1 to nb do result := result+nl+item[indx]; End ; function TtabStr.Find(const S: string ; var Index: Integer): Boolean;

{ Fonction qui recherche une chane S dans le tableau T la fonction renvoie - Vrai si S est dans T et le paramtre rsultat Index contient l'adresse - Faux sinon et index contient n'importe quoi} var i : word ; Begin // A crire ... End ; procedure TtabStr.sort (); {Trie les chanes du tableau en ordre croissant} Begin // A crire ... revoir le Qsort page 48 End; var maListe: TtabStr; BEGIN concat; maListe:= TtabStr.create; //Maintenant le constructeur initialise aussi nb. La 2me ligne clear est donc inutile. maListe.Add('premire ligne'); maListe.Add('deuxime ligne'); maListe.Add('toisime ligne'); ShowMessage('utilisation de la fonction :'+nl+nl+maListe.toutTexte); writeln( 'utilisation du champ : chane d''indice 1:'+nl+nl+maListe.item[1]); writeln; writeln('remarquer les lettres accentues en mode console et fentr'); ShowMessage('utilisation de la fonction :chane d''indice 1'+nl+nl+maListe.GetItem(1)); maListe.insert(3,'ligne 2 bis'); ShowMessage('utilisation de la fonction :'+nl+nl+maListe.toutTexte); maListe.exchange(1,3); ShowMessage('aprs utilisation de echange :'+nl+nl+maListe.toutTexte); maListe.delete(2); ShowMessage('aprs utilisation de delete :'+nl+nl+maListe.toutTexte); maListe.destroy END.

H.

Exemple dutilisation des objets prdfinis de delphi

1. Exemple 1 TStringList est une implmentation (plus efficaces) des listes de chanes de caractres en delphi . ( voir en particulier TStringList.CustomSort et find dans laide delphi)

program str_list; {$APPTYPE CONSOLE} uses classes,dialogs;


Delphi et Kilix

Const nl=#10#13; var maListe: TStringList; begin 66 D. Mailliet

MIAGE 2me anne

maListe:=TStringList.create; maListe.Add('premire ligne'); maListe.Add('deuxime ligne'); maListe.Add('toisime ligne'); writeln( 'utilisation de la proprit :'+nl+nl+maListe.Text); ShowMessage('utilisation de la proprit :'+nl+nl+maListe.Text); ShowMessage('utilisation de la fonction :'+nl+nl+maListe.GetText); 2. Exemple 2 program tst_form; uses Forms,stdctrls; var maForm:tform; MonBouton : TButton;

ShowMessage('chane d''indice 0 : '+nl+nl+maListe.Strings[0]); maListe.Text := 'tout le texte est chang'; ShowMessage('utilisation de la proprit :'+nl+nl+maListe.Text); ShowMessage('chane d''indice 0 : '+nl+nl+maListe.Strings[0]); end.

begin Application.Initialize; Application.CreateForm(TForm, maForm); maForm.visible := true; maForm.top:=30; Remarques et commentaires :

maForm.left:=100; maForm.height:=300; maForm.width:=400; maForm.caption := 'nouvelle fiche'; MonBouton := TButton.Create(maForm); with MonBouton do begin Parent := maForm; top := 20; left := 20; height := 20; width := 200; caption := 'nouveau bouton'; end; Application.Run; end.

Il ne sagit plus ici dune application console, mais un simple diteur et la compilation avec DCC32 suffisent. Cet exemple est donn dans un but pdagogique et ne correspond pas la faon dont on dveloppe des applications avec Delphi Application est une variable de type Tapplication dfinie automatiquement par Delphi. Les 3 lignes : Application.Initialize; Application.CreateForm(TForm, maForm); et Application.Run; seront automatiquement gnre par lEDI et feront partie du programme principal (fichier .DPR) menu :Projet/Voir le source Tapplication et Tform sont dfinis dans lunit Forms et Tbutton dans lunit stdctrls Nous aurions pu mettre maForm en facteur avec with comme cest fait pour monBouton Les proprits top, left, height, width, caption sont en gnral dfinies dans linspecteur dobjet (voir page 72) et non dans le code du programme : on peut leur donner une valeur numrique au clavier ou dplacer visuellement les objets Les coordonnes top et left du coin suprieur gauche sont donnes partir du coin suprieur gauche de lcran, celles du bouton partir du coin suprieur gauche de la fiche (le propriraire TButton.Create(maForm) et parent Parent := maForm) 3. Exemple 3

Reprenons lexemple 2 sans dclarer de variable MonBouton : program tst_form; uses Forms,stdctrls; var maForm:tform;
Delphi et Kilix

67

begin Application.Initialize; Application.CreateForm(TForm, maForm); maForm.visible := true; maForm.top:=30; maForm.left:=100; maForm.height:=300; D. Mailliet

MIAGE 2me anne

maForm.width:=400; maForm.caption := 'nouvelle fiche'; with TButton.Create(maForm) do begin Parent := maForm; top := 20; left := 20; 4. Exemple 4

height := 20; width := 200; caption := 'nouveau bouton'; end; Application.Run; end.

Cela se complique, si lon veut faire de mme avec la form : en effet, lobjet application gre automatiquement la cration et la destruction de la forme ainsi que de tous les objets crs par lapplication

program tst_form; {$APPTYPE CONSOLE} uses Forms,stdctrls; begin with Tform.create( nil ) do begin visible := true;

top:=30; left:=100; height:=300; width:=400; caption := 'nouvelle fiche'; end; readln; end.

Remarquons ici quil sagit dune application console et la prsence du readln. Sans ce Readln, labsence de Application.Initialize; Application.CreateForm(TForm, maForm); Application.Run; terminerait le programme ds la fin de la cration de la fiche et donc on ne verrait rien. Labsence de nom la fiche (pas de dclaration de variable) empche dy placer un lmnt visuel par exemp le un bouton comme prcdemment, faute de pouvoir nommer propritaire er parent.

I.

Constitution des fichiers DPR, DMF, PAS

Crons un nouveau projet. Nommons la fiche nouvelle fiche plaons y un bouton que lon nommera nouveau bouton , nous obtenons quelquechose comme ceci :

Un click droit sur cette fiche fait apparatre :

Choisissons voir comme du texte, nos observons le texte suivant :


Delphi et Kilix

68

D. Mailliet

MIAGE 2me anne

object Form1: TForm1 OldCreateOrder = False Left = 100 PixelsPerInch = 96 Top = 30 TextHeight = 13 Width = 400 object Button1: TButton Height = 300 Left = 20 Caption = 'nouvelle fiche' Top = 20 Color = clBtnFace Width = 200 Font.Charset = DEFAULT_CHARSET Height = 20 Font.Color = clWindowText Caption = 'nouveau bouton' Font.Height = -11 TabOrder = 0 Font.Name = 'MS Sans Serif' end Font.Style = [] end Si nous comparons lexemple prcdent, nous remarquons une hirarchie comparable lexemple 2 ci-dessus. Bien entendu, labsence de points-virgules et de := montre quil ne sagit pas de code delphi, mais de description des objets visuels : cest ce que contient le fichier .DFM (Delphi ForM)

X.
A.

Hirarchie des classes, hritage et surcharge


Dfinition

Nous avons dj parl des classes en expliquant qu'elles sont les types partir desquels sont dclars les objets. Ces classes ne sont pas simplement un ensemble dsorganis dans lequel on pioche : il existe une hirarchie. Cette hirarchie est base, comme les objets, sur un besoin simple : celui de ne pas rinventer constamment la roue. Les objets sont des structures pour la plupart trs complexes dans le sens o ils possdent un nombre important de mthodes, de variables et de proprits. Mettez-vous un instant la place d'un programmeur chevronn et imaginez par exemple tout ce qu'il faut pour faire fonctionner un simple bouton : il faut entre autres le dessiner, ragir au clavier, la souris, s'adapter en fonction des proprits. C'est une tche qui ncessite un volume impressionnant de code Pascal Objet. Prenons un autre composant, par exemple une zone d'dition : elle ragit galement au clavier et la souris. Ne serait-il pas intressant de pouvoir regrouper la gestion du clavier et de la souris un seul endroit pour viter de la refaire pour chaque composant (pensez qu'il existe des milliers de composants). De tels besoins de regroupement, il en existe normment. Pour cela, il existe la notion de hirarchie parmi les classes. Cette hirarchisation permet de regrouper dans une classe parent un certain nombre de proprits, de mthodes et de variables. Les classes qui auront besoin d'avoir accs ces fonctionnalits devront simplement descendre de cette classe, c'est--dire tre une classe descendante de cette classe parent . Le principe de la hirarchie des classes est en effet bas sur la relation parentdescendant. Chaque classe possde une seule et unique classe parente directe. Une classe peut avoir un nombre illimit de descendants. Lorsqu'une classe descend d'une autre classe, la premire possde absolument tout ce qui est dfini par la seconde : c'est l'hritage. La classe descendante est plus puissante que la classe parente dans le sens o de nouvelles mthodes, variables et proprits sont gnralement ajoutes ou modifies. On dit dans ce cas que lon drive la classe parente.
Delphi et Kilix

69

D. Mailliet

MIAGE 2me anne

Une telle hirarchie impose l'existence d'un unique anctre ultime qui n'a pas de parent : c'est la classe TObject (qui possde un nom quelque peu embrouillant). De cette classe descendent TOUTES les classes existantes sous Delphi, et ceci plus ou moins directement (toutes les classes ne sont pas des descendantes directes de TObject mais sont souvent des descendantes de descendantes de... de TObject . Cette dernire dfinit les mcanismes de base du fonctionnement d'un objet. Tous les objets sous Delphi sont d'une classe descendante de TObject, et possdent donc tout ce que d finit TObject, savoir le minimum. Voici (une partie de ) larbre reprsentant la hirarchie des classes Delphi: Dans lexemple des TtabStr, nous avons ajout un descendant Tobject (et donc un frre Tpersistent). TtabStr a donc immdiatement hrit des membres de la classe Tobject : nous avons dailleurs dans un premier temps utilis le constructeur create des Tobject avant de le surcharger pour obtenir un constructeur plus adapt. Nous remarquerons que TStringsList est un descendant de Tstrings et non de TList

B.

Exemple

Dans cet exemple, nous allons driver un Tlist pour raliser une liste de rels: unit U_ListReal; constructor tmaliste.create; (* ---------------------------------------------------Implmentation (partielle) d'une liste de begin Inherited Create; rels end; Sur le modle des TstringList ----------------------------------------------------*) destructor tmaliste.Destroy; interface uses classes; begin Inherited Destroy; end; type tmaliste =class(Tlist) constructor Create ; function tmaliste.Add(Item: real): Integer; destructor Destroy; var p :^real; function Add(Item: real): Integer; begin function getitem(Index:Integer):real ; // new(p); p^:=Item ; devrait tre dans la zone private procedure setitem(Index:Integer;Item: real); Result:= inherited add(p); end; // devrait tre dans la zone private private function tmaliste.getitem(index:Integer):real ; { Dclarations prives } protected begin result := real(inherited Items[index]^) ; { Dclarations protges } end ; public { Dclarations publiques } property Items[Index: Integer]:real read procedure tmaliste.setitem(Index:Integer;Item: getitem write setitem; real); begin real(inherited Items[index]^) := item published end; { Dclarations publies } end; end. implementation

C.

Suite de lexemple

Nous allons amliorer lexemple en fournissant une procdure de tri de la liste des rels ; Tout est prvu dans Delphi: Il suffit de dfinir une relation dordre par le biais dune fonction : laide de Delphi indique pour tList.sort : Trie la liste, en employant l'algorithme Tri Rapide (QuickSort) et en utilisant Compare comme fonction de comparaison. type TListSortCompare = function (Item1, Item2: Pointer): Integer; procedure Sort(Compare: TListSortCompare); Description

Delphi et Kylix

70

D. Mailliet

MIAGE 2me anne

La mthode Sort permet de trier les lments du tableau Items. Compare est une fonction de comparaison indiquant comment les lments sont ordonns. Compare renvoie < 0 si Item1 est infrieur Item2, 0 s'ils sont gaux et > 0 si Item1 est suprieur Item2. function cmpUp(Item1, Item2: Pointer): Integer; begin if(real(Item1^))>(real(Item2^)) then result := 1 else if (real(Item1^))=(real(Item2^)) then result := 0 else result := -1 end; function cmpDn(Item1, Item2: Pointer): Integer; begin result := -cmpUp(Item1, Item2); end; procedure tmaliste.triUp; begin sort(cmpUp) end; procedure tmaliste.triDn; begin sort(cmpDn) end;

D.

Mthodes statiques, virtuelles et dynamiques ou abstraites

Ceci sera vu plus loin dans ce cours (Notions avances sur les objets), mais pour plus dinformation consulter laide Delphi : Sommaire de laide/ Rfrence Pascal Objet/ Classes et objets/ Mthodes/ Liaisons de mthodes

XI. La programmation visuelle : lEDI et la VCL


A. Utilisation
Environnement de dveloppement intgr et la librairie de composants visuels. On les obtient directement par les onglets :

Ou par le menu voir/liste des composants :

Un click sur le composant et un click sur la forme permettent de le slectionner puis ensuite de le positionner.

Delphi et Kylix

71

D. Mailliet

MIAGE 2me anne

B.

Programme le plus simple avec lEDI

Il ny a aucun code crire : le simple fait douvrir une nouvelle application, de la compiler et de lexcuter, suffit crer un excutable ouvrant une fiche qui ragit aux vnements dagrandissement, dimensionnement, fermeture etc. Lexcutable produit quand mme une taille de 353 ko

C.

API Windows
WindowClass.lpszClassName := AppName; Result := RegisterClass(WindowClass) <> 0; end; { Crer la Class Window } function WinCreate: HWnd; var hWindow: HWnd; begin hWindow := CreateWindow(AppName, 'Fentre en Pascal Objet', ws_OverlappedWindow, cw_UseDefault, cw_UseDefault, cw_UseDefault, cw_UseDefault, 0, 0, HInstance, nil ); if hWindow <> 0 then begin ShowWindow(hWindow, CmdShow); UpdateWindow(hWindow); end; Result := hWindow; end; var AMessage: TMsg; hWindow: HWnd; begin if not WinRegister then begin MessageBox(0, 'l''enregistrement chou', nil , mb_Ok); Exit; end; hWindow := WinCreate; if hWindow = 0 then begin MessageBox(0, 'WinCreate a chou', nil , mb_Ok); Exit; end; while GetMessage(AMessage, 0, 0, 0) do begin TranslateMessage(AMessage); DispatchMessage(AMessage); end; Halt(AMessage.wParam); end.

Le programme suivant fait exactement la mme chose, mais nutilise que lAPI Windows :

program Window1; { Application Standard API Windows crite en Pascal Objet.Aucun code VCL inclu. Tout est fait au niveau de l'API Windows .Il faut quand mme inclure Windows et Messages!} uses Windows, Messages; const AppName = 'Window1'; function WindowProc(Window: HWnd; AMessage, WParam, LParam: Longint): Longint; stdcall; export; begin WindowProc := 0; case AMessage of wm_Destroy: begin PostQuitMessage(0); Exit; end; end; WindowProc := DefWindowProc(Window, AMessage, WParam, LParam); end;

{ enregistrer la Classe Window } function WinRegister: Boolean; var WindowClass: TWndClass; begin WindowClass.Style := cs_hRedraw or cs_vRedraw; WindowClass.lpfnWndProc := @WindowProc; WindowClass.cbClsExtra := 0; WindowClass.cbWndExtra := 0; WindowClass.hInstance := HInstance; WindowClass.hIcon := LoadIcon(0, idi_Application); WindowClass.hCursor := LoadCursor(0, idc_Arrow); WindowClass.hbrBackground := HBrush(Color_Window); WindowClass.lpszMenuName := nil ; Il est beaucoup plus long, mais il peut scrire avec un simple diteur et se compiler avec DCC32 : il ne prendra que 9,5 ko !!!soit 37 fois moins de place !!

XII. Composants usuels


Tous les composants ont une proprit name : celle-ci ne sera donc pas rpte chaque fois.
Delphi et Kylix

72

D. Mailliet

MIAGE 2me anne

Lors du placement dun composant sur la fiche, lEDI lui affecte automatiquement un nom (du style button1). Il est impratif dans un projet, de lui attribuer un nom significatif (du style monBouton).

A.
1.

La fiche : Composant "Form"


Caractristiques C'est LE composant conteneur classique qu'on utilise le plus souvent sans se rendre compte de cette fonctionalit

pourtant indispensable. 2. Quelques vnements pour form

Une fiche devient active quand elle obtient la focalisation, par exemple quand l'utilisateur clique dans la fiche

Delphi et Kylix

73

D. Mailliet

MIAGE 2me anne

Se produit la cration de la fiche.

procedure TForm1.test(Sender: TObject); begin showmessage('hello') end; La mthode test appel e par onActivate produira un affichage au dessus de la form La mme mthode appel e par onCreate produira un affichage avant que la form ne soit affiche.

Se produit quand la fiche est redessine.(trs souvent!) Se produit quand la fiche est affiche (c'est--dire quand la proprit Visible de la fiche prend la valeur True).

Autres vnements : Ils sont trs nombreux et dpendent normment du composant choisi! Il faut consulter laide: On clique sur lvnement dans linspecteur dobjet et on appuie sur F1

Delphi et Kylix

74

D. Mailliet

MIAGE 2me anne

Voici un petit tableau qui donne les caractristiques importantes des fiches. Ce genre de tableau sera rpt pour chaque composant dans la suite du chapitre. Fiche technique Icne Visibilit Conteneur (aucune) Visible. Oui

Les fiches ne se crent pas depuis la palette des composants, mais par une commande accessible par le menu "Fichier", choix "Nouveau..." puis "Fiche".. Cette fiche est alors ajoute au projet actuel (un projet doit tre ouvert). Pour effacer cette fiche, il faut aller dans le gestionnaire de projets (menu "Voir", choix "gestionnaire de projet") qui sera trait dans un futur chapitre consacr l'interface de Delphi. Pour voir la liste des fiches d'un projet, il faut utiliser la commande "Fiches..." du menu "Voir" ou le raccourci clavier Shift+F12. Ceci a pour effet de faire apparatre une liste des fiches :

Pour en faire apparatre une, slectionnez-la puis cliquez sur OK. Voici maintenant une liste des proprits intressantes connatre pour les fiches : Proprits BorderIcons Dcide des icnes prsentes dans la barre de titre de la fentre. Pour diter cette proprit, cliquez sur le + qui la prcde et modifier les sous-proprits de type boolen qui la composent (La proprit BorderIcons est en fait de type ensemble, vous dcidez de quel lment cet ensemble est constitu). o o o o BorderStyle biSystemMenu affiche le menu systme (en haut gauche). biMinimize affiche le bouton de rduction en icne. biMaximize affiche le bouton d'agrandissement maximal. biHelp affiche un bouton d'aide.

Permet de fixer le style de bordure de la fentre (style appliqu pendant l'excution de l'application seulement). o o o o bsDialog cre une bordure fixe standard. La fiche n'est pas redimensionnable. bsNone n'affiche pas de bordure. La fiche n'est pas redimensionnable. bsSingle affiche une bordure fine. La fiche n'est pas redimensionnable. bsSizeable affiche une bordure standard permettant de redimensionner la fiche. Les deux choix suivants servent crer des barres d'outils :

Delphi et Kylix

75

D. Mailliet

MIAGE 2me anne

o o Caption FormStyle

bsSizeToolWin est similaire bsSizeable, mais affiche une petite barre de titre. bsToolWindow est similaire bsSingle, mais affiche une petite barre de titre.

Permet de fixer le texte crit dans la barre de titre de la fentre. Permet de fixer le style de la fiche. Ce style, normalement fix fsNormal, est utilis principalement pour qu'une fiche reste affiche au premier plan (fsStayOnTop), ou pour crer une application MDI (fsMDIForm et fsMDIChild). Nous reparlerons de ce type d'application ultrieurement. Permet de fixer une icne pour cette fiche. Utiliser le bouton de pour l'diter et charger une icne (fichier .ICO). Cette icne est affiche dans sa barre de titre, gauche, et lorsque la fentre est rduite en icne dans la barre des tches. Note : il est aussi possible de fixer une icne pour l'application, qui est affiche dans la barre des tches et pour les raccourcis vers les applications cres sous Delphi. Utilisable depuis le code seulement, cette proprit, de type numr, permet de fermer une fiche montre par la mthode ShowModal en lui attribuant une constante non nulle. Cette valeur est alors renvoye par la mthode ShowModal. Le mcanisme des fentres modales est expliqu ci-dessous. Permet de fixer la position de la fiche. Utilisez une des valeurs proposes pour donner une position standard la fiche. Trop de possibilits tant offertes pour tre listes ici, vous pouvez les consulter dans l'aide en ligne en appuyant sur F1 aprs slection de la proprit (ce qui est d'ailleurs valable avec toutes les autres proprits, mais donne parfois des explications confuses ou imprcises). A manipuler depuis le code source, cette proprit permet de rendre une fiche visible ou invisible. Prfrez cependant l'utilisation des mthodes Show et ShowModal. Permet de fixer l'tat de la fentre : o o o wsMaximized : donne la taille maximale la fentre (mme effet que le clic sur le bouton d'agrandissement). wsMinimized : rduit la fentre en icne (mme effet que le clic sur le bouton de rduction en icne). wsNormal : redonne la fentre son tat normal, savoir non maximis et non icnise. vnements

Icon

ModalResult

Position

Visible WindowState

OnActivate

OnClick OnClose

OnCloseQuery

OnDeactivate OnHide OnResize

OnShow

Se produit chaque fois que la fiche est active, c'est--dire lorsqu'elle tait inactive (bordure souvent grise) et qu'elle devient active (bordure colore). Une fiche est galement active lorsqu'elle devient visible et lorsqu'elle est la fiche active de l'application et que celle-ci devient active. Permet de ragir au clic de la souris, vous connaissez dj bien cet vnement pour l'avoir dj expriment avec les boutons. Il fonctionne avec de trs nombreux composants. Se produit lorsque la fiche se ferme, c'est--dire lorsqu'elle devient invisible ou que sa mthode Close est appele. Le paramtre Action transmis permet certaines manipulations. Nous utiliserons cet vnement lorsque nous crerons un "splash-screen" lors d'un futur exemple. Se produit AVANT qu'une fiche soit ferme. Vous avez la possibilit de modifier un paramtre (CanClose) qui autorise ou non la fermeture de la fiche. On utilise souvent cet vnement dans les formulaires pour vrifier la validit des informations entres par l'utilisateur et ventuellement lui indiquer d'effectuer certaines corrections. Contraire de OnActivate. Se produit lors d'une dsactivation de la fiche. Se produit lorsque la fiche est cache, c'est--dire lorsque sa proprit Visible passe de True False. Se produit chaque fois que les dimensions de la fiche changent. Cet vnement permet ventuellement de mettre jour certaines dimensions de composants pour maintenir un effet visuel. Se produit lorsque la fiche est montre, c'est--dire lorsque sa proprit Visible passe de False True. Cet vnement se produit notamment lorsque la mthode Show ou ShowModal de la fiche est appele. Mthodes 76 D. Mailliet

Delphi et Kylix

MIAGE 2me anne

Close Show ShowModal 3.

Ferme la fiche. Vous pouvez obtenir le mme effet en fixant la proprit Visible False. Montre une fiche. Vous pouvez obtenir le mme effet en fixant la proprit Visible True. Montre une fiche, en la rendant modale. Une fentre modale reste visible jusqu' ce que sa proprit ModalResult soit diffrente de 0. Les fentres modales sont abordes ci-dessous.

Modales ou non ?

Les fentres modales sont une possibilit intressante de Delphi. Une fentre devient modale lorsqu'elle est montre au moyen de sa mthode ShowModal. On la ferme ensuite au choix en fixant une valeur non nulle sa proprit ModalResult, ou en appelant sa mthode Close qui, en fait, affecte la valeur constante "mrCancel" (valeur 2) ModalResult. Cette proprit permet de renseigner sur les circonstances de fermeture de la fentre, ce qui est souvent trs utile. Une fentre modale se distingue en outre d'une fentre normale par le fait qu'elle doit tre referme avant de pouvoir continuer utiliser l'application. Une utilisation classique en est faite pour crer des boites de dialogue : ces dernires doivent tre refermes avant de pouvoir continuer travailler dans l'application (prenez la boite de dialogue "A propos de..." de Delphi par exemple). La proprit ModalResult ferme donc une fiche modale lorsqu'elle est fixe diffrente de 0. Mais c'est une proprit de type numr, c'est--dire que ses valeurs sont prises parmi un jeu d'identificateurs ayant des noms significatifs. Pour fermer une fiche en donnant une information sur les circonstances de fermeture de la fiche (OK, annulation, ...), on pioche parmi ces valeurs. Voici une liste de valeurs possibles pour ModalResult (la valeur numrique, qui n'a aucune signification, est donne titre indicatif entre parenthses) : o o o o o o o o mrNone (0) : valeur prise par ModalResult lorsque ShowModal est appele. mrOk (1) : signifie que l'utilisateur a valid par un "OK" (ou tout autre moyen qui signifie "OK"). mrCancel (2) : signifie que l'utilisateur a annul. mrAbort (3) : signifie que l'utilisateur a abandonn. mrRetry (4) : signifie que l'utilisateur souhaite ressayer quelque chose (c'est vous de dterminer quoi !). mrIgnore (5) : signifie que l'utilisateur souhaite ignorer. mrYes (6) : signifie que l'utilisateur a rpondu par l'affirmative une question. mrNo (7) : signifie que l'utilisateur a rpondu par la ngative une question.

Toutes ces valeurs ne sont bien videmment pas appropries dans toutes les situations, elles permettent juste de couvrir un large ventail de circonstances standards de fermeture : souvent seules les valeurs mrOK et mrCancel sont significatives et signifient souvent que l'utilisateur a cliqu sur un bouton "OK" ou "Annuler".

B.

Composant "MainMenu"
Fiche technique Icne Visibilit Conteneur Invisible la cration, visible ensuite. Non

Ce composant permet de munir la fiche d'une barre de menus droulants comme vous en utilisez trs souvent. Ce composant est non visuel lorsqu'on vient de le poser sur une fiche : au lieu d'un composant visible, l'icne du composant vient se placer sur la fiche. A partir de son pseudo-bouton, vous pouvez accder via un double-clic une interface spcifique de cration de menus. Cette interface permet de crer directement de faon visuelle les menus en utilisant l'inspecteur d'objets et quelques raccourcis clavier. Cette interface permet en fait d'diter la proprit "Items" du composant (en slectionnant la proprit, puis en cliquant sur le bouton la mme chose). qui permet d'diter des proprits complexes, vous accdez

Les proprits importantes du composant "MainMenu" sont dcrites ci-dessous : Proprits Images Items Rfrence un composant "ImageList". Permet d'associer un menu une liste d'images stockes dans un composant "ImageList". Proprit objet. Permet l'accs l'diteur de menus.

Delphi et Kylix

77

D. Mailliet

MIAGE 2me anne

C.

Composant "TPopupMenu"
Fiche technique Icne Visibilit Conteneur Invisible la cration, peut tre visible l'excution Non

Ce composant permet de crer un menu contextuel. Les menus contextuels ont ceux qui apparaissent lorsqu'on clique avec le bouton droit de la souris. Ce genre de menu doit son nom au fait qu'il semble adapt la zone sur laquelle on clique. En fait, il faut souvent dans la pratique crer plusieurs menus contextuels et les adapter ventuellement (en activant ou dsactivant, ou en cachant ou en montrant certains choix) pendant l'excution de l'application. La cration de ce menu se fait dans le mme genre d'interface que les menus principaux ("MainMenu"). Proprits Alignment Images Items Spcifie l'alignement du menu par rapport l'endroit o le clic droit a eu lieu. "paLeft" est la valeur habituelle et par dfaut. Rfrence un composant "ImageList". Permet d'associer au menu une liste d'images stockes dans un composant "ImageList". Proprit objet. Permet l'accs l'diteur de menus. vnements Se produit juste avant que le menu contextuel soit montr. Utiliser une procdure rpondant cet vnement pour dcider ce moment de l'apparence du menu (lments (in)visibles, (ds)activs, cochs, ...) Mthodes Permet d'afficher directement le menu contextuel. Vous devez spcifier des coordonnes X et Y dont la signification varie suivant la valeur de la proprit "Alignment"

OnPopup

Popup

Pour utiliser un menu contextuel, il faut l'associer chaque composant qui doit le faire apparatre. Ceci est fait en slectionnant le menu dans la proprit "PopupMenu" (proprit de type rfrence) des composants (une trs grande majorit le proposent).

D.

Composant "Label"
Fiche technique Icne Visibilit Conteneur Visible Non

Un composant "Label" permet d'inclure facilement du texte sur une fiche. Ce texte n'est pas ditable par l'utilisateur et c'est donc un composant que l'on utilise souvent comme tiquette pour d'autres contrles. Bien que l'on puisse modifier la police utilise pour l'criture du texte, il faut toujours freiner ses ardeurs. Ces composants sont en gnral en grand nombre sur les fiches importantes, mais cela ne pose pas de problme car ils ne prennent presque pas de mmoire. Remarque : Les composants "Label" ne sont pas des vrais objets au sens de Windows : ils ne possdent pas de Handle. Ces composants sont en effet directement dessins sur le canevas de la fiche. Pour utiliser un Label avec un Handle (utile avec ActiveX), il faut utiliser le composant "StaticText". Un composant "Label" peut contenir jusqu' 255 caractres, ce qui le limite des textes trs courts. Les proprits "AutoSize" et "WordWrap" permettent d'obtenir une bande de texte largeur fixe sur plusieurs lignes, ce qui sert souvent pour donner des descriptions plus toffes que de simp les tiquettes. Les composants "Label" sont trs souvent utiliss et le seront donc dans les manipulations futures. 78 D. Mailliet

Delphi et Kylix

MIAGE 2me anne

Proprits Alignment Permet d'aligner le texte droite, au centre ou gauche. N'est utile que lorsque "AutoSize" est faux et qu'une taille diffrente de celle propose a t choisie. Le texte s'aligne alors correctement. Active ou dsactive le redimensionnement automatique du Label. "true" ne permet qu'une seule ligne, avec une taille ajuste au texte prsent dans le label, tandis que "false" permet plusieurs lignes, non ajustes au contenu du label. Permet de spcifier le texte afficher dans le label. Rfrence un autre contrle. Cette proprit permet de choisir le composant qui reoit le focus (qui est activ) lorsqu'on clique sur le label. Cette proprit permet un certain confort l'utilisateur puisqu'un clic sur une tiquette pourra par exemple activer le composant tiquet. Alter-ego vertical de "Alignment". Permet de montrer ou de cacher le label. Cette proprit fait partie des grands classiques qui ne seront plus repris dans la suite. Autorise les retours la ligne pour permettre d'afficher plusieurs lignes l'intrieur du label. "AutoSize" doit tre faux pour permettre l'utilisation de plusieurs lignes.

AutoSize

Caption FocusControl

Layout Visible WordWrap

E.

Composant "Edit"
Fiche technique Icne Visibilit Conteneur Visible Non

Les composants "Edit" permettent de proposer des zones d'dition. Ces zones trs souvent utilises sous Windows ne contiennent qu'une ligne de texte, dont la police peut tre rgle, toujours avec la mme parcimonie. Ce composant permet l'utilisateur d'entrer une information quelconque tape au clavier. Le texte entr dans le composant est accessible via une proprit "Text". Il est possible de fixer une limite la longueur du texte entr, de masquer les caractres (utile pour les mots de passe), de dsactiver la zone ou d'interdire toute modification du texte. Proprits AutoSelect Permet l'autoslection du contenu lors de l'activation : lorsque le contrle devient actif, le texte est slectionn, de sorte qu'il peut directement tre modifi en tapant un nouveau texte. Utiliser cette fonction dans les formulaires peut faire gagner un temps prcieux. Active ou dsactive la zone d'dition (l'dition n'est possible que lorsque la zone est active). Permet de fixer le nombre maximal de caractres entrs dans la zone. Mettre 0 pour ne pas donner de limite (par dfaut). A utiliser lorsqu'on veut masquer les caractres taps, comme pour les mots de passe. Utiliser le caractre "*" pour masquer (le plus souvent utilis) et "#0" (caractre n0) pour ne pas masquer. Permet d'active la lecture seule de la zone d'dition. Lorsque "ReadOnly" vaut "true", la lecture est toujours possible mais l'criture impossible. Contient le texte entr dans la zone d'dition. C'est aussi en changeant cette proprit que l'on fixe le contenu de la zone. vnements Se produit lorsqu'un changement de texte est susceptible de s'tre produit, c'est--dire lorsque le texte s'est effectivement produit, mais aussi dans certaines autres circonstances. La proprit "Modified" de type boolen permet de tester depuis la procdure de rponse aux vnements si une modification du texte a eu lieu. Lors de l'excution de la procdure associe cet vnement, la proprit "Text" est dj modifie et vous pouvez connatre le nouveau contenu en consultant cette proprit. Conseil : veillez ne pas crire de code trop long excuter dans la procdure de rponse cet vnement, car il se produit assez souvent lorsqu'un utilisateur remplit un formulaire constitu de quelques zones d'dition par exemple.
Delphi et Kylix

Enabled MaxLength PasswordChar

ReadOnly Text

OnChange

79

D. Mailliet

MIAGE 2me anne

F.

Composant "Memo"
Fiche technique Icne Visibilit Conteneur Visible Non

Le composant "Memo" permet l'dition de texte sur plusieurs lignes. Une utilisation clbre de ce composant est faite par le bloc-notes de Windows. Ce composant ne traite pas la mise en forme des caractres comme dans WordPad (pour cela, un autre composant, "RichEdit", est tout indiqu). Le composant "Memo", plac sur une fiche, permet donc lors de l'excution, d'crire du texte, d'ajouter des lignes en appuyant sur Entre, d'diter facilement ce texte (les fonctionnalits de copier-coller ne sont cependant pas automatiques et vous devrez apprendre les programmer, j'essaierai de traiter un exemple d'utilisation du presse-papier dans un futur chapitre, il est encore un peu tt pour cela). Concrtement, un mmo stocke le texte sous formes de lignes : chaque ligne est une chane de caractres. La proprit objet "Lines" des composants "Memo" permet l'accs aux lignes du mmo et leur manipulation. L'interface de Delphi permet mme d'crire directement dans le mmo en ditant la proprit "Lines". Proprits Align Permet d'aligner le mmo gauche, droite, en haut, en bas, ou en prenant toute la place du composant qui le contient (la fiche, ou un autre composant conteneur). Ceci permet au mmo de mettre jour automatiquement certaines de ses dimensions lorsque c'est ncessaire. Pendant l'excution de l'application, permet d'accder aux lignes du mmo, c'est--dire tout le texte qui y est crit. Lines possde une proprit tableau par dfaut qui permet de rfrencer les lignes par Lines[x] ou x est le n de ligne. Lines possde galement une proprit Count qui donne le nombre de lignes. Les lignes sont numrotes de 0 Count-1. Permet d'interdire la modification du texte du mmo (en fixant la valeur True). Autorise l'utilis ateur utiliser des tabulations l'intrieur du mmo. Bien qu'intressante, cette possibilit l'empche de sortir du mmo en utilisant la touche Tab comme il le fait avec d'autres contrles (je ne crois pas avoir auparavant expliqu qu'un composant est nomm "contrle" lors de l'excution) tels les boutons. Permet les retours la ligne automatique comme dans le bloc-note de Windows : lorsque WordWrap vaut True, les lignes trop longues sont dcoupes en plusieurs de faon ce que la largeur du texte colle avec celle du mmo. Ceci ne modifie en rien les lignes du mmo, car c'est une option visuelle seulement. Par dfaut, WordWrap vaut False et les lignes trop longues sont non dcoupes. vnements Analogue l'vnement OnChange des composants Edit.

Lines

ReadOnly WantTabs

WordWrap

OnChange

G.

Composant "Button"
Fiche technique Icne Visibilit Conteneur Visible Non

Pas vraiment besoin de prsenter longuement ici le composant Button : vous vous en servez depuis un bon moment si vous suivez ce guide depuis le dbut. Ce comp osant sert en gnral proposer l'utilisateur une action. Cette action lui est explique par un texte trs court sur le bouton, du style "OK" ou "Annuler". Lorsque l'utilisateur clique sur le bouton, ou appuie sur Espace ou Entree lorsque celui-ci est slectionn (ce qui revient le cliquer), l'vnement OnClick se produit, qui offre une possibilit de raction. C'est en gnral dans la procdure de rponse cet vnement qu'on effectue l'action propose l'utilisateur, comme afficher ou fermer une fiche par exemple pour citer des exemples rcents. Les boutons ont une fonctionnalit en rapport avec les fentres modales : ils ont une proprit ModalResult. Cette proprit ne fonctionne pas du tout comme celle des fiches. Elle est constante (fixe par vous), et est recopie dans la proprit ModalResult de la fiche lors d'un clic sur le bouton. Ceci a comme effet de pouvoir crer un bouton "OK" rapidement en lui donnant "mrOK" comme ModalResult. Lors d'un clic sur ce bouton, la proprit ModalResult de la fiche
Delphi et Kylix

80

D. Mailliet

MIAGE 2me anne

devient mrOK et la fiche se ferme donc, sans aucune ligne de code source crite par nous. Nous utiliserons cette possibilit dans de futurs exemples. Proprits Cancel Lorsque Cancel vaut True, un appui sur la touche Echap a le mme effet qu'un clic sur le bouton (lorsque la fiche est active). Cette fonction rserve au bouton "Annuler" permet d'utiliser le raccourci clavier Echap pour sortir de la fiche. Texte du bouton. Une seule ligne est autorise. Si le texte est trop long, seule une partie est visible sur le bouton. Analogue de Cancel mais avec la touche Entre. Cette fonction est en gnral rserve au bouton "OK" de certaines fiches trs simples que la touche Entre suffit alors refermer (pensez tout simplement aux messages affichs par ShowMessage. Mme si l'on utilise pas explicitement de fiche, c'est bel et bien une fiche qui est employe avec un bouton "OK" avec sa proprit "Default" fixe True). Comme pour beaucoup de composant, Enabled dcide si le bouton est utilisable ou non. Permet de modifier automatiquement la proprit ModalResult de la fiche contenant le bouton lors d'un clic et si la fiche est modale. La gestion de l'vnement OnClick devient parfois inutile grce cette proprit. vnements Permet de rpondre au clic sur le bouton. Cet vnement se produit aussi lorsque le bouton est actif et que la touche Entre ou Espace est enfonce, ou lorsque la touche Echap est enfonce et que la proprit Cancel vaut True, ou lorsque la touche Entre est enfonce et que la proprit Default vaut True. L'appel de la mthode Click dclenche aussi cet vnement. Mthodes La mthode Click copie la proprit ModalResult du bouton dans celle de sa fiche, et dclenche un vnement OnClick. C'est la mthode appeler lorsqu'on doit dclencher l'vnement OnClick depuis le code source.

Caption Default

Enabled ModalResult

OnClick

Click

H.

Composant "CheckBox"
Fiche technique Icne Visibilit Conteneur Visible Non

Un composant CheckBox permet de donner l'utilisateur un choix de type "Oui/Non". S'il coche la case, la rponse est "Oui", sinon, c'est "Non". Au niveau du code, une proprit de type boolen stocke cette rponse : Checked. Il est possible de donner un texte explicatif de la case cocher dans la proprit Caption. Ce texte apparait cot de la case. Une modification de l'tat de la case dclenche un vnement OnClick, que cette modification provienne effectivement d'un clic ou d'une pression sur la touche Espace. La modification depuis le code source de la proprit Checked ne dclenche pas cet vnement. Proprits Caption Permet de spcifier le texte qui apparait cot de la case cocher. Il est noter que le composant ne se redimensionne pas pour afficher automatiquement tout le texte. Ce sera donc vous de prvoir cela si c'est ncessaire. Permet de connatre ou de modifier l'tat de la case : coche ou pas. vnements Dclench lorsque l'tat de la case cocher change, quelle que soit l'origine du changement. La proprit Checked est dj mise jour lorsque la procdure de rponse cet vnement s'excute.

Checked

OnClick

Delphi et Kylix

81

D. Mailliet

MIAGE 2me anne

XIII. Programmation vnementielle et envoi de messages


A. Dfinition
On voit ci-dessus que les objets des diffrents composants (visuels ou non) ragissent lorsquune action extrieure intervient : par exemple appuis sur une touche du clavier, dplacement de la souris, top de lhorloge interne ou toute autre interruption matrielle ou non. Lorsquun vnement survient, un message est envoy aux procdure de gestion dvnements avec les caractristiques de lexpditeur du message. Bien souvent, on ne se proccupe pas de lexpditeur, on indique dans linspecteur dobjets longlet vnement (par un double-clic) le nom de la mthode charge de le grer.

B.

Exemple

Crons une fiche avec 2 boutons appels (proprit name) respectivement Button1 et Button2 et comportant tous deux la mme inscription : Appuyez ici (proprit caption). De plus la proprit visible de lun est true et de lautre est false. On fera un double-clic indique dans linspecteur dobjets longlet vnement pour chaque bouton sur lvnement OnMouseMove Le but du programme est de rendre invisible le bouton sur lequel lutilisateur essaye de cliquer et de rendre lautre visible :

unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls, ComCtrls, ExtDlgs; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer); procedure Button2MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer); private { Dclarations prives } public { Dclarations publiques } end; var

Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin button1.visible := false; button2.visible := true end; procedure TForm1.Button2MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin button2.visible := false; button1.visible := true end; end.

C.

Rponse un vnement

Reprenons lexemple (page 67)de cration dynamique dune forme et dun bouton et ajoutons-lui une raction un click :

program tst_form; uses Forms, stdctrls, dialogs; type bidon=class


Delphi et Kilix

procedure repondre(expediteur : tobject); end; procedure bidon.repondre(expediteur : tobject); 82 D. Mailliet

MIAGE 2me anne

begin showmessage ('ok') end; var maForm:tform; gamelle: bidon; begin Application.Initialize; Application.CreateForm(TForm, maForm); maForm.visible := true; maForm.top:=30; maForm.left:=100; maForm.height:=300;

maForm.width:=400; maForm.caption := 'nouvelle fiche'; with TButton.Create(maForm)do begin Parent := maForm; top := 20; left := 20; height := 20; width := 200; caption := 'nouveau bouton'; onclick := gamelle.repondre; end; Application.Run; end.

La gestion dun vnement se fait par une mthode (et non une simple procdure) ce qui explique la cration dune classe bidon instancie par lobjet gamelle . En Ralit, la mthode fait partie de la classe cre spcialement et qui ragit lvnement qui lui correspond !

D.

Retour sur les fichiers DFM

Lexemple prcdent, sil est correct, nest pas propre : fabriquer une clase bidon pour traiter un vnement nest pas des plus lisible. Il vaut mieux crer une classe englobant la fiche, le bouton et le traitement de lvnement comme suit : program Project2; Application.Initialize; Application.CreateForm(TmaForm, maForm); maForm.visible := true; uses Forms, stdctrls, dialogs; maForm.top:=30; maForm.left:=100; type TmaForm=class(tform) maForm.height:=300; monbouton : TButton; maForm.width:=400; procedure repondre(expediteur : tobject); maForm.caption := 'nouvelle fiche'; end; maForm.monbouton:= TButton.Create(maForm); procedure TmaForm.repondre(expediteur : with maForm.monbouton do begin tobject); Parent := maForm; top := 20; begin showmessage ('ok') left := 20; end; height := 20; width := 200; caption := 'nouveau bouton'; var maForm:TmaForm; onclick := maForm.repondre; end; {$R prj.dfm} Application.Run; end. begin On remarquera la prsence de {$R prj.dfm} (ou de {$R *.dfm} sil ny a pas de confusion possible). Le fichier prj.dfm est un simple fichier texte comportant : object maForm: TmaForm end Il contient presque rien, mais il est Obligatoire !ceci est mettre en relation avec le chapitre sur Constitution des fichiers DPR, DMF, PAS

E.

Exemple pratique : bouton double fonctionnalit

Le but est de du programme est de changer la fonctionnalit dun bouton : par exemple, on souhaite mettre jour une liste quelconque et lon dispose dun bouton intitul (caption ) ajouter sur lequel on peut cliquer. Le mme bouton permet de valider la mise jour son intitul se transformant en valider. Bien entendu chaque intitul, correspond une fonctionnalit diffrente entranant un traitement diffrent. Entre autre, 3 solutions soffrent nous :

Delphi et Kylix

83

D. Mailliet

MIAGE 2me anne

1.

1 Bouton 1 vnement

Dans lexemple qui suit, on a un bouton, et lon teste son intitul : Attention, il faut faire attention la chasse (Majuscule / Minuscule) des captions. Selon son titre, le traitement seffectue selon le cas 1 ou 2.

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Dclarations prives } public { Dclarations publiques } end; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin with button1 do begin if caption='Ajouter' then begin caption:='Valider'; //traitement cas 1 end else begin caption:= 'Ajouter'; //traitement cas 2 end; end; end; end.

var Form1: TForm1; Il ny a quun seul bouton, lutilisateur ne voit quun bouton dont lintitul change et qui ragit en consquence. 2. 2 Boutons 2 vnements Ici, on utilise 2 boutons que lon cache (proprit visible) alternativement.

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button2Click(Sender: TObject); private { Dclarations prives } public { Dclarations publiques } end; var Form1: TForm1; implementation
Delphi et Kylix

{$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin button2.Width:=button1.Width; button2.Top:=button1.Top; button2.Left :=button1.Left; button2.Height:=button1.Height; button2.Visible:=false; end; procedure TForm1.Button1Click(Sender: TObject); begin button2.Visible:=True; button1.Visible:=false; //traitement cas 1 end; procedure TForm1.Button2Click(Sender: TObject); begin button1.Visible:=True; button2.Visible:=false; 84 D. Mailliet

MIAGE 2me anne

//traitement cas 2 end;

end.

Lutilisateur toujours limpression de ne voir quun seul bouton, car le programmeur, qui a plac le second nimporte o sur la fiche, a pris soin dans lvnement FormCreate de donner au button2 les mmes caractristiques que button1 . Et donc lutilisateur le voit apparatre au mme endroit et croit que cest le mme bouton dont seul le titre a chang. Lavantage de cette deuxime solution est dviter de faire un test pour savoir dans quel cas lon se trouve. Linconvnient est davoir un objet (bouton) supplmentaire. 3. 1 Bouton 2 vnements

Dans cette troisime solution, on ne manipule quun seul bouton, mais chaque click entrane un changement de gestionnaire dvnement OnClick du button1 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click1(Sender: TObject); procedure Button1Click2(Sender: TObject); private { Dclarations prives } public { Dclarations publiques } end; var Form1: TForm1; implementation 4. Conclusion {$R *.dfm} procedure TForm1.Button1Click1(Sender: TObject); begin with button1 do begin OnClick:=Button1Click2; caption:= 'Valider'; end; //traitement cas 1 end; procedure TForm1.Button1Click2(Sender: TObject); begin with button1 do begin OnClick:=Button1Click1; caption:= 'Ajouter'; end; //traitement cas 2 end; end.

Les 3 solutions se valent, seules les techniques diffrent. La premire est la plus compacte, mais souffre de 2 inconvnients dus au if : Les 2 traitements sont dans la mme mthode sparation des taches moins vidente donc lisibilit moindre.

Le test sur les caption doit absolument respecter la chasse des caractres : par exemple si la caption vaut Valider et que le test se fait sur valider, celui-ci vaudra false !.

XIV. vnements et Envoi de messages


Un vnement est une action ou une occurrence dtecte par un programme. La plupart des applications modernes sont dites pilotes par vnements, car elles sont conues pour rpondre des vnements. Dans un programme, le programmeur na aucun moyen de prvoir la squence exacte des actions que va entreprendre lutilisateur. Il peut choisir un lment de menu, cliquer sur un bouton ou slectionner du texte. Vous allez donc crire le code qui gre chacun des vnements qui vous intressent au lieu dcrire du code sexcutant toujours selon le mme ordre.

A.

Evnements utilisateur

Les vnements utilisateur sont des actions inities par lutilisateur. Les vnements utilisateur sont, par exemple, OnClick (lutilisateur a cliqu avec la souris), OnKeyPress (lutilisateur a appuy sur une touche du clavier) et OnDblClick

Delphi et Kylix

85

D. Mailliet

MIAGE 2me anne

(lutilisateur a double-cliqu sur un bouton de la souris). Ces vnements sont toujours rattachs une action de lutilisateur.

B.

Evnements systme

Ce sont des vnements que le systme dexploitation dclenche pour vous. Par exemple, lvnement OnTimer (le composant Timer dclenche lun de ces vnements lorsquun intervalle prdfini sest coul), lvnement OnCreate (le composant est en train dtre cr), lvnement OnPaint (un composant ou une fentre a besoin dtre redessin), etc. En rgle gnrale, ces vnements ne sont pas directement dclenchs par des actions de lutilisateur.. Toutes les classes Delphi disposent dun mcanisme intgr pour grer les messages : ce sont les mthodes de gestion des messages ou gestionnaires de messages. Lide sous-jacente aux gestionnaires de messages est la suivante : un objet reoit des messages quil rpartit selon le message en appelant une mthode choisie dans un ensemble de mthodes spcifiques. Un gestionnaire par dfaut est appel si aucune mthode nest dfinie pour le message. Le diagramme suivant illustre le fonctionnement du systme de rpartition de message : EvnementMainWndProcWndProcDispatchGestionnaire Exemple 1 La procedure AppMessage dfinie ci-dessous capture tous les vnements OnMessage de l'application. Attention cette procdure est appele pour chaque message si vous n'y prenez garde, elle peut ralentir votre application les messages arrivent mme s'ils sont destins une autre fentre que la fentre principale (essayez dans la fentre du ShowMessage) }

Type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private procedure AppMessage( var Msg: TMsg; var Handled: Boolean); end; Var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); {----------------------------------------------------affectation de AppMessage en temps que procdure dclenche par OnMessage ------------------------------------------------------} begin Application.OnMessage := AppMessage; end; procedure TForm1.AppMessage( var Msg: TMsg; var Handled: Boolean); { procdure lance par chaque vnement Affectez la valeur True Handled si le message a t compltement gr afin d'empcher le traitement normal du message. } begin if (Msg.message =WM_KEYDOWN) then ShowMessage('message WM_KEYDOWN dans AppMessage') else if (Msg.message =WM_RBUTTONDOWN) then ShowMessage('message WM_RBUTTONDOWN dans AppMessage'); { handled=true; aurait empch la suite du traitement normal du message: il n'aurait donc pas t trait par WindProc} end; Dclaration dune mthode spcifique pour le traitement du messageu envoy lors dun click droit sur la souris Type TForm1 = class(TForm) Panel1: TPanel;
Delphi et Kylix

86

D. Mailliet

MIAGE 2me anne

private procedure SourisCliqueDroit( var msg:TMessage); message WM_RBUTTONDOWN; end; Var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.SourisCliqueDroit( var msg:TMessage); begin ShowMessage('Message dtect dans SourisCliqueDroit'); inherited ; // si on veut continuer propager le message end; Le message est envoy par la Tform1 et non par les objets qui lui appartiennent Un clic droit dans le panel1 nen envoie pas ! Const WM_MESSAGEPERSO = WM_USER + 1; { le 1 peut tre remplac par le nombre de votre choix ne pas utiliser le mme nombre pour un autre message } type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private procedure WMMessagePerso(var Msg : TMessage); message WM_MESSAGEPERSO; // procdure destine recevoir notre messageend; Var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); begin SendMessage(Form1.Handle, WM_MESSAGEPERSO,0,0); //envoi de notre message Form1 end; procedure TForm1.WMMessagePerso(var Msg : TMessage); begin ShowMessage('Message Perso reu par WMMessagePerso'); end;

Sur une forme, un bouton et un panel procedure TForm1.Button1Click(Sender: TObject); begin Panel1.Color:=clRed; sleep(3000); // delays 3000 msec Panel1.Color:=clGreen; end;

procedure TForm1.Button1Click(Sender: TObject); begin Panel1.Color:=clRed; Application.ProcessMessages;


Delphi et Kylix

On pourrait esprer que le clic sur le bouton entrane une coloration rouge du panel pendant 3 secondes et quensuite, il devienne vert. Il nen est rien car la mthode repaint ne sera appel e quen sortie de procdure : le message envoy est captur et trait par cette procdure qui ne rend la main que lorsquelle a fini. Et donc le vert vient recouvrir immdiatement le rouge que lil na pas le temps de percevoir La solution consiste laisser passer les messages D. Mailliet

87

MIAGE 2me anne

End

sleep(3000); // delays 3000 msec Panel1.Color:=clGreen;

XV. Exemple rcapitulatif


Il sagit de raliser un programme simulant une calculatrice conforme aux spcifications du TP2, mais il ne s agit pas dun corrig dans la mesure ou le cours ntait pas suffisemment avanc pour fournir une rponse de cette nature .

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, QControls, Forms, Dialogs, StdCtrls, ExtCtrls, Controls; type tbbout = class private nl,nc :byte; proprio:tcomponent; public tb : array of array of TButton; constructor create(nl,nc:byte;proprio:tcomponent;tt:TNotifyEvent; kp:TKeyPressEvent); procedure dimensionne; end; Calculatrice = class private Op1,Op2 : Extended;//Operandes de l'entree en cours Operation : char;//stocke l'operation demande parmi {+,-,/,*} entree_en_cours : string ; nbop:byte; public constructor create; Function Gere_chif(Chaine: string ) : string ; Function Gere_oper(Chaine: string ) : string ; Procedure Clear;//Efface tous les champs aprs operation Function ExecOperation : Extended; end; TForm1 = class(TForm) Button_egal: TButton; Panel_chif: TPanel; Panel_oper: TPanel; Button_clear: TButton; afficheur: TLabel; procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction);
Delphi et Kylix

88

D. Mailliet

MIAGE 2me anne

procedure FormResize(Sender: TObject); procedure Button_egal_Click(Sender: TObject); procedure Button_clear_Click(Sender: TObject); procedure FormKeyPress(Sender: TObject; var Key: Char); private Calculette:Calculatrice; boutons_oper,boutons_chif : tbbout; old_width : integer; procedure traite_chif(Sender: TObject); procedure traite_oper(Sender: TObject); end; var Form1: TForm1; Implementation {$R *.dfm} const MINI=378; {--------------------- classe calculatrice -----------------------------} constructor Calculatrice.create; begin inherited ; clear; nbop:=0; end; procedure Calculatrice.Clear; begin Op1:=0; Op2:=0; Operation:=#0; entree_en_cours:=''; end; function Calculatrice.Gere_oper(chaine: string ):string ; begin inc(nbop); if entree_en_cours='' then entree_en_cours:= '0'; case nbop of 2 : op1:=ExecOperation; 1 : Op1:=StrtoFloat(entree_en_cours); else op1:=0; end; Operation:=Chaine[1]; result:=FloatToStr(op1); entree_en_cours:=''; end; Function Calculatrice.Gere_chif(chaine: string ) : string ; begin if chaine=',' then begin if entree_en_cours='' then entree_en_cours:='0,'; result:=entree_en_cours; if ansipos(',',entree_en_cours) <> 0 then Exit;//viter de mettre 2 virgules! end; if chaine='+/-' then begin // il faut juste prendre l'oppos
Delphi et Kylix

89

D. Mailliet

MIAGE 2me anne

if (entree_en_cours<>'') then entree_en_cours:=FloattoStr(-StrtoFloat(entree_en_cours)) end else if entree_en_cours='0' then entree_en_cours:=Chaine else entree_en_cours:=entree_en_cours+Chaine; result:=entree_en_cours; end; function Calculatrice.ExecOperation: Extended; begin op2:=StrtoFloat(entree_en_cours); if nbop>0 then dec(nbop); Case Operation of '+' : Result:=Op1+Op2; '-' : Result:=Op1-Op2; '*' : Result:=Op1*Op2; '/' : begin if op2=0 then Exit; Result:=Op1/Op2; end; else result:=0; end; entree_en_cours:=floatToStr(result); Operation:=#0; end; {--------------------- classe tbbout -----------------------------} constructor tbbout.create(nl,nc:byte;proprio:tcomponent;tt:TNotifyEvent;kp:TKeyPressEvent); var i,j:byte; begin inherited create; self.nl:=nl; self.nc:=nc; self.proprio:=proprio; setlength(tb,nl,nc); for i:= 0 to nl-1 do for j:=0 to nc-1 do begin tb[i,j]:= TButton.create(proprio); with tb[i,j] do begin parent:= proprio as TWinControl; caption := intTostr(i*nc+j+1); Font.Charset := DEFAULT_CHARSET; Font.Color := clWindowText ; Font.Height := -24 ; Font.Name := 'MS Sans Serif' ; Font.Style := [fsBold] ; onclick := tt; onkeypress:=kp; end; end; end; procedure tbbout.dimensionne; var i,j:byte; w,h,l,t : integer;
Delphi et Kylix

90

D. Mailliet

MIAGE 2me anne

begin w:=((proprio as TWinControl).width-30) div nc -20; h:=((proprio as TWinControl).height-30) div nl -20; t:=-h; for i:= 0 to nl-1 do begin t:=t+h+20; l:=-w; for j:=0 to nc-1 do begin l:=l+w+20; tb[i,j].width:=w; tb[i,j].height:=h; tb[i,j].top:=t; tb[i,j].left:=l; end; end; end; {--------------------- classe Tform1 -----------------------------} procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin calculette.Destroy; end; procedure TForm1.FormResize(Sender: TObject); begin width:=height; self.ChangeScale(width,old_width); old_width:=width; end; procedure TForm1.FormCreate(Sender: TObject); begin calculette:=Calculatrice.Create; Panel_oper.BevelInner := bvNone; Panel_oper.BevelOuter := bvNone; Panel_chif.BevelInner := bvNone; Panel_chif.BevelOuter := bvNone; boutons_chif := tbbout.create(4,3,panel_chif, traite_chif,FormKeyPress); boutons_oper := tbbout.create(4,1,panel_oper,traite_oper,FormKeyPress); boutons_chif.tb[3,0].caption:=','; boutons_chif.tb[3,1].caption:='0'; boutons_chif.tb[3,2].caption:='+/-'; boutons_oper.tb[0,0].caption:='+'; boutons_oper.tb[1,0].caption:='-'; boutons_oper.tb[2,0].caption:='*'; boutons_oper.tb[3,0].caption:='/'; boutons_chif.dimensionne; boutons_oper.dimensionne; self.Constraints.MinHeight := MINI; self.Constraints.MinWidth := MINI; old_width:=width; calculette.Clear; afficheur.caption:='0'; end; procedure TForm1.traite_oper(Sender: TObject); begin afficheur.caption:=calculette.Gere_oper(string ((Sender as TButton).Caption)); Button_egal.SetFocus;
Delphi et Kylix

91

D. Mailliet

MIAGE 2me anne

end; procedure TForm1.traite_chif(Sender: TObject); begin afficheur.caption:=calculette.Gere_chif(string ((Sender as TButton).Caption)); Button_egal.SetFocus; end; procedure TForm1.Button_egal_Click(Sender: TObject); begin afficheur.caption:=floatToStr(calculette.ExecOperation); end; procedure TForm1.Button_clear_Click(Sender: TObject); begin calculette.Clear; afficheur.caption:='0'; Button_egal.SetFocus; end; procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char); begin if key='.' then key:=','; case upcase(key) of '=' : afficheur.caption:=floatToStr(calculette.ExecOperation); 'C' : Button_clear_Click(Sender); '0'..'9',',': afficheur.caption:=calculette.Gere_chif(key); '+','-','*','/': afficheur.caption:=calculette.Gere_oper(key); end; Button_egal.SetFocus; end; end.

XVI. Transtypage des objets : loprateur As et is


1. Exemple 1 Reprenons lexemple ci dessus en ncrivant quune procdure ButtonMouseMove au lieu de 2. Dans linspecteur dobjet, indiquons que lvnement onMouseMove de chaque bouton est gr par ButtonMouseMove (au lieu de Button1mouseMove et Button2ouseMove). Il faut en contre-partie identifier lauteur du message qui a dclanch lvnement :

unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls, ComCtrls, ExtDlgs; type TForm1 = class(TForm) Button1: TButton; Button2: TButton;

procedure ButtonMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); private { Dclarations prives } public { Dclarations publiques } end; var Form1: TForm1; implementation

Delphi et Kylix

92

D. Mailliet

MIAGE 2me anne

{$R *.DFM} procedure TForm1.ButtonMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer); begin (sender as Tbutton ).visible := false; if sender =button1 then end; end.

button2.visible := true else button1.visible := true

2. Exemple 2 Dans cet exemple, on cre dynamiquement 2 boutons et lon identifie la nature et lauteur du message : unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,stdctrls; type TForm1 = class(TForm) procedure FormActivate(Sender: TObject); procedure FormClick(Sender: TObject); public { Dclarations publiques } MonBouton1,monbouton2 : TButton; procedure creerbouton(monbouton:TButton;h :integer); end; var Form1: TForm1; with MonBouton do begin Parent := Form1; height := 20; width := 200; caption := 'nouveau bouton '+IntToStr(TabOrder); left := 20; top := h; end; MonBouton.OnClick:=Form1.OnClick END; procedure TForm1.FormActivate(Sender: TObject); begin creerbouton( MonBouton1,20); creerbouton( MonBouton2,60); end; procedure TForm1.FormClick(Sender: TObject); begin if sender is tbutton then showMessage(' Click :'+ IntToStr((Sender as TButton).TabOrder)); end; end.

implementation {$R *.DFM} procedure tform1.creerbouton(monbouton:TButton;h :integer); BEGIN MonBouton := TButton.Create(Form1);

XVII.Les Bases de DonnesOn procde en 2 temps :


Crer la structure de la base et des tables Crer linterface sous delphi

Utiliser BDE (Borland Database Engine) : le moteur est en libre distribution si delphi a t acquis rgulirement, il doit tre dploy avec lapplication BD Delphi est prvu pour fonctionner avec Des bases Paradox Des bases Dbases Des bases ODBC

A.

Bases Paradox et DBaseLe module de bases de donnes Delphi permet de crer des BD au format Paradox ou Dbase
Delphi et Kylix

93

D. Mailliet

MIAGE 2me anne

B.

Bases ODBC :Le gestionnaire est accessible partir de : C:\WINDOWS\SYSTEM\ODBCAD32.EXEOu Dmarrer/paramtres/panneau de configuration
Il p ermet d as s o cier n o m lo g iq u e/p h y s iq u e La march e s u iv re es t d e :Crer une base vide avec Access : tstbd.mdb Lui associer un nom logique ess-bd

Dans la suite, nous allons crer des tables, y ajouter des enregistrements , les relire ainsi que les champs et dtruire des enregistrements. Les codes donns ci-dessous sont des applications consoles et ne correspondent pas lutilisation classiques sous delphi pour laquelle ces oprations son faites de faon quasi automatiques et sont transparentes pour le dveloppeur.

C.

Cration tables

program cre_table; {$APPTYPE CONSOLE} uses sysutils, dbtables, db, Forms; var table1:ttable; begin table1:=ttable.create(application); with Table1 do begin Active := False; // sinon imp de crer les champs DatabaseName := 'ess_bd'; TableName := 'Matable'; if Table1.Exists then begin writeln('La table existe dj : elle sera efface'); readln; end; // ici, il faudrait affiner with FieldDefs do begin // def des champs Clear; with AddFieldDef do begin Name := 'numero'; DataType := ftInteger; Required := True; end; with AddFieldDef do begin Name := 'nom'; DataType := ftString; Size := 30; end;

with AddFieldDef do begin Name := 'prenom'; DataType := ftString; Size := 30; end; end; { Puis description des index } with IndexDefs do begin Clear; { il s'agit d'une cl primaire // Imp pour les tables texte} with AddIndexDef do begin Name := 'cle'; Fields := 'numero'; Options := [ixPrimary]; end; with AddIndexDef do begin Name := 'Fld2Indx'; Fields := 'nom'; Options := [ixCaseInsensitive]; end; end; { Appel de la mthode CreateTable pour crer la table } CreateTable; end; end.

D.

Lister les champs

program litchamp; {$APPTYPE CONSOLE} Uses sysutils, dbtables, db, Forms;


Delphi et Kylix

var Table1:ttable; i: Integer; 94 D. Mailliet

MIAGE 2me anne

begin Table1:=ttable.create(application); Table1.DatabaseName := 'ess_bd'; Table1.TableName := 'Matable'; Table1.Active := true; // maintenant oui !

for i:= 0 to Table1.FieldDefs.Count - 1 do writeln(Table1.FieldDefs[i].Name); Table1.Active := False; readln; end.

E.

Ajout denregistrements
Table1.TableName := 'Matable'; Table1.Active := True; Table1.Append; // Ajout en fin Table1.FieldValues['nom'] := 'toto'; Table1.FieldValues['prenom'] := 'titi'; Table1.Post; // validation ajout Table1.Active := False; end.

program aj_enr; {$APPTYPE CONSOLE} Uses sysutils, dbtables, db, Forms; var Table1:ttable; i: Integer; begin Table1:=ttable.create(application); Table1.DatabaseName := 'ess_bd';

F.

Lister les enregistrements


Table1.First; for i := 1 to Table1.RecordCount do begin writeln(Table1.FieldValues['numero'],' ', Table1.FieldValues['prenom'],' ', Table1.FieldValues['nom']); Table1.Next; end; Table1.Active := False; readln; end.

program lire_enr; {$APPTYPE CONSOLE} Uses sysutils, dbtables, db, Forms; var table1:ttable; i: Integer; begin table1:=ttable.create(application); Table1.DatabaseName := 'ess_bd'; Table1.TableName := 'Matable'; Table1.Active := true;

G.

Supprimer 1 enregistrement
Table1.Active := true; Table1.First ; // on est sur le premier Table1.MoveBy(2); // maintenant sur le 3e Table1.delete; // si moins de 3--> sur le dernier Table1.Active := False; // erreur si aucun readln; end.

program det_enr; {$APPTYPE CONSOLE} Uses sysutils, dbtables, db, Forms; var table1:ttable; i: Integer; begin table1:=ttable.create(application); Table1.DatabaseName := 'ess_bd'; Table1.TableName := 'Matable';

H.

Base de donnes texte

Une base de donnes texte est un rpertoire Un fichier de description dans ce rpertoire schema.ini Autant de fichiers textes que de tables

Delphi et Kylix

95

D. Mailliet

MIAGE 2me anne

Il est possible de changer type de base tout moment sans recompiler les programmes prcdents ! Utilisation de lunit Forms ncessaire linitialisation de lapplication en vue de linitialisation des objets OLE

Nom dun rpertoire vide cr prcedemment Il suffit de changer lassociation nom physique en gardant le mme nom logique Ch an g emen t d e type d e b as e Avec une BD texte, on ne peut pas dfinir dindexes

I.
1.

Base de donnes et SQL :


insertion requete .DatabaseName := 'ess_bd'; requete.Close; requete.SQL.Clear; requete.SQL.Add('insert into matable (numero,nom,prenom) values (10,''tata'',''titi'')'); requete.execSQL; end.

program query_ins; {$APPTYPE CONSOLE} uses sysutils, dbtables, db, Forms; var requete:tquery; begin requete:=tquery.create(application); requete .Active := false; 2. suppression

program query_supr; {$APPTYPE CONSOLE} uses sysutils, dbtables, db, Forms; var requete:tquery; begin requete:=tquery.create(application); requete .Active := false; 3. exploration

requete .DatabaseName := 'ess_bd'; requete.Close; requete.SQL.Clear; requete.SQL.Add('delete from matable where nom=''tata'''); requete.execSQL; end.

program query_lire; {$APPTYPE CONSOLE} uses sysutils, dbtables, db, Forms; var requete:tquery; i:byte; begin requete:=tquery.create(application); requete.Active := false; requete.DatabaseName := 'ess_bd'; requete.Close;
Delphi et Kylix

requete.SQL.Clear; requete.SQL.Add('select * from matable '); requete.open;

96

D. Mailliet

MIAGE 2me anne

for i:=0 to requete.Fieldcount-1 do write(requete.Fields[i].FieldName:10, ' '); writeln; while not requete.eof do begin for i:=0 to requete.Fieldcount-1 do write(requete.Fields[i].value:10, ' ');

writeln; requete.Next; end{while} ; readln; end.

J.

Utilisation classique des TABLEs

Placer sur une form : TdataSource, Ttable, TDBGrid :

Type TForm1 = class(TForm) DataSource1: TDataSource; Table1: TTable; DBGrid1: TDBGrid;

type TForm1 = class(TForm) DataSource1: TDataSource; Table1: TTable; DBGrid1: TDBGrid; procedure FormActivate(Sender: TObject); procedure TForm1.FormActivate(Sender: TObject); Begin DBGrid1.DataSource := DataSource1; DataSource1.DataSet := Table1; Table1.databaseName := 'ess_bd'; Table1.TableName := 'matable'; // Query1 Table1.Active := true; // ou encore :Table1.open; end;

Les 5 lignes ci-contre sont les valeurs des proprits des diffrents objets. Il est donc possible de ncrire aucune ligne de code et de se passer de lvnement et de la mthode associe FormActivate

Composants BD
1. type Fiche

Delphi et Kylix

97

D. Mailliet

MIAGE 2me anne

TForm1 = class(TForm) DataSource1: TDataSource; Table1: TTable; DBText1: TDBText; DBEdit1: TDBEdit; DBNavigator1: TDBNavigator; procedure FormActivate (Sender: TObject); end; var Form1: TForm1; Implementation {$R *.DFM} procedure TForm1.FormActivate(Sender: TObject); begin DataSource1.DataSet := Table1; Table1.databaseName := 'ess_bd'; Table1.TableName := 'matable'; DBNavigator1.DataSource := DataSource1; DBText1.DataSource := DataSource1; DBText1.DataField:='numero'; DBEdit1.DataSource := DataSource1; DBEdit1.DataField:='nom'; Table1.Active := true; end;

L.

Tables Matre/dtailSoit une base de donnes relationnelle cre avec Access (par exemple), les liens ODBC ont ts effectus : M. BD Tables
DBGrid1.DataSource := DataSource1; DataSource1.DataSet := Table1; Table1.databaseName := 'bd_rel'; Table1.TableName := 'produits'; DBGrid2.DataSource := DataSource2; DataSource2.DataSet := Table2; Table2.databaseName := 'bd_rel'; Table2.TableName := 'fournisseurs'; // Table1.MasterSource:= DataSource2; // Table1.MasterFields:='Ref_fournisseur' ; Table2.Active := true; Table1.Active := true; Les 7 premires lignes et les 2 dernires permettent de crer 2 tables indpendantes! MasterSource et MesterFilds permettent de lier 2 tables Malheureusement les lignes de codes NE CONVIENNENT PAS Il faut obligatoirement utiliser linspecteur dobjet pour remplir toutes les proprits prcdentes. Proprit de table1

Delphi et Kylix

98

D. Mailliet

MIAGE 2me anne

La liaison prcdente num-fournisseur->ref-fournisseur de table1 donne pour chaque fournisseur la liste des produits Il est possible de dfinir la place une liaison ref-fournisseur-> num-fournisseur dans table2 pour obtenir le fournisseur pour chaque produit Bien entendu cest lun ou lautre sous peine de rfrence circulaire!

N.
1.

Composant BD
QUERY

procedure TForm1.FormActivate(Sender: TObject); begin DBGrid1.DataSource := DataSource1; DataSource1.DataSet := Query1; Query1.databaseName := 'ess_bd'; Query1.SQL.clear; Query1.SQL.add('select nom from matable'); Query1.Active := true; end;

2. Amliorations de la prsentation des colonnes dune grille (DBGrid) Inspecteur dobjet : proprits de DB Grid

Delphi et Kylix

99

D. Mailliet

MIAGE 2me anne

3.

Les filtres :

effet comparable SQL Inspecteur dobjet : proprits de Ttable


l Filter l Si

peut contenir une chane du genre : nom=par* or num-ref >17

Filtred = true, le filtre est actif = true majuscules et minuscules indiffrentes

l foCaseInsensitive

O.

Impressions de rapports Les proprits liant les Ttables et les Tquickrep sont les mmes que pour

les TDbGrid.

TQuickRep
TTable

Ttable : proprits renseigner DatabaseName TableName

TQRLabel

Les proprits liant les Ttables et les Tquickrep sont les mmes que pour les TDbGrid.

TQRBand

TQRDBText : proprits renseigner DataField : nom du champ dont on veut visualiser les enregistrements DataSet : nom du Ttable

TQRDBText Obligatoirement dans la Bande d tail Pour R p tition des enregistrements

Bien que la proprit Visible napparat pas dans la liste, elle existe. On utilisera les mthodes Preview et Print

P.

Complments sur les DBGrid et transtypage en DrawGrid

procedure TForm1.Button1Click(Sender: TObject); var i, j: Integer; s: string ; begin if DBGrid1.SelectedRows.Count>0 then with DBGrid1.DataSource.DataSet do for i:=0 to DBGrid1.SelectedRows.Count-1 do begin GotoBookmark(pointer(DBGrid1.SelectedRows.Items[i])); for j := 0 to FieldCount-1 do begin if (j>0) then s:=s+', '; s:=s+Fields[j].AsString; end; Listbox1.Items.Add(s); s:= ''; end; end; Il suffit dajouter un bouton lexemple du paragraphe XVII (Utilisation classique des TABLEs) page 93
Delphi et Kylix

100

D. Mailliet

MIAGE 2me anne

Et de donner la valeur TRUE l options dgMultiSelect du DBGrid qui permet de slectionner plusieurs lignes (comme son nom lindique). On remarquera que lon naccde pas directement aux cellules de la grille : un DBGrid ne possde pas comme les autres Grid de proprit Row et col ; mais aux lments slectionns par lintermdiaire de la DataSource. Lutilisateur pouvant changer lordre des colonnes, ce ne serait pas une bonne ide daccder une cellule par ses coordonnes . Il est cependant possible daccder directement aux cellules en transtypant une DBGrid en DrawGrid Label1.Caption := Format ( 'ligne: %2d; colonne: %2d', [TdrawGrid (DbGrid1).Row, TdrawGrid (DbGrid1).Col]); Label2.Caption :=DbGrid1.Columns.Grid.Fields[TdrawGrid (DbGrid1).col-1].AsString ; Label3.Caption :=DbGrid1.Columns.Grid.Fields[0].AsString ; for i:= 1 to DbGrid1.FieldCount-1 do Label3.Caption :=Label3.Caption+', '+ DbGrid1.Columns.Grid.Fields[i].AsString ; Lexemple prcdent indique dans le : Label1 : les numros de ligne et de colonne de llment slectionn. Label2 : le contenu de la cellule slectionne Label3 : le contenu de la ligne slectionne

Q.
1.

Table XML
Le programme

Lexemple suivant cre une table sous forme de fichier au format XML et en fait la lecture : Le programme ci-dessous utilise des lments visuels ou non crs dynamiquement. Dans une application relle, on crrait un projet, avec une fiche (Form) sur laquelle on dposerait une TDBGrid, TdataSource, TclientDataSet, TopenDialog, TsaveDialog, TDBNavigator ,Tbutton et Tedit puis on renseignerait les proprits dans linspecteur dobjet tel que cest fait par lignes de code dans le programme : program TableXML; uses Windows, Messages,SysUtils,Variants,Classes,Graphics,Co ntrols, Forms,Dialogs,DB,DBClient,Grids,DBGrids; CONST nomFic='\ess.xml'; var Form1 :TForm; DBGrid1: TDBGrid; DataSource1: TDataSource; ClientDataSet1: TClientDataSet; rep_de_l_applic: string ; procedure creerTable; Begin ClientDataSet1.Active:=False; ClientDataSet1.FieldDefs.Clear; with ClientDataSet1.FieldDefs.AddFieldDef do begin Name:='Champ1'; DataType:=ftString; Size:=20; end; with ClientDataSet1.FieldDefs.AddFieldDef do begin
Delphi et Kylix

Name:='Champ2'; DataType:=ftInteger; end; ClientDataSet1.CreateDataSet; End; procedure Ajout_enregistrement(ch1: string ;ch2:integer); begin ClientDataSet1.Append; ClientDataSet1.FieldValues['champ1'] := ch1; ClientDataSet1.FieldValues['champ2'] := ch2; ClientDataSet1.Post; end; begin // Rcupration du rpertoire de l'application rep_de_l_applic:=ExtractFileDir(paramstr(0)); // Cration d'une table avec 2 enregistrements ClientDataSet1:= TClientDataSet.Create( nil ); creerTable; Ajout_enregistrement('abcd',12); Ajout_enregistrement('efg',34); // Destroy n'est pas ncessaire puisqu'on rutilise ClientDataSet1 Clientdataset1.SaveToFile(rep_de_l_applic+no mFic,dfxml); 101 D. Mailliet

MIAGE 2me anne

ClientDataSet1.Destroy; // Lecture de la table : ces 2 parties ( ) sont indpendantes Application.Initialize; Application.CreateForm(TForm, Form1); dbgrid1 := TDBGrid.create(Form1); DataSource1:= TDataSource.Create(Form1); ClientDataSet1:= TClientDataSet.Create(Form1); Form1.Left := 0; Form1.Top := 0; Form1.Width := 688; 2. Le rsultat

Form1.Height := 453; dbgrid1.parent:=Form1; dbgrid1.Align := alClient; dbgrid1.DataSource := DataSource1; DataSource1.DataSet := ClientDataSet1; ClientDataSet1.Active:=false; ClientDataSet1.FileName:=rep_de_l_applic+no mFic; ClientDataSet1.Active:=true; Application.Run; end.

Le programme ci-dessus cre une table sous forme de fichier Texte au format XML dont louverture avec Internet Explorer 6 de Microsoft donne :

En ralit le fichier texte ne comporte pas de mise en page , Tout est sur une seule ligne, cest IE6 qui interprte le fichier sous une forme arborescente que lon peut dvelopper ou non en cliquant sur les + et - :

De plus en intercalant entre la premire et la deuxime ligne : <?xml version="1.0" standalone="yes"?> <?xml-stylesheet type="text/xsl" href="ess.xsl"?> <DATAPACKET Version="2.0"> et en ajoutant la feuille de style XSL ess.xsl dans le mme rpertoire :

Delphi et Kylix

102

D. Mailliet

MIAGE 2me anne

Porgramme msxsl.js crit en javascript et interprtable par Windows Scripting Host


//Info: http://www.CraneSoftwrights.com/links/msxsl.htm //Args: input-file style-file output-file var xml = WScript.CreateObject("Msxml2.DOMDocument.3.0"); xml.validateOnParse=false; xml.load(WScript.Arguments(0)); var xsl = WScript.CreateObject("Msxml2.DOMDocument.3.0"); xsl.validateOnParse=false; xsl.load(WScript.Arguments(1)); on obtient avec IE5 :

//input

//style

var out = WScript.CreateObject("Scripting.FileSystemObject"); //output var replace = true; var unicode = false; //output file properties var hdl = out.CreateTextFile( WScript.Arguments(2), replace, unicode ) hdl.write( xml.transformNode( xsl.documentElement )); //eof Il suffit dans une fentre de commande de taper msxls.js ess.xml ess.xls ess.html pour obtenir ess.html (donnant le rsultat ci-contre ) partir de ess.xml et ess.xls Il est facile de transformer le Script ci-dessus en un programme Delphi (voir ole Automation)

Ceci donne un exemple d universalit du format XML et de lintrt de ce type dapplication utilisant Clientdataset1.SaveToFile( ,dfxml); 3. Amliorations : On peut avantageusement remplacer les lignes rep_de_l_applic:=ExtractFileDir(paramstr(0));
Delphi et Kylix

103

D. Mailliet

MIAGE 2me anne

Clientdataset1.SaveToFile(rep_de_l_applic+nomFic,dfxml); Et ClientDataSet1.FileName:=rep_de_l_applic+nomFic; Par : with TSaveDialog.Create( nil ) do begin DefaultExt:='xml'; Filter :='*.xml'; if execute then Clientdataset1.SaveToFile(filename) else Halt; end; Ce qui permet de choisir le nom de sauvegarde du fichier 4. Remarques Clientdataset1.SaveToFile possde 2 paramtres : Le premier de type string est le nom complet du fichier Le second est de type TDataPacketFormat, de lunit DBClient , prcise le format du fichier et est dfini comme type TDataPacketFormat = (dfBinary, dfXML, dfXMLUTF8); Description (provenant de laide) : TDataPacketFormat indique comment un fournisseur code les informations de base de donnes en paquets de donnes. Le tableau suivant numre les valeurs possibles : Valeur dfBinary dfXML dfXMLUTF8 Signification Les informations sont codes en format binaire. Les informations sont codes en format XML, les caractres tendus tant cods l'aide d'une squence d'chappement. Les informations sont codes en format XML, les caractres tendus tant rrep_de_l_applicrsents en utilisant UTF8. Et with TOpenDialog.create(form1) do if execute then ClientDataSet1.FileName:=FileName else Halt;

ClientDataSet1.FieldDefs.AddFieldDef.DataType est de type TFieldType de lunit DB dfini comme : type TFieldType = (ftUnknown, ftString, ftSmallint, ftInteger, ftWord, ftBoolean, ftFloat, ftCurrency, ftBCD, ftDate, ftTime, ftDateTime, ftBytes, ftVarBytes, ftAutoInc, ftBlob, ftMemo, ftGraphic, ftFmtMemo, ftParadoxOle, ftDBaseOle, ftTypedBinary, ftCursor, ftFixedChar, ftWideString, ftLargeint, ftADT, ftArray, ftReference, ftDataSet, ftOraBlob, ftOraClob, ftVariant, ftInterface, ftIDispatch, ftGuid, ftTimeStamp, ftFMTBcd); Description (provenant de laide) : Le type TFieldType est l'ensemble de valeurs ou la proprit DataType d'objets champ, d'objets de dfinition de champ et d'objets paramtre. Les classes dans lesquelles les valeurs TFieldType sont utilises comprennent TField (et les descendants), TFieldDef, TParam et TAggregate. Les valeurs TFieldType sont aussi utilises dans des fonctions relatives au champ et des mthodes telles que TFieldDefs.Add. Le tableau suivant dcrit chacune de ses valeurs : Valeur ftUnknown ftString ftSmallint ftInteger ftWord ftBoolean Description Champ inconnu ou non dtermin Champ caractre ou chane Champ entier sur 16 bits Champ entier sur 32 bits Champ entier non sign sur 16 bits Champ boolen Valeur ftDBaseOle ftTypedBinary ftReference ftFixedChar ftWideString ftLargeint Description Champ OLE dBASE Champ binaire typ Champ REF Champ caractre fixe Champ chane de caractres large Champ nombre entier de grande taille

Delphi et Kylix

104

D. Mailliet

MIAGE 2me anne

FtFloat ftCurrency FtBCD

Champ numrique virgule flottante Champ montaire Champ dcimal cod binaire qui peut tre converti en type Currency sans perte de prcision. Champ date Champ heure Champs BLOB dans les tables Oracle 8 Nombre fixe d'octets (stockage binaire) Nombre variable d'octets (stockage binaire) Champ compteur autoincrment entier sur 32 bits Champ BLOB (Binary Large Object) Champ mmo texte Champ date et heure accessible par le biais de dbExpress Champ mmo texte format

FtADT ftArray ftCursor

Champ type de donnes abstrait Champs tableau Curseur de sortie d'une procdure stocke Oracle (TParam uniquement). Champ DataSet Champ date et heure Champs CLOB dans les tables Oracle 8 Donnes de type inconnu ou indtermin Rfrences pour les interfaces (IUnknown) Rfrences pour les interfaces IDispatch Valeurs GUID (identificateur globalement unique) Champ bitmap Champ dcimal cod binaire trop long pour ftBCD. Champ OLE Paradox

FtDate FtTime ftOraBlob ftBytes ftVarBytes ftAutoInc FtBlob ftMemo ftTimeStamp ftFmtMemo

ftDataSet ftDateTime ftOraClob ftVariant ftInterface ftIDispatch FtGuid ftGraphic ftFMTBcd ftParadoxOle

XVIII.Canvas : une proprit commune tous les composants


Il est possible de dessiner, dcrire ou de transformer la forme des composants visuels en agissant sur leur proprit canvas. A titre dexemple, voici un programme qui dessine une sinusode :

unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,ComCtrls, Tabnotbk, ExtCtrls; type TForm1 = class(TForm) boiteDessin: TPaintBox; procedure boiteDessinPaint(Sender: TObject); private { Dclarations prives } public { Dclarations publiques } end;
Delphi et Kylix

var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.boiteDessinPaint(Sender: TObject); var x,y:extended; GX,Gy, W,H :integer; begin With BoiteDessin do begin W:= clientwidth; H:= clientheight; for GX := 0 to W do begin x:= 2*Pi/W*GX -Pi; y:= sin(x); Gy :=round(-w/2/Pi*y+H/2); 105 D. Mailliet

MIAGE 2me anne

Canvas.Pixels[Gx,Gy] :=clRed; end; end;

end; end.

XIX. OLE, COM et Automation


A. Dfinitions
Object Linking and Embedding (liaison et incorporation d'objets) Technique mise au point par Microsoft pour inclure dans un document, des documents d'autres applications, selon le principe du client/serveur , i.e. en gardant le lien avec l'application d'origine, qu'on pourra rappeler pour une modification ou une mise jour CORBA : Common Object Request Broker Achitecture. Standard de gestion d'objets distribus, mis au point par l'OMG (Object Management Group), et rivalisant avec COM de Microsoft. L'objectif est de permettre des applications dveloppes dans des langages diffrents de communiquer mme si elles ne sont pas sur la mme machine Component Object Model. Standard de gestion d'objets distribus, propre Microsoft. OLE 2.0 est bas sur COM Automation : Technique permettant de piloter une application par une autre

B.

OLE : Exemples
Excel Word Internet Explorer Et tous les processus qui ont prvu une interface OLE

Il est possible travers Delphi de piloter

C.

OLE Excel
Utilisation de lunit Forms ncessaire l initialisation de lapplication en vue de l initialisation des objets OLE
C ration du lien OLE pour la classe r frenc par Excel dans la base de registre "Excel.Application" Utilisation de l unit Forms n cessaire l initialisation de l application en vue de l initialisation des objets OLE cration du lien OLE pour la classe r frenc par Excel dans la base de registre "Excel.Application"

program ess11; {$apptype console} uses Forms,StdCtrls,ComObj,ExtCtrls; var OleApplication :variant;

begin Application.Initialize; OleApplication := CreateOleObject('excel.Application'); OleApplication.visible:=True; // pour rendre Excel visible OleApplication.Workbooks.Add; // Pour ajouter un classeur dans Excel

readln; try // Lutilisateur Aurait pu fermer lapplication Excel. Ce qui donnerait une erreur de fonctionnement OleApplication.Quit; except end; end.

D.

OLE Word

program essWord; {$apptype console} uses Forms,StdCtrls,ComObj,ExtCtrls; var


Delphi et Kylix

106

D. Mailliet

MIAGE 2me anne

OleApplication :variant; begin Application.Initialize; OleApplication := CreateOleObject('Word.Application'); OleApplication.visible:=True; OleApplication.Documents.add; OleApplication.Selection.Font.Name := 'Apex'; OleApplication.Selection.TypeParagraph; OleApplication.Selection.TypeText('essai'); OleApplication.Selection.HomeKey; OleApplication.Selection.Font.Bold := 1; OleApplication.Selection.ParagraphFormat.Alignment := 2 ; readln; try OleApplication.Quit; except end; end.

E.

OLE Internet Explorer

program essIE5; {$apptype console} uses Forms,StdCtrls,ComObj,ExtCtrls; Var OleApplication :variant; texte : string ; begin Application.Initialize; OleApplication := CreateOleObject('InternetExplorer.Application'); OleApplication.visible:=True; OleApplication.Navigate ('http://www.univ-lille1.fr'); writeln('attendez que la page soit charge et appuyez sur entre'); readln; texte:=OleApplication.Document.frames.item('haut').document.Body.innerText; writeln('Il faut connaitre le nom des frames : ',texte); writeln('Ecriture dans la page : appuyez sur entre'); readln; OleApplication.Document.writeln('essai<br>suite'); texte:=OleApplication.Document.Body.innerText; writeln('Recuperation du texte (pas de frame) :', texte); readln; try OleApplication.Quit; except end; end.

F.

OLE Conclusion

Pour utiliser lautomation : Il faut connatre : Le nom denregistrement de lapplication dans la base de registre. Le nom des mthodes quexporte lapplication toute erreur ne peut tre dtecte qua lexcution. Pour IE, il faut de plus connatre la structure de la page HTML Toutes ces info sont difficiles trouver ; heureusement on rcupre de nombreux exemples sur internet

G.

OLE Excel : complments

Excel dispose dun langage de programmation : VBA (Visual basic pour application.

Delphi et Kylix

107

D. Mailliet

MIAGE 2me anne

Il dispose de plus dun enregistreur de macros qui traduit toutes les commandes souris et clavier en code VBA. Word possde aussi ces 2 lments Voir la suite pour une dmonstration Excutez Excel Lancer lenregistrement de la macro Choisir un nom pour la macro

Taper les commandes voulues

Arrter lenregistrement

Aprs avoir arrt lenregistrement, cliquer ici Range("E2").Select ActiveCell.FormulaR1C1 = "=RC [-2]+RC[-1] Range("E3").Select End Sub

Ouvrir lditeur VBA On obtient le code VBA suivant:

Sub mon_essai_ole() Range("C2").Select ActiveCell.FormulaR1C1 = "15" Range("D2").Select ActiveCell.FormulaR1C1 = "12"


Delphi et Kylix

108

D. Mailliet

MIAGE 2me anne

En remplaant les ( ) par [ ], les = par := et les " " par begin Application.Initialize; OleApplication := CreateOleObject('excel.Application'); OleApplication.visible:=True; OleApplication.Workbooks.Add; OleApplication.Range['C2'].Select; OleApplication.ActiveCell.FormulaR1C1 := '15';

OleApplication.Range['D2'].Select; OleApplication.ActiveCell.FormulaR1C1 := '12'; OleApplication.Range['E2'].Select; OleApplication.ActiveCell.FormulaR1C1 := '=RC [2]+RC[-1]'; OleApplication.Range['E3'].Select; readln; try OleApplication.Quit; except end; end.

XX. Cration dun serveur OLE


Commencer un nouveau projet MonServ_Ole Choisir un nom ServUnit pour lunit et sauvegarder Placer un mmo sur la fiche principale Dans le menu fichier/nouveau/activeX, choisir objet Automation

Choisir un nom de classe

Delphi et Kylix

109

D. Mailliet

MIAGE 2me anne

Slectionnez ici puis l

Slectionnez ici, choisir un nom de procdure ainsi que les paramtres et types puis Validez

Dans une deuxime unit, ServUnit2 on obtient le code ci-dessous. On le complte par uses ComServ,Servunit; // nom de lunit possdant fiche et mmo

procedure Tmon_Ole.ins_txt(const Texte: WideString); begin Form1.Memo1.Lines.add(Texte); end; Compilez et excutez : il fonctionne comme un projet normal

XXI. Cration dun client OLE


Ouvrir un nouveau projet et sur la fiche placez Un Tedit et un bouton unit ClientUnit1pas; interface uses Windows, Messages, SysUtils, Classes,graphics, Controls, Forms,Dialogs,StdCtrls,ComObj; type TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); 110 D. Mailliet

Delphi et Kylix

MIAGE 2me anne

end; var Form1: TForm1; obj_ole : variant; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin Il est ncessaire denregistrer le serveur dans la base de registre: Dans une console excutez la ligne de commande MonServ_Ole /regserver Pour retirer les informations la base de registre: Dans une console excutez la ligne de commande MonServ_Ole /unregserver Il est aussi possible de choisir Excuter/Paramtres dans lEDI

obj_ole :=createOleObject('monserv_ole.mon_Ole') end; procedure TForm1.Button1Click(Sender: TObject); begin obj_ole.Ins_Txt(Edit1.Text) end; end.

XXII.Modification du client-Serveur OLE


Pour ajouter une fonctionnalit au serveur : Il ne faut surtout pas modifier directement le code de lunit 2

Voir/Bibliothque des types dans lEDI puis Cot serveur complter : procedure Tmon_Ole.eff_txt; begin Form1.Memo1.Clear; end; Cot client, Ajouter un bouton et complter : procedure TForm1.Button2Click(Sender: TObject); begin obj_ole.eff_Txt end;

Delphi et Kylix

111

D. Mailliet

MIAGE 2me anne

XXIII.Notions avances sur les objets


Dans le but dorganiser et de structurer les classes et le code, on dfinit des : Mthodes virtuelles et dynamiques Mthodes abstraites Mthodes de classes et dobjets Interfaces . Ne pas confondre avec la section interface dune unit

A.

Compatibilit des classes

Un objet peut tre cr par son constructeur ou le constructeur de sa sous-classe (descendant) mais non de sa super-classe (ascendant) Cest pour cette raison que, dans les mthodes de gestion des vnements, le sender est toujours un TObject mme si en ralit il sagit dun Tbutton, revoir lexemple : Procedure TForm1.evenement(Sender: Tobject); if Sender is Tbutton Sender as Tbutton

Delphi et Kilix

112

D. Mailliet

MIAGE 2me anne

B.

Mthodes Virtuelles et dynamiques


program clas_virt; {$APPTYPE CONSOLE} type texemple = class procedure test; dynamic; //virtual; end; texemple1 = class(texemple) procedure test; override; end; procedure texemple.test; begin writeln ('exemple'); end; procedure texemple1.test; begin writeln ('exemple 1'); end; Var ex : texemple; expl : texemple1; begin ex:=texemple.create; ex.test; ex.destroy; ex:=texemple1.create; ex.test; ex.destroy; { expl:=texemple.create; ==> erreur} expl:=texemple1.create; expl.test; expl.destroy; readln; end.

program clas_virt; {$APPTYPE CONSOLE} type texemple = class procedure test; end; texemple1 = class(texemple) procedure test; end; procedure texemple.test; begin writeln ('exemple'); end; procedure texemple1.test; begin writeln ('exemple 1'); end; Var ex : texemple; expl : texemple1; begin ex:=texemple.create; ex.test; ex.destroy; ex:=texemple1.create; ex.test; ex.destroy; { expl:=texemple.create; ==> erreur} expl:=texemple1.create; expl.test; expl.destroy; readln; end.

exemple exemple exemple 1

exemple exemple 1 exemple 1

C.

Conclusion

Lorsque la mthode est dclare override (ne pas confondre avec overload) , si un objet est cr avec le constructeur de sa sous-classe, cest la mthode de sa sous-classe qui est utilise Lorsque la mthode nest pas dclare override , si un objet est cr avec le constructeur de sa sous-classe, cest la mthode de sa classe qui est utilise. Une mthode ne peut tre dclare override que si son anctre est virtual ou dynamic (pas de diffrence smantique)

Delphi et Kylix

113

D. Mailliet

MIAGE 2me anne

XXIV.Mthodes abstraites
Une mthode abstraite est une mthode virtuelle ou dynamique n'ayant pas d'implmentation dans la classe o elle est dclare. Son implmentation est dlgue une classe drive. Les mthodes abstraites doivent tre dclares en spcifiant la directive abstract aprs virtual ou dynamic. Il nest possible dappeler une mthode abstraite que dans une classe ou une instance de classe dans laquelle la mthode a t surcharge. Lide est de fournir un cadre gnral et de laisser le dveloppeur raliser les classes concrtes sil le souhaite

unit U_abstraite; interface type t_essai = class // dclaration des champs et mthodes procedure test ; virtual ; abstract; program abstraite; {$APPTYPE CONSOLE} Uses U_abstraite; type t_essai2 = class(t_essai) procedure test ; end; procedure t_essai2.test; begin

end; Implementation // implmentation des mthodes de t_essai // on n'implmente pas test ! end. writeln('a marche') end; var x : t_essai2; begin x:=t_essai2.create; x.test; x.destroy; readln; end.

XXV.Le type Interface


Comme une classe, une interface hrite de toutes les mthodes de ses anctres. Mais les interfaces, la diffrence des classes, n'implmentent pas les mthodes (elles ont ce point commun avec les mthodes abstraites). Ce dont hrite l'interface, c'est de l'obligation d'implmenter les mthodes ; obligation qui est en fait supporte par toute classe grant l'interface. Il sagit en quelque sorte dun contrat que souscrivent les classes implmentant ces interfaces. Ces classes doivent driver de TInterfacedObject plutt que de Tobject

type Iligne= interface function perimetre : real; Isurface= interface function diagonale : real; function surface : real; procedure double; end; end; // On dfinit ici une sparation logique entre les mthodes ayant trait aux lments physiques linaires et surfaciques de lobjet rel rectangle= class (TInterfacedObject,Iligne,Isurface) constructor create(initL,initH :real); function perimetre : real; function surface : real; procedure double;
Delphi et Kylix

114

function diagonale : real; private largeur,hauteur:real; end; // exactement la mme implmentation que sil ny avait pas dinterface D. Mailliet

MIAGE 2me anne

A.

Interface : rsolution de nom

Lorsque dans 2 interfaces, des lments portent le mme nom, on peut les distinguer, dans la class de la manire suivante :

program ess_ interface_dbln; {$APPTYPE CONSOLE} uses sysutils; type I_1 = interface procedure test; end; I_2 = interface procedure test; end; Cl = class (TInterfacedObject,I_1,I_2) procedure I_1.test = tst1; procedure I_2.test = tst2; procedure tst1; procedure tst2; end;

procedure Cl.tst1; begin writeln('test 1') end; procedure Cl.tst2; begin writeln('test 2') end; var c:Cl; begin c:= Cl.create; c.tst1; c.tst2; c.destroy; readln; end.

B.

Utilisation de interfaces

On peut imaginer quune interface est une vision dun objet travers une fentre Soit le problme suivant : On dispose dobjets de la vie courante tels du papier sur lequel on peut crire et une bouteille que lon peut remplir. Donc des comportement radicalement diffrents . mais ces objets ont un point commun cest que mis la poubelle, ils sont recyclables. Seulement, le recyclage est diffrent quil sagisse dun papier ou dune bouteille. On ne peut donc pas driver une classe pour en faire hriter bouteille et papier. Et pourtant on souhaite recycles les objets de la poubelle quils soient papier ou bouteille par un traitement du style for i:=1 to 2 do poubelle[i].recycle; program ess_ interface_poubel; {$APPTYPE CONSOLE} uses sysutils; type Irecyclable = interface procedure recycle ; // il peut y avoir d'autres mthodes end; papier = class (TInterfacedObject,Irecyclable) procedure recycle ; procedure ecrit; // il peut y avoir d'autres mthodes mais il // doit y avoir au moins celles de l'interface end; bouteille = class (TInterfacedObject,Irecyclable) procedure recycle ; procedure remplit;
Delphi et Kilix

// il peut y avoir d'autres mthodes mais il // doit y avoir au moins celles de l'interface end; procedure papier.recycle; begin writeln('recyclage du papier'); end; procedure papier.ecrit; begin writeln('criture sur papier'); end; procedure bouteille.recycle; begin writeln('recyclage de bouteille'); end; procedure bouteille.remplit; 115 D. Mailliet

MIAGE 2me anne

begin writeln('remplissage de bouteille'); end; var p:papier; b:bouteille; poubelle: array [1..2] of Irecyclable; i:byte; begin p:=papier.Create;

b:=bouteille.Create ; poubelle[1]:=p; poubelle[2]:=b; for i:=1 to 2 do poubelle[i].recycle; p.ecrit; // poubelle[1].ecrit; ==> Erreur b.remplit; readln; end.

XXVI.Mthodes de classes
Une mthode de classe est une mthode (autre qu'un constructeur) qui agit sur des classes et non sur des objets. La dfinition d'une mthode de classe doit commencer par le mot rserv class . Remarque : le constructeur la mme syntaxe quune mthode de classe.

program meth_clas; {$APPTYPE CONSOLE} type texemple = class class procedure test; end;

begin writeln ('exemple'); end; begin texemple.test; readln; end.

class procedure texemple.test; // lutilisation dune mthode de classe ressemble en quelque sorte lutilisation dun constructeur dun objet. Elle est prfixe par la classe et non par lobjet Il nest pas ncessaire dinstancier un objet pour se servir dune mthode de classe program meth_clas2; {$APPTYPE CONSOLE} type texemple = class i : integer; class procedure test_c; procedure test_o; end; procedure texemple.test_o; begin writeln ('mthode d''objet'); writeln('i vaut : ',i); end; Var e : texemple;

begin e := texemple.Create; class procedure texemple.test_c; e.i := 5; texemple.test_c; //Mthode de classe begin writeln ('mthode de classe'); e.test_o; //Mthode dobjet readln; // writeln('i vaut : ',i); end; end. Une mthode de classe na pas accs aux lments propres dun objet. Ici la tentative daccder un champ dun objet dans la mthode de classe provoque une erreur puisque la mthode de classe est fabrique avant que ne soit instanci lobjet et une seule fois pour toutes les instanciations de tous les objets dune mme classe

A.

Utilisation des mthodes de classes


uses 116 SysUtils; D. Mailliet

Lide est de construire une classe ressemblant un type numr program jr_sem; {$APPTYPE CONSOLE}
Delphi et Kylix

MIAGE 2me anne

type jourDeSemaine = class class function lun : jourDeSemaine ; class function mar : jourDeSemaine ; class function mer : jourDeSemaine ; class function jeu : jourDeSemaine ; class function ven : jourDeSemaine ; class function sam : jourDeSemaine ; class function dim : jourDeSemaine ; class function suivant(j:jourDeSemaine) : jourDeSemaine ; constructor create(jr:jourDeSemaine); overload; function est_avant( j:jourDeSemaine) : boolean; function asstring:string ; function svt: jourDeSemaine ; private name : string ; index: 1..7 ; constructor create(nom:string ;idx:byte); overload; end ; constructor jourDeSemaine.create(nom:string ;idx:byte); begin inherited create; self.name:=nom; self.index:=idx; end; class function jourDeSemaine.lun : jourDeSemaine ; begin result:= create('lundi',1); // jourDeSemaine facultatif end; class function jourDeSemaine.mar : jourDeSemaine ; begin result:= jourDeSemaine.create('mardi',2); end; class function jourDeSemaine.mer : jourDeSemaine ; begin result:= self.create('mercredi',3); // self reprsente la classe et non l'objet // self.name:='mercredi'; erreur // name :='mercredi'; NAME EST INACCESSIBLE end; class function jourDeSemaine.jeu : jourDeSemaine ; begin
Delphi et Kylix

result:= jourDeSemaine.create('jeudi',4); end; class function jourDeSemaine.ven : jourDeSemaine ; begin result:= jourDeSemaine.create('vendredi',5); end; class function jourDeSemaine.sam : jourDeSemaine ; begin result:= jourDeSemaine.create('samedi',6); end; class function jourDeSemaine.dim : jourDeSemaine ; begin result:= jourDeSemaine.create('dimanche',7); end; constructor jourDeSemaine.create(jr:jourDeSemaine); begin create(jr.name,jr.index); end; function jourDeSemaine.asstring:string ; begin result:= name; end; (*$WARNINGS OFF*) class function jourDeSemaine.suivant(j:jourDeSemaine) : jourDeSemaine ; begin case j.index Mod 7+ 1 of 1: result:= lun; 2: result:= mar; 3: result:= mer; 4: result:= jeu; 5: result:= ven; 6: result:= sam; 7: result:= dim; // else result:= dim; evite $warnings end; end; (*$WARNINGS ON*) function jourDeSemaine.svt: jourDeSemaine ; begin result := jourDeSemaine.suivant(self); end; function jourDeSemaine.est_avant( j:jourDeSemaine) : boolean; begin result := self.index<j.index; end; 117 D. Mailliet

MIAGE 2me anne

var unJour,autreJour : jourDeSemaine ; begin unJour:=jourDeSemaine.create('lundi',1); // serait impossible si unit /= writeln(jourDeSemaine.lun.asstring); writeln(unJour.asstring); writeln(jourDeSemaine.suivant(unjour).asstring); Remarquez lenchanement des .svt.svt.svt.svt.svt

writeln(UnJour.svt.svt.svt.asstring); autreJour:=jourDeSemaine.create(jourDeSema ine.mer); writeln(AutreJour.svt.svt.svt.svt.svt.asstring); writeln(unJour.est_avant(autreJour)); writeln(unJour.lun.asstring); readln; end.

XXVII.Cration de composants
Delphi possdent un certain nombre de composants visuels (VCL) ou non Il est possible den crer de nouveaux et de les ajouter la VCL unit labelclignotant; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TLabelClignotant = class(TLabel) constructor Create (AOwner: TComponent); destructor Destroy; private TimerClignotement : TTimer; FTempsClignotement : Cardinal; procedure clignote(Sender : Tobject); procedure setTempsClignotement(temps : Cardinal); public clignote_ok : boolean; published property TempsClignotement: Cardinal read FTempsClignotement write setTempsClignotement; end; implementation constructor TlabelClignotant.create(AOwner: TComponent); begin inherited ; // inherited create(Aowner) ; clignote_ok := true; FTempsClignotement := 500; TimerClignotement := TTimer.Create(self); // instanciation du timer TimerClignotement.Interval := FTempsClignotement; TimerClignotement.Enabled := True; TimerClignotement.OnTimer := Clignote// Lvnement appelle la procdure clignote end; destructor TlabelClignotant.Destroy; begin TimerClignotement.Free; Inherited Destroy; end;
Delphi et Kylix

118

D. Mailliet

MIAGE 2me anne

procedure TlabelClignotant.clignote(Sender : Tobject); begin if clignote_ok then visible:=not visible; end; procedure TlabelClignotant.setTempsClignotement(temps : Cardinal); begin FTempsClignotement :=temps; TimerClignotement.Interval:=FTempsClignotement end; // FTempsClignotement, bien que priv, est accessible dans lunit dans laquelle il est dclar end. Notre nouveau composant hrite des TLabels et ncessite un TTimer : Cest ce Timer qui est charger denvoyer de messages qui feront apparatre ou disparatre le Label Une partie prive empche dagir directement sur certains lments Une proprit permet de contrler lintervention sur ces lments. Une partie publique permet de faire cesser le clignotement

A.

Vrification de composants

Uses ,labelclignotant; type TForm1 = class(TForm) Button1: TButton; procedure FormActivate(Sender: TObject); procedure Button1Click(Sender: TObject); public lc : TLabelClignotant; end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); begin lc.clignote_ok:=not (lc.clignote_ok); end; procedure TForm1.FormActivate(Sender: TObject); begin lc:=TLabelClignotant.create(self); lc.Parent := self; // Les 2 1res lignes dues cration dynamique lc.left :=95; lc.top:=48; lc.caption:='le Label clignotant'; lc.visible:=true; // lc.FTempsClignotement := 400; priv! lc.TempsClignotement :=400; end; end. Le nouveau composants est oprationnel (il a t test) Mais ce stade, chaque fois quon veut lutiliser, il faut inclure lunit labelclignotant
Delphi et Kylix

119

D. Mailliet

MIAGE 2me anne

Il est possible de dposer notre composant dans la VCL:

B.

Installation du composants

Il suffit dajouter dans la partie interface et dans la partie implmentation : . procedure Register ; implementation procedure Register ; begin RegisterComponents(Mes Composants', [TLabelClignotant]); end; . Il faut ensuite excuter linstallation : menu composant/Installer un composant..

XXVIII.Flux
Un flux est une suite de donnes continues. Cette suite peut se trouver sur un disque (fichier), en mmoire, sur une connexion... TStream est la classe abstraite qui fournit l'architecture ncessaire la gestion d'un flux, elle propose les mthodes de base pour la lecture et l'criture dans un flux. Chaque descendant devra donc implmenter ces mthodes. Lavantage des flux est la rapidit de traitement C'est un moyen "universel" de lire et d'crire des donnes sur un support.

A.

Flux chanes
flux_ch.position :=0; writeln('10 a partir de 0 : ', flux_ch.readstring(10)); flux_ch.seek(5,soFromBeginning); writeln('10 a partir de 5 : ', flux_ch.readstring(10)); flux_ch.seek(8,soFromBeginning); flux_ch.Write('blabla',2); flux_ch.seek(1,soFromBeginning); writeln(flux_ch.dataString); flux_ch.size := 15; writeln('une taille de 14 : ', flux_ch.dataString); readln; end

program ess_stream1; {$APPTYPE CONSOLE} uses classes,dialogs; var flux_ch: TStringStream; s: string ; pch:pchar; begin pch:='essai'; s:= 'encore'; flux_ch:= TStringStream.Create(''); flux_ch.WriteString(pch); flux_ch.WriteString('suite'); flux_ch.WriteString(s); writeln(flux_ch.dataString); writeln(flux_ch.position); essaisuiteencore 16 10 a partir de 0 : essaisuite 10 a partir de 5 : suiteencor essaisuibl une taille de 14 : essaisuibl ncor
Delphi et Kylix

Remarquez lespace

120

D. Mailliet

MIAGE 2me anne

B.

Flux mmoire
pch:=flux_mem.memory; s:=string (flux_mem.memory) ; SetLength(s,13); // ou s[0]:=chr(13); writeln(s); writeln(pch); writeln(pchar(flux_mem.memory)); writeln(flux_mem.position); flux_mem.seek(8,soFromBeginning); flux_mem.Write('blabla',2); writeln(pchar(flux_mem.memory)); readln; end.

program ess_stream2; {$APPTYPE CONSOLE} uses classes,dialogs; var flux_mem:TMemoryStream; s: string [100]; pch:pchar; b:byte; begin pch:='essai'; s:='encore'; flux_mem:= TMemoryStream.Create; flux_mem.Write(pch^,5); flux_mem. Write('suite',5); flux_mem.Write(s[1],6); b:=0; flux_mem.Write(b,1); essaisuiteenc essaisuiteencore essaisuiteencore 17 essaisuiblencore

C.

Flux fichiers
flux_fic. Write(s[1],6); b:=0; flux_fic. Write(b,1); flux_fic.Free; flux_fic:= TfileStream.Create('essai.txt',fmOpenRead); pch:=StrAlloc(10); flux_fic. read(pch^,9); writeln(pch); flux_fic. read(pch^,9); writeln(pch); StrDispose(pch); flux_fic.Free; readln;

program ess_stream5; {$APPTYPE CONSOLE} uses classes,Sysutils; var flux_fic : TfileStream; s : string [100]; pch : pchar; b : byte; begin pch:='essai'; s:='encore'; flux_fic:= TfileStream.Create('essai.txt',fmCreate);

flux_fic. Write(pch^,5); flux_fic. Write('suite',5);

end.

essaisuit eencore
Delphi et Kilix

121

D. Mailliet

MIAGE 2me anne

XXIX.tude de cas : butineur Web

: TClientSocket composant Internet unit : ScktComp Unit Unit1 ; Interface Uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ScktComp, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; cli_http: TClientSocket; memo: TMemo; Label1: TLabel; procedure h_connecting(sender : tObject;skt :TCustomWinSocket); procedure h_read (sender : tObject;skt :TCustomWinSocket); procedure h_connect(sender : tObject;skt :TCustomWinSocket); procedure h_disconnect(sender : tObject;skt :TCustomWinSocket); procedure h_error (sender : tObject;skt :TCustomWinSocket; ErrorEvent:TErrorEvent; var ErrorCode : Integer); procedure Button1Click(Sender: TObject);
Delphi et Kylix

122

D. Mailliet

MIAGE 2me anne

end;

Var Form1: TForm1;

implementation {$R *.DFM} procedure TForm1.h_connecting(sender : tObject; skt :TCustomWinSocket); Begin memo.lines.add('connexion'); End; procedure TForm1.h_connect(sender : tObject; skt :TCustomWinSocket); Begin memo.lines.add('connecte'); skt.SendText('GET '+ '/'+#10#13); End; procedure TForm1.h_disconnect(sender : tObject; skt :TCustomWinSocket); Begin memo.lines.add('deconnecte'); cli_http.active := False; End; procedure TForm1.h_read (sender : tObject; skt :TCustomWinSocket); Begin memo.lines.add(skt.receiveText); End;

procedure TForm1.h_error(sender : tObject; skt :TCustomWinSocket; ErrorEvent:TErrorEvent; var ErrorCode : Integer); Begin memo.lines.add('Erreur'); ErrorCode := 0; skt.close; End; procedure TForm1.Button1Click(Sender: TObject); begin cli_http.host:=edit1.text; cli_http.active := true;
Delphi et Kylix

123

D. Mailliet

MIAGE 2me anne

end; end. Pour comprendre le fonctionnement : transformons le programme prcdent en une application console

program tsthttp;{$apptype console} uses Classes, Forms ,scktcomp; type Tcmp = class(Tcomponent) cli_http: TClientSocket; constructor create(url:string ); procedure h_connecting(sender : tObject;skt :TCustomWinSocket); procedure h_read (sender : tObject;skt :TCustomWinSocket); procedure h_connect(sender : tObject;skt :TCustomWinSocket); procedure h_disconnect(sender : tObject;skt :TCustomWinSocket); procedure h_error (sender : tObject;skt :TCustomWinSocket; ErrorEvent:TErrorEvent; var ErrorCode : Integer); end; procedure Tcmp.h_connecting(sender : tObject;skt :TCustomWinSocket); Begin writeln('connexion'); End; procedure Tcmp.h_read (sender : tObject;skt :TCustomWinSocket); Begin writeln(skt.receiveText); End; procedure Tcmp.h_connect(sender : tObject;skt :TCustomWinSocket); Begin writeln('connecte'); skt.SendText('GET '+ '/'+#10#13);
Delphi et Kylix

124

D. Mailliet

MIAGE 2me anne

End; procedure Tcmp.h_disconnect(sender : tObject;skt :TCustomWinSocket); Begin writeln('deconnecte'); cli_http.active := False; End; procedure Tcmp.h_error(sender : tObject;skt :TCustomWinSocket; ErrorEvent:TErrorEvent; var ErrorCode : Integer); Begin writeln('Erreur'); ErrorCode := 0; skt.close; End; constructor Tcmp.create(url:string ); Begin inherited create( nil ); // pas de propritaire (owner) cli_http:= TClientSocket.create(self); with cli_http do begin name:=Cli_http'; port:=80; host:=url; clientType := ctNonBlocking; onconnecting:=h_connecting; onread:=h_read ; onconnect := h_connect; ondisconnect := h_disconnect; onerror:=h_error; active := true; end; End; var cmp :tcmp; AD: string ; BEGIN write('URL : http://'); readln(AD); cmp:=tcmp.create(AD); while not cmp.cli_http.active do application.handleMessage; while cmp.cli_http.active do application.handleMessage; writeln; write('Appuyez sur entree pour terminer'); readln; END. La classe Tcmp (drive de la classe TCoMPosant) est instanci en un objet cmp La proprit active indique si la connexion de socket est ouverte et disponible pour la communication avec d'autres machines. Pendant ltablissement de la connexion, celle-ci nest pas active. Elle devient active lorsque la connexion est tablie. Et redevient inactive lorsque la page a t transmise.

Delphi et Kylix

125

D. Mailliet

MIAGE 2me anne

Pendant les 2 premires phases, il faut que lapplication traite les messages qui arrivent pour que les mthodes de cmp puissent ragir aux vnements qui les concernent les 2 boucles aux tests contradictoires

XXX.Annexe 1 : Le langage S Q L
Le SQL (Structured Query Language) permet de crer / grer des bases de donnes. Les requtes SQL peuvent tre dfinies dans plusieurs langages de programmation: Dbase, Java etc. d'o l'utilit de connaitre les bases de ces requtes. Les diffrents types de donnes du SQL Les bases de donnes sous SQL Manipuler des tables SQL Le verbe SELECT est les clauses La clause FROM La clause WHERE La clause ORDER BY La clause GROUP BY La clause HAVING La clause SAVE TO TEMP La clause DISTINCT Remarques sur le format DATE et les combinaison de clauses La clause WHERE et les PREDICATS Le prdicat BETWEEN Le prdicat LIKE Le prdicat IN Remarques sur les sous-interrogation Le prdicat ANY Le prdicat ALL Le prdicat EXISTS Les fonctions SQL / DBASE 4 Les fonctions de DBASE 4 Utilisation du verbe SELECT dans la commande INSERT INTO

1.

Introduction

Pour expliquer le SQL je me base sur Dbase 4 /SQL. Pour pouvoir utiliser SQL sous Dbase 4, vous devez sur la ligne de commande de Dbase tapez la commande: SET SQL ON. pour quitter le mode SQL vous devez taper SET SQL OFF. Passons maintenant au petit lexique du SQL. Au dbut on cre un base donnes. Dans cette base de donnes on cre des TABLES, que l'on pourrait apparenter un fichier en Dbase. Cette table est elle compose de COLONNE que l'on pourrai apparenter des champs en Dbase. 2. Les diffrents types de donnes du SQL

sommaire Quand vous crez une table, vous devez spcifier le type des donnes qui entrerons dans les colonnes. Les types de donnes Type de donne Valeur CHAR Toute chane de 254 caractres max. entoure de " " DATE Toute date au format MM/JJ/AA par dfaut mais peut etre chang avec SET DATE Nombre de 19 chiffres max. (x le nombre total de chiffre, y la place du point dcimal en DECIMAL(x,y) partant de la droite FLOAT(x,y) idem mais + de chiffres INTEGER de - 9999999999 99999999999 LOGICAL .T./.Y. .F./.N. NUMERIC(x,y) idem dcimal SMALLINT de -99999 999999
Delphi et Kylix

126

D. Mailliet

MIAGE 2me anne

3.

Les bases de donnes sous SQL

sommaire Voici toutes les commandes utiles la cration d'une base de donnes et de ses tables sous SQL REMARQUE: faite attention ne pas oublier le point-virgule! Cration de bases de donnes sous SQL Commandes Valeurs permet de crer un repertoire correspondant CREATE DATABASE <nom de la bdf> ; une nouvelle base de donnes SHOW DATABASE; affiche toutes les bases de donnes START DATABASE; ouvre, initialise une base de donnes STOP DATABASE; ferme une base de donnes supprime une base de donnes ( y compris DROP DATABASE <nom de la bdf> ; ses tables), une base de donnes doit tre ferme pour pouvoir tre fface cre une table dans la base de donnes CREATE TABLE <nom de la table> (col1 type taille, col2 type taille, etc.); ouvertes (comme un fichier de base de donnes en Dbase) permet d'ajouter une ou plusieur colonnes ALTER TABLE <nom de table> ADD (col1 type taille, col2 type taille, etc); la table spcifie DROP TABLE <nom de la table> ; permet de supprimer la table indique Exemples: CREATE DATABASE AMIS; START DATABASE AMIS; CREATE TABLE FRIENDS (nom CHAR(30), prenom CHAR(30), cpost CHAR(5), ville CHAR(20),age SMALLINT); STOP DATABASE; Ici nous venons de crer une base de donnes AMIS (ligne 1). On ouvre ensuite cette base de donnes (ligne 2). On y cre une table de nom FRIENDS, qui contient 5 colonnes.(ligne 3) On ferme la base de donne (ligne 4) Et voila, vous venez de voir comment crer une base de donnes en SQL. Nous allons voir maintenant comment manipuler les tables d'une base de donnes SQL (ici la table s'appelle FRIENDS). 4. La manipulation des tables en SQL

sommaire Maintenant si vous avez bien suivi le chapitre prcdent vous avez une base de donne nomme AMIS qui contient une table FRIENDS. Voyons maintenant comment placer des donnes l'interieur de cette table. Insrer des donnes dans les tables: INSERT INTO <nom de table> [(nom col1, nom col2,...)] VALUES (valeur1, valeur2,...); Introduit les valeurs indiques dans les colonnes spcifies de la table. Si les colonnes ne sont pas spcifie, la commande insre partir de la colonne de gauche. Voici un exemple avec notre table FRIENDS, sans spcification de colonnes: INSERT INTO friends VALUES ('Lebout','Thierry','7033','Cuesmes',19); Copie d'un fichier de donnes vers une table SQL: LOAD DATA FROM [chemin d'accs] <nom de fichier> INTO TABLE <nom de la table> Charge les informations du fichier spcifi (Dbase par dfaut) dans une table ayant la mme structure de fichier que le fichier source. On peut dfinir le type de fichier en ajoutant la fin [TYPE DBASE2\DIF\RPD\ETC...]. Voici un exemple, le fichier amigo.dbf doit exister pour que la commande fonctionne, ne l'oubliez si vous voulez essayez cette commande! LOAD DATA FROM C:\DBASE4\amigo.dbf INTO TABLE friends; Copie d'une table SQL vers un fichier de donnes: sommaire UNLOAD DATA TO [chemin] <nom de fichier> FROM TABLE <nom de table> Charge le contenus de la table vers un fichier (par dfaut Dbase 4) qui doit tre de mme structure que la source (on peut aussi spcifier le type de fichier, voir ci-dessus). L'exemple suivant passe les donnes de friends vers amigo: UNLOAD DATA TO C:\DBASE4\amigo.dbf FROM TABLE friends; Afficher le contenus d'une table: SELECT <nom de col1>,<nom de col2>,etc. FROM <nom de table> ; Affiche le contenus des colonnes slectionnes. Si on remplace les noms de colonnes par le symbole * on affiche tous. L'exemple affiche le contenus de notre table FRIENDS. Essayez de rajouter une ligne puis regardez nouveaux: SELECT * FROM friends;
Delphi et Kylix

127

L. Jourdan

MIAGE 2me anne

Remplacer le contenus d'une table: UPDATE <nom de table> SET <nom de col1> = <nouvelle valeur1> etc... [WHERE <condition>]; Remplace les valeurs existantes des colonnes par les nouvelles valeurs indiques. La clause WHERE permet d'ajouter une ou plusieurs conditions. Exemple, la colonne nom et la colonne cpost seront remplae si le nom est Franck: UPDATE friends SET prenom='Albert', cpost='1602' WHERE nom='Lebout'; Supprimer une ligne de la table: sommaire DELETE FROM <nom de table> WHERE <nom col> = <valeur> Supprime une ligne de la table. Exemple: DELETE FROM friends WHERE nom='Lebout'; 5. Le verbe SELECT et les clauses

sommaire Les clauses sont des mots indiquant une table ou un groupe de table sur lesquelles le verbe doit porter. Ici le verbe SELECT permet d'interroger la base de donnes Je vous conseille de bien remplir votre table friends, histoire pouvoire essayez les exemples qui vont suivre. Nous allons maintenant interroger notre table friends. La clause FROM sommaire Elle permet d'indiquer que la commande porte sur la table dont le nom est spcifi juste aprs. Exemple: SELECT * FROM friends; La clause WHERE sommaire La clause WHERE permet d'indiquer une ou plusieurs conditions. Dans l'exemple suivant on verra l'cran les information des personnes de nom Lebout ET dont le cpost est 7033: SELECT * FROM friends WHERE nom='Lebout' AND cpost='7033'; La clause ORDER BY sommaire Cette clause permet de spcifier l'ordre dans lequel les informations seront affiches. Il est possible de voir apparatre les lignes d'une table dans l'ordre ascendant, option ASC (par dfaut) ou descendant option DESC. Exemple, on affiche tous les noms par ordre descendant: SELECT * FROM friends ORDER BY nom DESC; La clause GROUP BY sommaire Elle permet de grouper les lignes d'une table ayant les mme valeurs. Gnralement associe aux fonctions statistiques (SUM,AVG etc.), elle permet d'effectuer des totaux pour les lignes de mme valeur. Pour l'exemple qui suit vous devez avoir plusieur personnes de mme noms dans votre table: SELECT nom,SUM(age) FROM friends GROUP BY nom; Dans cet exemple on groupe les lignes par nom et on effectue la somme des ges des personnes portant le mme nom, pour chaque nom. La clause HAVING sommaire Cette clause est gnralement utilise si la clause GROUP BY a t spcifie. En effet, HAVING permet de dfinir une condition sur l'ensemble des lignes groupes par la clause GROUP BY, au mme titre que la clause WHERE permet de dfinir une conditions sur les lignes de la tables. Exemples: SELECT nom,SUM(age) FROM friends GROUP BY nom HAVING SUM(age)>20; Dans cet exemple on groupe les lignes par nom et on effectue la somme des ges des personnes portant le mme nom, pour chaque nom. Mais en plus il faut, pour tre affich, que la somme de ces ges soient suprieur 20. La clause SAVE TO TEMP sommaire Cette clause permet de crer une nouvelle table a partire de la commande select. Le rsultat de la slection est enregistr dans une table pour laquelle il est possible de dfinir un nom et ventuellement des nouveaux nom pour les colonnes. Cette disparatra au changement de base de donnes. Avec l'option KEEP, un fichier Dbase (avec extention .DBF) est cr, de sorte qu'il est possible de manipuler directement les rsultats partir de Dbase 4. Syntaxe: SAVE TO TEMP <nom de table> (nom col1, nom col2, etc)] [KEEP]; Exemple: SELECT nom,prenom,age FROM friends ORDER BY prenom DESC SAVE TO TEMP friends_2(nom_per,prenom,age); Cette exemple cre donc une table temporaire FRIENDS_2, dans laquelle ont trouve le nom, le prenom et l'age. Remarquez que la 1er colonne change de nom au passage. La clause DISTINCT sommaire
Delphi et Kylix

128

L. Jourdan

MIAGE 2me anne

Cette clause permet d'afficher toutes les lignes distinctes de la table. Les informations redondantes ne seront pas affiches (les lignes identiques). Exemples: SELECT DISTINCT nom FROM friends; Tous les nom diffrent de la tables seront affichs 6. Remarques sur le format DATE et les combinaison de CLAUSES:

sommaire Pour utiliser le format date comme condition avec un WHERE on place la date entre { et }. Exemple, imaginons que nous aurions dans notre table friends une colonne annee, reprsentant par exemple une date de naissance: SELECT nom,prenom,age FROM friends where annee >={01/01/85}; Ici la condition est donc que le contenu de la colonne annee soit plus grand ou gal au 01/01/85. Il existe un ordre pour les clauses: 1. La clause GROUP BY vient immdiatement aprs la clause FROM, s'il n'existe pas de WHERE, sinon elle vient aprs cette dernires; La clause HAVING se place toujours aprs la clause GROUP BY; La clause ORDER BY est toujours la dernire clause dans une command SELECT. Mais doit tre avant la clause SAVE TO TEMP si cette dernire existe; La clause DISTINCT doit toujours se placer avant la liste de colonnes de la table slectionner.

2. 3.

4.

7.

La clause WHERE et les PREDICATS

sommaire Voici des autres prdicats (autre que <, >, <=, >=, <>) permettant de dfinir une conditions dans la clause WHERE: ALL - ANY - EXISTS - BETWEEN - IN - LIKE Le prdicat BETWEEN sommaire Le prdicat BETWEEN permet de dfinir une borne infrieure et une borne suprieure utilise pour une condition, BETWEEN veux dire ENTRE borne1 et borne2, l'utilisation de NOT permet de faire une condition "si le nombre ne se trouve pas dans les limites de BETWEEN". Exemples: SELECT nom,prenom FROM friends WHERE age BETWEEN 17 AND 25; SELECT nom,prenom FROM friends WHERE age NOT BETWEEN 17 AND 25; Le prdicat LIKE sommaire Le prdicat LIKE permet de faire une comparaison entre une colonne et une chaine de caractres. Remarque, on peut utiliser les symboles suivants: % qui reprsente une chaine de caractere ( * en MS-DOS) _ qui reprsente un caractre ( ? en MS-DOS)

On peut galement utiliser le NOT pour inverser la condition. Exemple pour afficher tous les nom commenant par 'LE': SELECT nom,prenom FROM friends WHERE nom LIKE 'LE%'; Exemple pour afficher tous les nom ne commenant pas par la lettre j de 6 lettres: SELECT nom,prenom FROM friends WHERE nom NOT LIKE 'j_ _ _ _ _'; Le prdicat IN sommaire Ce prdicat permet de tester si l'information d'une colonne se trouve dans une liste de valeurs, celles-ci tant indiques derrire le prdicat lui- mme. Cette liste se trouve entre parenthses et chaque lments entre cote ou double cote spars par une virgule, ou par OR. On peut galement effectuer le test inverse grace NOT. Exemples: SELECT nom,prenom FROM friends WHERE nom IN ('lebout','dehut'); SELECT nom,prenom FROM friends WHERE nom NOT IN ('lebout','dehut'); Remarques sur les sous-interrogation sommaire La commande SELECT permet d'interroger une base de donnes; c'est une commande d'interrogation. Un verbe SELECT dans une commande SELECT est donc une sous-interrogation. Les 3 prdicats suivant sont gnralement utilis dans une sous-interrogation (ANY - ALL - EXISTS). Syntaxe d'une sous interrogation:
Delphi et Kylix

129

L. Jourdan

MIAGE 2me anne

SELECT <liste de colonnes> FROM <table> WHERE (SELECT... sous-interrogation); Le prdicat ANY sommaire Le prdicat ANY ressemble beaucoup au prdicat IN. La diffrence tant que la liste de valeurs est fournie implicitement par une sous- interrogation. La comparaison de l'information avec la liste doit tre vraie pour au moins une des valeurs. Pour cet exemple on doit crer une nouvelle table, ayant en commun avec la table friends une colonne. Imaginons une table cops avec comme colonne commune nom et une nouvelle table rue, placez enfin dans la nouvelle colonne nom un nom dj prsent dans la table friends, plusieurs fois avec des rues differentes. Plac maintenant d'autre nom prsent dans la table friends. Voici un exemple de sous-interrogation: SELECT nom,prenom FROM friends WHERE nom = ANY (SELECT nom FROM cops WHERE rue='rue des iris'); Dans cet exemple on affiche l'information (nom et prenom) si le nom est gal au nom d'une personne habitant la rue des iris dans la table cops. On remarque que le lien entre les deux tables est fait avec la colonne nom. Le prdicat ALL sommaire Si ANY retourne vrai si un lment de la liste satisfait la condition, ALL demande ce que TOUTE la liste rponde la condition. Exemple: SELECT nom,prenom FROM friends WHERE nom <> ALL (SELECT nom FROM cops WHERE rue='rue de wasmes'); Ici on affichera le nom et prenom des personnes de la table friends, n'habitant pas la rue de wasmes. Le prdicat EXISTS sommaire Le prdicat EXIST permet de vrifier l'existence d'une information dans une sous-interrogation. Pour chaque information existant dans la sous- interrogation, la commande SELECT de l'interrogation affichera les informations des colonnes demandes. L'exemple suivant fait entrer en jeux le terme d'ALIAS, il s'agit de la marque que l'on place devant des noms de colonnes identique de table diffrente pour les diffrencier. SELECT nom,prenom FROM friends WHERE EXISTS (SELECT nom FROM cops WHERE friends .nom = auto.nom); Ici on affichera le nom et prenom des personne de la table friends, dont le nom se trouve galement dans la table cops. On peut galement utiliser l'oprateur logique NOT pour effectuer la condition inverse (non-existence) donc NOT EXISTS. 8. Les fonctions SQL/DBASE IV

sommaire Dans une commande SELECT il est possible d'utiliser des fonctions mises la disposition de l'utilisateur par SQL/DBASE 4. Ces fonctions (au nombre de six) effectuent des oprations sur les informations des colonnes dsignes la suite du verbe SELECT, fonctions qui peuvent galement porter sur un groupe de lignes dfini par une condition ventuelle. Les fontions SQL/DBASE 4 Fonctions AVG (<nom d'une colonne>) COUNT(DISTINCT <nom de colonne>) COUNT(*) SUM(<nom de colonne>) MAX(<nom de colonne>) MIN(<nom de colonne>) Actions Effectue la moyenne arithmtique des informations dsignes Comptabilise le nombre de ligne diffrentes (clause distinct) de la colonne spcifie Comptabilise le nombre de ligne de la table. Ce nombre comprend d'ventuelles valeurs gale. Renvoie la somme des information de la colonne spcifie Renvoie un nombre correspondant la valeur maximale de la colonne spcifie Renvoie un nombre correspondant la valeur minimale de la colonne spcifie

Exemples: sommaire Voici plusieurs exemples reprenant les fonction ci-dessus: SELECT AVG(age) FROM friends; SELECT SUM(age) FROM friends; SELECT COUNT(*) FROM friends; SELECT MIN(age) FROM friends; SELECT MAX(age) FROM friends; SELECT COUNT(DISTINCT nom) from friends;

Delphi et Kylix

130

L. Jourdan

MIAGE 2me anne

9.

Les fontions Dbase 4

sommaire La pluspart des fonctions DBASE IV sont utilisable sous SQL. Il est tout a fait permis de combiner des fonctions SQL/DBASE 4 et les fonctions propre Dbase 4, exemples: CDOW( ) retourne le jour de la semaine indique en toutes lettre: SELECT annee,CDOW(annee) FROM friends; LOWER( ) convertit une chaine de caractres majuscules en minuscules: SELECT nom,LOWER(prenom) FROM friends; 10. Utilisation du verbe SELECT dans la commande INSERT INTO

Le verbe SELECT peut galement tre utilis dans la commande INSERT INTO de la manire suivante: INSERT INTO <nom table> [(nom col1, nom col2)] SELECT [(nom col1, nom col2)] FROM <nom table 2> [WHERE <condition>]; Il doit y avoir correspondance entre les diffrents noms de colonnes des deux tables. Exemple: Aprs avoir crer une table friends2 on fait: INSERT INTO friends2 (nom,prenom,age,cpost) SELECT (nom,prenom,age,cpost) FROM friends WHERE nom='Lebout'; Ici entre les informations de la table friends dans la table friends2 si le nom = Lebout

XXXI.Annexe 2 : Dploiement
Les applications Delphi simples, constitues d'un seul fichier excutable, s'installent facilement sur un ordinateur cible. Il suffit de copier le fichier sur l'ordinateur. Mais les applications plus complexes composes de plusieurs fichiers exigent une procdure d'installation plus sophistique. De telles applications ncessitent un programme d'installation spcifique. Les botes outils d'installation automatisent le processus de cration d'un programme d'installation, le plus souvent sans avoir besoin d'crire une seule ligne de code. Les programmes d'installation crs par les botes outils d'installation effectuent diverses tches lies l'installation des applications Delphi, y compris la copie de l'excutable et des fichiers ncessaires sur l'ordinateur cible, la cration des entres de registre Windows et l'installation du moteur de bases de donnes Borland pour les applications de base de donnes. InstallShield Express est une bote outils d'installation fournie avec Delphi. InstallShield Express est spcialement adapt l'utilisation de Delphi et du moteur de bases de donnes Borland. InstallShield Express n'est pas install automatiquement lors de l'installation de Delphi, et doit tre install manuellement afin de pouvoir crer des programmes d'installation. Excutez le programme d'installation du CD Delphi pour installer InstallShield Express. D'autres botes outils d'installation sont disponibles, cependant vous ne devez utiliser que celles certifies pour dployer le moteur de bases de donnes Borland (BDE).

A.

Utilisation d'installShield

Lancez InstallShield, choisissez "crer un nouveau projet d'installation"

Donnez les renseignements suivants : Le Nom du projet (= nom du fichier.iwz qui contiendra tous les renseignements propre l'installation). En ouvrant ce fichier partir d'InstallShield, vous pourrez facilement regnrer une procdure d'installation suite une mise jour de votre programme. Le dossier o se mettra ce fichier .iwz ( l'aide de "Lecteur", "Rpertoire" et ventuellement de "Nouveau sous-rpertoire" Cliquez sur crer Delphi et Kylix 131 L. Jourdan

MIAGE 2me anne

Cliquez sur "Groupes et Fichiers

Delphi et Kylix

132

L. Jourdan

MIAGE 2me anne

Cette partie d'InstallShield va vous permettre de slectionner les fichiers joindre l'installation (exe, dll, ocx, ini etc)

Chaque groupe correspond un dossier de destination lors de l'installation. Pour ajouter un groupe, cliquez sur "Nouveau groupe". Diffrents rpertoires de destination sont pr-informs. Par exemple, <WINSYSDIR> correspond, en Win 98 et pour une installation standard de Windows c:\windows\system <INSTALLDIR> correspond au rpertoire de destination du programme l'installation

Delphi et Kylix

133

L. Jourdan

MIAGE 2me anne

Si vous utilisez des ActiveX dans votre programme, il faut que le poste o se droulera l'installation recense cette ActiveX. Pour cela, se placer sur le fichier contenant l'ActiveX (ocx, dll..) puis faire proprits et vrifier que la case "Permet Express d'autorecenser ce fichier" est coche.

Faire OK et Cliquez sur Gnrateur de disques

Delphi et Kylix

134

L. Jourdan

MIAGE 2me anne

Indiquez la taille du support qui vous servira l'implantation du programme sur le poste o vous dsirez faire l'installation. Par exemple, si vous souhaitez passer par des disquettes pour effectuer l'installation, choisissez 1.44MB

Cliquez sur Gnrer

Vous pouvez alors cliquer sur Excuter le test pour voir comment se droulera l'installation (vous pourrez ultrieurement dsinstaller en passant par le menu dsinstaller de Windows.

Pour gnrer les disquettes, cliquez sur "Copier sur disquettes". Vous avez galement une image de ces disquettes dans un sous dossier de votre dossier contenant votre fichier projet InstallShield.

B.

Complments

Si, dans votre programme, vous faites appel au BDE (Moteur de base de donnes Borland), cliquez sur Options Gnrales

et slectionnez le BDE

Delphi et Kylix

135

L. Jourdan

MIAGE 2me anne

Si l'application utilise des paquets d'excution, il faut distribuer les fichiers paquet avec l'application. InstallShield Express gre l'installation des fichiers paquet de la mme manire que les DLL, copie ces fichiers et cre les entres ncessaires dans les registres Windows. Borland recommande l'installation des fichiers paquet d'excution d'origine Borland dans le rpertoire Windows\System. Cela sert d'emplacement commun afin que plusieurs applications puissent accder une seule instance de ces fichiers. Pour des paquets personnaliss, il est recommand de les installer dans le rpertoire de l'application. Seuls les fichiers .BPL doivent tre distribus.

Si vous distribuez des paquets d'autres dveloppeurs, fournissez les fichiers .BPL et .DCP.

Delphi et Kylix

136

L. Jourdan

MIAGE 2me anne

XXXII.Annexe 3 : Notion d interfaces hommes-machines


In tro d u ctio n : L' Interface Homme-Ordinateur (IHO) englobe tous les aspects des systmes informatiques qui influencent la participation de l'utilisateur des tches informatises. Les aspects immdiatement observables sont bien sr l'environnement physique du travail et le matriel constituant le poste de travail. Ces aspects sont peut tre les mieux connus, car tudis depuis plus longtemps, mais ce ne sont pas les seuls, ni les plus importants. D'autres aspects, plus subtils, concernent les diverses faons dont les informations sont stockes et manipules. Ceci inclut les procdures informatiques, mais aussi les outils annexes, tels les documents papier, les aides au travail, etc. Par opposition d'autres machines qui reprsentent des extensions du corps humain, par exemple qui fournissent des capacits physiques et une puissance supplmentaires, l'ordinateur, et en particulier le logiciel, reprsente plutt une extension du cerveau humain, en faisant appel des processus plus cognitifs (e.g., perception, mmoire, langage, rsolution de problmes, prise de dcision, etc.).

A.

Les grands principes

Linterface offre une reprsentation permettant lchange dinformations entre lutilisateur humain et la machine. La conception dune interface fait intervenir : Lhomme (sciences cognitives) La machine (informatique) Lergonomie (interaction des deux) Pour des aspects gnraux de la conception des interfaces, on peut identifier un certain nombre de principes ergonomiques respecter. Linterface doit rduire les efforts de lutilisateur et rpondre aux principes suivant : Compatibilit Homognit Concision Flexibilit Feedback, Guidage Charge informationnelle Contrle explicite Gestion des erreurs

Les IHM doivent tre valides : Prototypage, maquettage graphique Tests dergonomie De faon gnrale, on peut dire qu'il est essentiel de respecter les objectifs, connaissances, reprsentations et mthodes des utilisateurs. Nous allons dabord regarder un un, les principes ergonomiques : 1. Compatibilit Le principe de compatibilit repose sur le fait que les transferts d'information seront d'autant plus rapides et plus efficaces que le recodage d'information est rduit. Il faut donc au maximum utiliser la connaissance de lutilisateur : cran compatible avec un support papier existant Dnomination de commandes tire du vocabulaire de lutilisateur
Delphi et Kylix

137

L. Jourdan

MIAGE 2me anne

Adopter un style dinterface commun dautres produits Il faut aussi raisonner en terme de tche utilisateur et faciliter le passage dune tche une autre (multi fentrage). 2. Homognit

Elle repose sur une logique dutilisation. Il convient de prsenter les informations de mme nature de faon consistante Lobjectif tant de rendre le comportement du systme prvisible, de diminuer le temps de recherche dune information, de faciliter la prise dinformation. 3. Concision La mmoire court terme tant limite, il convient dviter lutilisateur de mmoriser des informations longues et nombreuses 4. Flexibilit (souplesse) Linterface doit tre capable de sadapter aux diverses populations dutilisateurs. Par exemple, offrir plusieurs moyens datteindre un objectif (acclrateur, raccourci clavier ...) Loutil doit sadapter lhomme et non linverse. 5. Feedback et guidage Lutilisateur doit toujours tre inform du rsultat dune action connatre ltat du systme savoir comment poursuivre le dialogue

Lexemple suivant (fig 1), donn par word, nous donne un feedback sur notre document word.

fig 1 : un exemple de feedback Linterface peut le guider par messages davertissement, aide en ligne : guidage explicite diffrenciation typographique (police, couleur) , structuration de laffichage : guidage implicite

fig 2 : Message davertissement Lobjectif tant de faciliter lapprentissage du logiciel, daider lutilisateur se reprer et choisir ses actions, et de prvenir les erreurs. 6. Charge informationnelle La probabilit derreur humaine augmente avec la charge, il faut donc : Minimiser le nombre doprations effectuer, par exemple en entre (ex. valeurs par dfaut) Minimiser le temps de traitement afin de rduire le temps dattente de lutilisateur 7. Contrle explicite

Mme si le logiciel a le contrle, linterface doit apparatre comme tant sous le contrle de lutilisateur : par exemple, lexcution dune opration ne doit se raliser que sur une action explicite de lutilisateur. 8. Gestion des erreurs Lutilisateur doit avoir le moyen de corriger ses erreurs (commande Annuler) Le systme doit dtecter des erreurs de faon prventive (contrle des entres) 138 L. Jourdan

Delphi et Kylix

MIAGE 2me anne

Lobjectif de ce principe est de favoriser lexploration et lapprentissage du logiciel par lutilisateur en permettant un systme lui autorisant les changements de dcision de lutilisateur.

B.

Quelques exemples dergonomie

Favoriser les mtaphores Bureau Objets reprsents par des icnes Oprations la souris, drag and drop Limiter le texte lire Articles de menus courts et explicites Nombre darticles limit par menu Une bote de dialogue doit mettre en valeur la source, le type et limportance dun message (information, erreur, etc.) 1. Utilisation de la couleur Lemploi de la couleur est dlicat, son utilisation abusive peut tre nfaste. Il faut donc : tre cohrent avec les associations habituelles (ex. feux tricolores) Limiter le nombre de couleurs viter certains couples de couleurs reconnus comme causant une sollicitation excessive de la rtine (rouge/bleu, jaune/violet, jaune/vert) 2. Prsentation des textes

Un texte crit en minuscules se lit beaucoup plus vite quun texte en majuscules UN TEXTE CRIT EN MINUSCULES SE LIT BEAUCOUP PLUS VITE QUUN TEXTE EN MAJUSCULES Souligner de longs mots rduit la lisibilit : Un texte crit en minuscules se lit beaucoup plus vite quun texte en majuscules. La vitesse de lecture en majuscules a t estime 13% plus lente quen minuscules, ceci provenant dune diffrenciation plus forte des minuscules que des majuscules La lecture dun texte est amliore si la longueur dune ligne est suprieure 26 caractres Il existe beaucoup dautres exemples, vous pouvez trouver une guide de style ainsi que plusieurs outils : http://deptinfo.cnam.fr/Enseignement/CycleSpecialisation/IHM/Cours/index.htm

C.

Causes et consquences

Les dfauts de conception de l'IHO rsultent en gnral de diverses erreurs qui tiennent des croyances. Deux d'entre elles sont encore trop communes. La premire erreur est de croire que des amliorations pour l'utilisateur seront issues uniquement des progrs technologiques, alors que chaque nouvelle technologie (e.g., les crans ou la commande vocale) fait surgir de nouveaux problmes (e.g. disposition spatiale des informations ou entranement du locuteur) par rapport la technologie prcdente (respectivement les tltypes ou les claviers). La seconde erreur est de penser que pour concevoir des logiciels ergonomiques, il suffit d'y rflchir un peu. Or on sait bien que l'introspection dans ce domaine, surtout propos de phnomnes cognitifs complexes, ne donne pas de bons rsultats. Deux des consquences de ces croyances sont que souvent les concepteurs ne connaissent pas suffisamment bien les tches qu'ils sont supposs informatiser, et qu'ils ne ralisent pas l'effort, ou ne connaissent les mthodes appropries ncessaires pour obtenir cette connaissance. Une autre consquence est que les concepteurs ont souvent tendance fournir aux utilisateurs tout ce quoi ils peuvent penser. Malheureusement, fournir dix mauvais outils n'est pas meilleur que de n'en proposer qu'un seul qui soit bien adapt. L'organisation des quipes de conception ainsi que les contraintes de temps sont aussi des facteurs importants dans les erreurs de conception. Le fait que le logiciel soit implment par des individus qui ne partagent pas ncessairement la mme vue des procdures oprationnelles dsires peut conduire des interfaces non homognes, voire incompatibles. Quand un utilisateur doit effectuer des tches avec des procdures diffrentes, ou pire, quand il doit effectuer diffremment des transactions conceptuellement similaires au sein d'une mme tche, une contrainte non ncessaire lui est impose pour l'apprentissage et l'utilisation du systme. Quand plusieurs systmes sont dvelopps au sein d'une grande entreprise et Delphi et Kylix 139 L. Jourdan

MIAGE 2me anne

quand la conception de l'IHO est tablie indpendamment pour chaque systme, le rsultat est souvent d'imposer des comportements incompatibles des utilisateurs qui pourront avoir utiliser plusieurs systmes, ou tout simplement communiquer avec d'autres utilisateurs qui ont besoin de cooprer vers le mme objectif. Les dfauts de conception de l'IHO conduisent une performance dgrade des systmes. Les utilisateurs peuvent parfois compenser une mauvaise conception par des efforts supplmentaires. Cependant, il y a une limite l'adaptation des utilisateurs une mauvaise interface. L'effet ngatif cumul rsultant de plusieurs erreurs de conception peut conduire des dysfonctionnements des systmes, des performances insatisfaisantes, et des plaintes des utilisateurs. Cela peut aussi conduire : - une non-utilisation du systme et au recours d'autres sources d'information; - une diminution de l'utilisation quand celle-ci est optionnelle et une rgression des procdures manuelles; - mauvaise utilisation, contournement des rgles du systme pour court-circuiter les difficults rencontres pour raliser une opration; - utilisation partielle, utilisation seulement d'un sous-ensemble des capacits du systme; - emploi d'un intermdiaire entre l'utilisateur et le systme (conduite typique des managers); - modification de la tche; - activits compensatoires, oprations supplmentaires ou dtournes; - frustration, dsintrt, rejet, taux d'erreurs levs, performance faible, etc. Cela signifie bien entendu des oprations interrompues, du temps, des efforts et des investissements perdus, et l'chec vis -vis des avantages potentiels de l'informatisation. Par ailleurs, le passage de procdures manuelles l'informatique peut aussi signifier en fait deux fois plus de temps ncessaire pour mener des tches leur terme en raison de dficiences dans la conception de l'IHO (en effet, dans certains cas, la tche est double, i.e., qu'il y a conservation de la procdure manuelle en plus de la procdure informatise).

D.
1.

Liens intressants
Microsoft Windows

http://msdn.microsoft.com/library/books/winguide/fore.htm

2.

OSF/Motif

http://www.bgu.ac.il/ebt-bin/nph-dweb/dynaweb/SGI_Developer/Motif_SG/@Generic__BookView 3. Les recommandation Afnor

Afnor Paris Z67-110 : Ergonomie et conception du dialogue homme-ordinateur, janvier 1998. Afnor Paris Z67-133-1 :Dfinition des critres ergonomiques de conception et dvaluation des produits logiciels

Delphi et Kylix

140

L. Jourdan

MIAGE 2me anne

XXXIII. Les TPs


Cette parite contient les TP qui seront effectus lors des scances en salle machine. Les TP sont toujours terminer dune scance sur lautre.

A.

TP1 DELPHI : Nos Premiers pas

Objectif : Initiation aux cinq tapes essentielles au dveloppement dun projet en Delphi. 1- Crer un projet 2- Ajouter des composants 3- Modifier leurs proprits 4- Ajouter des ractions aux vnements 5- Excuter ce que lon a fait

A ce point il est trs important, voir mme vital , de comprendre le principe du raisonnement qui mne la construction d'un programme. Il faut toujours se poser la question suivante: Je veux qu'il se passe quoi, lorsque quel vnement se produit sur quel objet ? Rpondre ces trois questions est obligatoire. Si un doute subsiste concernant ne serait-ce qu'une de ces trois questions, alors le principe mme de la ralisation d'applications Windows avec Delphi est fortement compromis.

1.

Exemple 1

But : Crer un bouton ayant pour titre ATTEND qui se transforme en CLIC aprs avoir cliqu dessus. Crer un nouveau projet (par dfaut) Enregistrer dans un rpertoire (un rpertoire par projet) Il faut utiliser la commande Fichier | Enregistrer projet. Unit cre .PAS (par exemple main pour indiquer que cest le programme principal) Projet .DPR (par exemple exemp le1). a) Lancer lexcution

Excuter | Excuter ou F9 ou w Rsultat : fentre vierge que vous pouvez dplacer, agrandir, rduire, minimiser . Arrter lapplication : double clique sur le menu systme - ou ALT+F4 ou fermeture du menu systme b) c) Ajout de composant Modifier les proprits

Il suffit de prendre un composant dans la palette des composants et de le dposer sur la fiche. Slectionner un composant Name (proprit dun objet : nommer lobjet ; cette proprit correspond lidentificateur du composant pour le programme) Caption (proprit dun objet : crire un nom sur lobjet) : Ecrire sur le bouton : ATTEND Nommer la fentre Premier exercice d) Ajouter des ractions des vnements

Nous dsirons ragir au clic de lutilisateur sur le composant, on choisit le composant et on regarde dans longlet vnement de lobjet. Slection dun composant + choix dun vnement (ici On Click ) Nous allons crer une mthode : double-clic sur la partie valeur de On Click . Ceci saffiche dans le corps de la procdure : L. Jourdan

MIAGE 2me anne

procedure TForm1.Button1Click(Sender: TObject); begin end; end. Nous dsirons que lorsquon clique le bouton naffiche plus ATTEND mais Clic : procedure TForm1.Button1Click(Sender: TObject); begin Button1.Caption := Clic ; end; end. Exercice 1 : Crer un projet avec une fentre de titre Premier exercice contenant un seul bouton intitul Actif . Lorsque vous appuierez sur ce bouton, son titre deviendra Gris et le composant sinvalidera (proprit Enable). 2. Exemple 2

But : Cet exemple va nous conduire manipuler 2 boutons et les faire interagir. Le premier bouton sera un compteur (didentificateur compteur) qui comptabilisera le nombre de clics effectus dessus et le visualisera dans son titre, tandis que le second bouton permettra de remettre ce compteur zro.

Pour cela vous avez besoin des fonctions de transtypage : InttoStr et StrToInt. Il faut donc transformer en nombre (StrToInt) pour lui ajouter un et le remettre en texte ensuite (IntToStr).

Exercice 2 : Dsactivez le bouton RAZ quand le compteur est zro. Etapes : Invalider le bouton RAZ la construction Activer le bouton RAZ lorsque lon clique sur le compteur Invalider le bouton RAZ lorsque lon clique dessus

Exercice 2(Bis) : De la mme faon, rendez invisible le bouton RAZ quand le compteur est zro.

Exercice 3 : Crer une fentre contenant 2 boutons qui sont visibles tour tour (un clic sur le premier bouton fait disparatre ce bouton et apparatre le second bouton et ainsi de suite).

Delphi et Kylix

142

L. Jourdan

MIAGE 2me anne

De plus, on ne doit pas pouvoir agir sur la taille de la fentre (composant BorderStyle).

Exercice 4 :

Avec

+ qui incrmente de 5 ;

- qui dcrmente de 5 et est invisible quand il ne peut tre utilis; le compteur ne doit pas devenir ngatif ; RAZ remet 0 et est invisible quand on ne peut pas lutiliser.

Exercice 5 : Lister les proprits des objets de lexercice prcedent et trouver celle qui pemet dempcher de resizer le fentre.

Exercice 6 : Question de dcallage

On veut pouvoir rordonner le pav numrique, un clic sur un nombre (nimporte lequel) provoque un dcalage comme suit :

Delphi et Kylix

143

L. Jourdan

MIAGE 2me anne

Faite-le de manire intelligente !!!!!! Exercice 7 : Utilisation de laide Delphi et fonction format Vous rechercherez dans laide Delphi la fonction format . Vous noterez ses spcifications (Attention toute fonction vue en TP est considre comme connue !). Vous raliserez de 2 faons diffrents laffichage de la phrase suivante : Il y a 7 jours dans 1 semaine. sans que votre fiche ne contienne directement la phrase J.

B.

TP2 DELPHI : Quelques composants standards

Boutons (Button) Botes listes (ListBox) Saisies (Edit) Menus principaux (Main Menu) Botes de dialogues standards (OpenDialog et SaveDialog) 1. Exemple 2

But : Cration dun rpertoire tlphonique Fiche = une bote liste (ListBox) des noms et numros de tlphone + Une saisie (Edit) pour ajouter un nouveau numro + Deux boutons (Buttons) pour ajouter la saisie dans la liste et pour effacer les numros slectionns dans la liste Unit principale : main Projet : Exemple3 Etape 1 : placer les composant et changer le titre pour obtenir la fentre standard suivante :

Nommer la liste Liste + mettre la proprit Align alTop pour que la liste se redimensionne en mme temps que la fiche. Nommer la saisie Edition + proprit text pour leffacer Etape 2 : Ajouter les ractions aux vnements Appuyer sur le bouton Ajouter qui ajoutera la zone de saisie dans la liste Appuyer sur le bouton Enlever qui enlvera la slection de la liste Contraintes : On ne peut ajouter le contenu de la zone de saisie dans la liste que si elle nest pas vide. On ne peut enlever la slection de la liste que si elle existe.
Delphi et Kylix

144

L. Jourdan

MIAGE 2me anne

Etat au dmarrage : Edition est vide _ bouton Ajouter gris liste est vide _ bouton Enlever gris i.e : Enable := False Activer et dsactiver le bouton Ajouter Evnement OnChange de Edition Mthode Editionchange Ajouter.Enabled := Edition.texte <> ; Ajouter le contenu de l Edition dans la liste : Evenement OnClick Liste.Items.Add(Edition.text) ; Les autres mthodes sont delete, exchange, Move, selected. Le bouton Enlever Evnement OnClick Ajouter Enlever.Enabled := True; Evenement OnClick Enlever Liste.Items.delete(Liste.ItemIndex); If Liste.Items.Count =0 then Enlever.Enabled := False; On aimerait bien sr pouvoir sauvegarder ce qui a t fait : on se rfrera au chapitre base de donnes. Amlioration : Les personnes rpertories classes par ordre alphabtique. Proprit sorted de liste = True Remarque : Bouton par dfaut (mis en action par la touche entre : Default = True) Pour avoir le raccourci clavier (Alt + lettre) sur le nom dun objet ajouter & devant le nom dans la proprit caption. Exercice 3 : Nouvelle fonctionnalit : modification dun lment existant Lorsque lutilisateur cliquera sur un lment de la bote liste, llment apparatra aussi dans la saisie que lon pourra modifier librement puis la reporter dans la liste en cliquant sur un nouveau bouton modifier. Exercice 4 : Ralisation dune calculatrice de base Dans cette premire tape, il faut effectuer les actions suivantes: placer l'affichage de la calculatrice sous forme d'un Label (par exemple criture vert fluo sur fond noir, Arial 14 Pts gras, justifi droite). Placer les boutons Ragir aux boutons numriques et aux boutons de calcul du rsultat Utiliser une mme fonction pour les boutons numriques (cf. aide jointe) : on choisit dans lvnement onClick de lobjet la fonction dfinie

Delphi et Kylix

145

L. Jourdan

MIAGE 2me anne

Sender reprsente l'"expditeur", ou l'objet qui est l'origine de l'appel de la mthode. Pascal tant strict au niveau de la compatibilit des types, Sender est dclar comme tant de type Tobject. Tobject tant l'anctre de tous les objets Delphi, la compatibilit est assure. Il faut toutefois utiliser le transtypage: (Sender as Tbutton) afin d'accder effectivement l'objet dsir. Cette expression est totalement quivalente sept lorsque le bouton "sept" t cliqu ou deux lorsque le bouton "deux" t cliqu. Donc l'expression: (Sender as Tbutton).caption fournit le texte associ au bouton sur lequel l'utilisateur a cliqu. La concatnation avec le texte existant dans l'affichage permet de construire de nombre. A l'aide de ce transtypage il est possible d'accder toutes les proprits et mthodes de l'objet vis. Rappelons que nous parlons d'objets, mais c'est un abus de langage (du en partie la notation employe par Delphi). En ralit, il s'agit de pointeurs vers des objets. Remarque: Le langage Pascal (Turbo Pascal ou Delphi) autorise en principe le transtypage sous la forme: TButton (Sender) Ou encore, par exemple: Integer ('A') Mais cette forme de transtypage n'effectue aucune vrification. Si l'on crit: Tbutton (Sender).Text := 'OK' Il n'y a pas de vrification qu'un bouton ne possde pas de proprit Text. En revanche, la forme: (Sender as TButton).Text := 'OK' vrifie que Sender est bien du type Tbutton, sinon une exception est dclenche. Il convient donc d'utiliser cette dernire forme d'criture. Il est bien entendu possible et souhaitable d'utiliser la forme: With Sender as Tbutton do begin Caption := 'OK'; Top := 120; End; Afin d'viter de provoquer des exceptions en cas d'erreur, il est prfrable de tester la validit l'aide de "is". Voici un exemple: If Sender is Tbutton then (Sender as Tbutton).caption := 'a marche'; Grce cette forme d'criture il est possible d'crire une mthode appele par des objets de type diffrents et de diffrencier le traitement: If Sender is Tbutton then (Sender as Tbutton).caption := 'a marche'; If Sender is TEdit then (Sender as TEdit).Text := 'a marche'; procedure TForm1.ListeClick(Sender: TObject); begin { on a cliqu sur un lment de la liste, il est maintenant slectionn, on reporte la chaine dans le composant 'Edition' } Edition.Text := Liste.Items[Liste.ItemIndex]; { on donne maintenant la possibilit de modifier en activant le bouton Modifier } Modifier.Enabled := True; end;

C.

TP3 DELPHI : Quelques composants standards (suite)

Delphi et Kylix

146

L. Jourdan

MIAGE 2me anne

1.

Exemple 3

But : Crer un diteur de texte simple Crer des (MainMenu) et ragir leurs commandes Utiliser les botes de dialogue OpenDialog et SaveDialog pour ouvrir des fichiers et les enregistrer Cration dun projet : caption=Editeur Ajout dun mmo : Composant (Memo ) dans la fiche Proprit Align = alClient (indique que le mmo doit remplir la place utile de la fentre mme si cette dernire est redimensionne) Name = Edition Text = BorderStyle = bsSingle ou bsNone Barre de dfilement (Scrollbar) Scrollbars = scBoth scHorizontal, scVertical, ScNone

Cration dun menu MainMenu : une entre Fichiers ayant plusieurs commandes : Ouvrir Enregistrer sous Quitter une entre Recherche pour Rechercher et Remplacement Proprit Item (Rappel : double Clic sur le composant) &Fichier suivi dentre (rappel : & permet de souligner et de dfinir la lettre servant de raccourci pour les menus). Remarque : pour sparer les entres dun menu par un trait, il suffit de crer une entre de Caption = -

Rpondre aux commandes du menu : Mthode de raction au clic (onclick) Ex: Ficher/Quitter slectionner Code : mettre close; dans le corps de la procdure
Delphi et Kylix

147

L. Jourdan

MIAGE 2me anne

Ajout dune bote de dialogue standard : Page Dialogues : 1 composant pour ouvrir un fichier, 1 composant pour enregistrer un fichier ( faire glisser dans la fentre) :

Gestion du Menu Ces mthodes feront appel aux botes standard par leur nom (proprit name) en les excutant (mthode Execute). Cration dun lien entre Fichier/Ouvrir et la boite standard douverture de fichiers Dans la procedure TForm1.Ouvrir1Click(Sender: TObject) ajouter : OpenDialog1.Execute ;

Le contenu dun mmo est reprsent par sa proprit lines Pour connatre les proprits, les vnements et surtout les mthodes dun composant ou la proprit en question [F1] Utilisez laide pour Lines type : Tstrings Mthode : LoadFromFile Cette mthode va nous permettre de charger le contenu du fichier dans le mmo. Ligne de code : Nb : Il faut rcuprer le nom du fichier rentr par lutilisateur. If OpenDialog1.Execute then Edition.Lines.LoadFromFile(OpenDialog1.Filename) ; Ajout dun filter de fichier : pour voir seulement le *.txt (Proprit filter de OpenDialog)

Gestion du presse papiers Il suffit de faire des lien entre la gestion pr-existente du presse papier du mmo et nore application. Complter le Menu par une entre Edition droite de fichier et la complter comme suit :

Delphi et Kylix

148

L. Jourdan

MIAGE 2me anne

En tant quutilisateur Windows vous connaissez les raccourcis habituels. Vous pouvez les spcifier par la proprit ShortCut de llment du menu en question.

Raliser le lien entre ces commandes et les fonctionnalits du mmo. Il existe 3 mthodes ralisant ce que lon veut faire : CutToClipboard, CopyToClipboard et PasteFromClipBoard.

Exercice 4: Ajout de la possibilit de changer de police : Lutilisateur doit pouvoir choisir la commande Texte|Police afin quil puisse choisir la fonte (proprit Font) de lEdition partir de la boite de dialogue des fontes.

Delphi et Kylix

149

L. Jourdan

MIAGE 2me anne

Solution : procedure TForm1.Police1Click(Sender: TObject); begin if FontDialog1.execute then Edition.font:= FontDialog1.Font;; end;

Exercice 5 : Une calculatrice postfixe Refaire une calculatrice fonctionnant selon le principe de la notation postfixe (polonaise inverse). On utilisera Exemple :

15 3 2 + - 4 +
Le principe des expressions postfixes est qu'une opration suit toujours ses oprandes. L'expression donne ci-dessus s'crit en notation arithmtique usuelle : 15 - (3 + 2) + 4. En effet, le premier signe + utilise 3 et 2 comme oprandes. Ensuite, le signe - utilise 15 et le rsultat de 3+2 comme oprandes. Enfin, le deuxime signe + plus utilise le rsultat de cette dernire opration et le 4. Exercice 6 : Cryptage / Dcryptage Raliser un programme permettant de raliser le cryptage dcryptage dune squence de caractre ANSI. Superposer les codes ANSI de deux phrases : 1. La premire est la phrase crypter 2. La deuxime est la phrase crypte avec la cl de cryptage. Le logiciel doit, connaissant la cl 1. Crypter 2. Dcrypter La cl est une constante du programme sur 8 caractres stocke sous forme : k_cle : array[1..8] of char='DELPHIV6';

Delphi et Kylix

150

L. Jourdan

MIAGE 2me anne

Mmo

Bouton ralisant le cryptage et le dcryptage

Boutons Bitmap

D.

TP4 DELPHI : Les botes de dialogue

Exemple : La bote A propos Reprendre le TP de lditeur de Texte (TP3) Ajouter une commande Aide | A Propos.. dans le menu

Delphi et Kylix

151

L. Jourdan

MIAGE 2me anne

Cration dune autre fiche Fichier |Nouvelle Fiche Si la fentre de choix dun modle de fiche napparat pas aller dans Outil | Rfrentiel | Fiches | A propos + Cocher Nouvelle Fiche Cela permet de dire que A propos devient le modle de fiche.

Image Label

Panel (volet) Bouton Bitmap (BitBtn)

Introduction Modle et Expert : Modle va reprendre une fiche que vous pouvez modifier Expert va vous aider en construire une Si le bouton nest pas BitMap en mettre un la place. Les proprits intressantes de ce bouton sont Layout, Glyph, Kind. Le panel permet de regrouper des composants : jouer avec les proprits. Il vous faut maintenant dans la fiche principale avec la bonne mthode : AboutBox.showModal; Lutilisation de la bote AboutBox : de faon modale : lorsque lutilisateur choisit la commande Aide | A propos la bote apparat et lutilisateur ne peut plus revenir lapplication sans fermer la bote (en appuyant sur le bouton ok par exemple). De faon amodale : la bote saffiche mais laisse lutilisateur accder normalement lapplication Panel : Surface visible qui peut contenir dautres composant Intrt : regroupement visuel de composant Proprits : BorderWidth : paisseur de la bordure BevelInner : Biseaux Interne BevelOuter : Biseaux externe BevelWidth : Distance Personnalisation de la bote gnre Composant : Label compos de TLabel
Delphi et Kylix

152

L. Jourdan

MIAGE 2me anne

Proprits : Caption : texte Autosize : taille Alignement : position WordWrap

Il faut maintenant donner un nom votre Unit 1 -> A propos Application : exemple 5 Fiche principale : Main Nouvelle bote : Unit 1 -> A propos Exercice 1 : Reprendre le rpertoire tlphonique et lamliorer (Menu + bote A propos). Exercice 2 : Reprendre lditeur de texte est lamliorer le plus possible (pour tre le plus proche de Wordpad). (Fichier daide Exemple pour rechercher : procedure TForm1.FindDialog1Find(Sender: TObject); var SelPos: Integer; begin with TFindDialog(Sender) do begin { Effectuer une recherche globale faisant la diffrence maj/min de FindText dans Memo1 } SelPos := Pos(FindText, Edition.Lines.Text); if SelPos > 0 then begin Edition.SelStart := SelPos - 1; Edition.SelLength := Length(FindText); end else MessageDlg(Concat('Impossible de trouver "', FindText, '" dans edition.'), mtError, [mbOk], 0); end; end;

E.

TP5 DELPHI : Visualisateur de forme

But : apprendre ragir des vnements valable pour nimporte quelle ficher + utilisation de Tshape (un composant reprsentant des formes). Cration du projet TP5 + Ficher principale Main.pas Ajout de Composants Composant Shape (Supplment) de nom Forme Composant MainMenu
Delphi et Kylix

153

L. Jourdan

MIAGE 2me anne

Quitter A propos

Paramtres Alt+P Shape

1.

Cration dune bote de dialogue

La bote de dialogue que nous allons crer permet de choisir une forme parmi un ensemble de formes possibles (celles de la proprit Shape du composant Shape) au moyen de boutons radio (RedioButton), le style du trait (le crayon : prorit Pen) par une autre groupe de boutons radio et les couleurs du traits et du fond (le pinceau : proprit Brush ) Etapes pour construire la bote de dialogue : 1- Crer une nouvelle fiche vierge que vous nommerez Paramtres et que vous intitulerez Paramtre de la forme 2- Dposez un volet (Panel) sur la fiche en lui donnant une dimension assez grande et en enlevant son titre 3- Dposez un autre volet en haut du premier et donnez-lui le titre Forme et le valeur bvLowered la proprit BevelOuter 4- Cliquez sur le composant bouton radio (RadioButton) avec la touche [Maj] enfonce afin de dposer plusieurs boutons radios dans le premier volet sans avoir les reprendre de la palette

Panel

avec les noms (Name) des boutons portant le mme nom que caption sans les accents et les espaces. 6- Ajouter une botes options (ComboBox) pour reprsenter le style de trait que vous nommerez StyleTrait . Vous y placerez les lments (proprits Items) suivants : Delphi et Kylix 154 L. Jourdan

5-

MIAGE 2me anne

789-

Vous changerez sont Style pour csDropDownList afin de limiter le choix de lutilisateur aux lment que vous venez de complter Placer une grille de couleur (ColorGrid de le page Exemples ) au dessous de la bote option et nommez la Couleurs Ajouter ensuite un biseau (bevel, page Supplment ) avec un alignement alBottom et une forme bsTopLine Terminez par lajout de 2 boutons bitmap

Enregister : Unit2 sous Params, unit1 sous Main 2. Interagir avec la bote de dialogue Appeler la bote de notre fiche principale : 1- Rfrence lunit Params dans linstruction Uses au dbut du source de lunit principale (+Paramtres aussi) 2- Ajouter la ligne de code habituelle que lon a vu pour la bote A propos : Parametres.ShowModal; Remarque : les points de suspension dans un titre indique quune bote de dialogue va tre active.

Delphi et Kylix

155

L. Jourdan

MIAGE 2me anne

3.

Reprendre les donnes partir de la bote

La premire chose dterminer cest de savoir par quel bouton la bote a t frme : [Ok] ou [Annuler]. La valeur que renvoie la mthode ShowModal : mrOk ou mrCancel. Se servir de laide pour rcuprer laide sur ShowModal, Style . Style est un type numer : TPenStyle = (psSolid, psDash, psDot, psDashDot, psDashDotDot, psClear, psInsideFrame); Style psSolid psDash psDot psDashDot psDashDotDot psClear PsInsideFrame Signification Une ligne continue Une ligne constitue d'une srie de tirets Une ligne constitue d'une srie de points Une ligne constitue d'une alternance de tirets et de points Une ligne constitue d'une srie de squences tiret-point-point Pas de ligne dessine (style utilis pour ne pas dessiner la ligne autour de formes dont le contour est dessin par le crayon en cours) Une ligne continue pouvant utiliser une couleur mlange si Width est suprieure 1

Vous devez rcuprez chacune des informations de la bote pour la reporter qui de droit. Pour xecuter plusieurs instruction la suite dun mme bloc : begin end. Ainsi : if Parametres.ShowModal = mrOK then begin { Rcupration des informations saisies dans la boite } Forme.Pen.Style := TPenStyle(Parametres.StyleTrait.ItemIndex); Forme.Pen.Color := Parametres.Couleurs.ForegroundColor; Forme.Brush.Color := Parametres.Couleurs.BackgroundColor; if Parametres.Rectangle.Checked then Forme.Shape := stRectangle else if Parametres.Carre.Checked then Forme.Shape := stSquare else if Parametres.RectangleArrondi.Checked then Forme.Shape := stRoundRect else if Parametres.CarreArrondi.Checked then Forme.Shape := stRoundSquare else if Parametres.Ellipse.Checked then Forme.Shape := stEllipse else if Parametres.Cercle.Checked then Forme.Shape := stCircle; end; Utilisation des boutons radio : Nous devons tester si chacun des boutons est slectionn ou non. Pour que la bote reflte ltat courant de la forme il faut lui donner les infos ncessaires avant de lafficher (donc avant showmodal) : Forme.Pen.Style := TPenStyle(Parametres.StyleTrait.ItemIndex); Forme.Pen.Color := Parametres.Couleurs.ForegroundColor; Forme.Brush.Color := Parametres.Couleurs.BackgroundColor; 4. Amlioration Evenement OnResize Crons une mthode de raction lvnement OnResize lequel sur produit chaque dimension de la fentre. Nous navons qu gnrer une mthode de raction cet vnement pour modifier les proprits left, Width, Top et Height : Forme.Left := Width div 4; Forme.Width := Width div 2; Forme.Top := Height div 4; Forme.Height := Height div 2; Div est un mot rserv de Delphi qui renvoie le quotient de lentier sa gauche par lentier sa droite. Rem : cest pas terrible, il faut travailler distinctement sur la zone intrieure et la zone extrieure. Il faut utiliser ClientWidth et ClientHeight pour redimensionner lintrieur de la fentre :
Delphi et Kylix

156

L. Jourdan

MIAGE 2me anne

Forme.Left := ClientWidth div 4; Forme.Width := ClientWidth div 2; Forme.Top := ClientHeight div 4; Forme.Height := ClientHeight div 2; Lvnement Oncreate se produit quand une fiche vient dtre cre. OnQueryClose et OnClose surviennent juste avant que la fiche ne soit dtruite par lutilisateur et vous permet donc de lempcher de se fermer ou de proposer quelque chose. OnDestroy aussi juste avant la destruction mais on ne peut plus rien faire. OnPaint, OnActivate, OnEnter, OnExit, OnDeactivate. Il existe des venements pour grer la souris et le clavier : OnKeyDown, OnKeyPress, OnKeyUp + OnMouseDown, OnMouseMove, OnMouseUp, OnClick, OnDblClick, OnDragDrop et onDragOver. (on verra dans le prochain TP). Exercice 6 : Construire une bote de marge afin que lutilisateur puisse choisir les proportions gauche, droite, en haut et en bas de la forme qui pour linstant sont figes 25%.

procedure TForm1.Position1Click(Sender: TObject); begin if Marges.ShowModal = mrOK then begin Forme.Left := (ClientWidth * StrToInt(Marges.Gauche.Text)) div 100; Forme.Width := (ClientWidth * (100 - StrToInt(Marges.Gauche.Text) - StrToInt(Marges.Droite.Text))) div 100; Forme.Top := (ClientHeight * StrToInt(Marges.Haut.Text)) div 100; Forme.Height := (ClientHeight * (100 - StrToInt(Marges.Haut.Text) - StrToInt(Marges.Bas.Text))) div 100; end; + Une belle bote de dialogue Marges

F.

TP 6-7 : Bases de donnes sous Delphi 3

Quand vous devez dvelopper des applications utilisant les bases de donnes, la toute premire tape consiste dfinir la structure de la base (dfinition des tables et de leurs champs). Cette structure de base dfinie, la deuxime tape consiste la construire. Delphi est livr avec un logiciel qui permet de grer les bases de donnes : Module de base de Donnes . Ralisation dun rpertoire : 1. Cration dune nouvelle table Type de table : dBase pour Windows Dfinition de la structure de la table :

Delphi et Kylix

157

L. Jourdan

MIAGE 2me anne

a)

Dfinition dun index

Dans la partie droite de la description, vous voyez apparatre Index dans une bote option. Dfinissez un index sur le NOMPRENOM. b) Enregistrement

Noubliez pas denregistrer votre table !! 2. Manipulation dune table

Pour ajouter des enregistrements une table, il faut louvrir. Votre table choisie, vous voyez apparatre dans une fentre :

Delphi et Kylix

158

L. Jourdan

MIAGE 2me anne

3.

Ajout et modification de donnes , dappeler la commande

Pour ajouter un enregistrement notre table, il suffit de cliquer sur le bouton de droite Table|Edition des donnes ou dutiliser le raccourci clavier [F9].

4.

Crer un nouveau projet

Il faut crer un nouveau projet et crer un menu comme suit :

Nous ne plaons pas de commande Enregistrer car lenregistrement se fait au fur et mesure de lvolution de la base, ce qui permet de partager la mme base entre diffrents utilisateurs en mme temps.

Delphi et Kylix

159

L. Jourdan

MIAGE 2me anne

5.

Grer la base de donnes

Vous trouverez dans la page AccsBD de la palette de composants 3 icones : 1- une pour les bases de donnes Database 2- une pour les tables (Paradox ou dBase) Table 3- une pour les requtes SQL Query Rfrencer une table : Dposer le composant Table dans la fiche et initialiser ses proprits DatabaseName lalias du rpertoire au ce situe votre base et TableName au nom de la base. Composant Table possde les mthodes simples First, Last, Next, Prior et MoveBy permettant de se dplacer dans la table tandis que BOF et EOF permettent de dterminer la position du curseur (enregistrement courant) au dbut ou la fin du fichier. La proprit Fiels et la mthode FieldByName servent accder aux champs. Utiliser un index Les proprits IndexFieldNames et IndexNale des Table servent dfinir un index la table en question (elle doit tre non active) correspondant un champ donn de la table, soit un index dfini pour la table. Il nous suffit de rfrencer la proprit IndexName par NOMPRENOM lindex de notre table. Afficher une table Utilisez une grille de base de donnes (DBGrid) dans le panel ContrleBD . Nous allons lui accorder toute la zone cliente et lui enlever sa bordure. Faire le lien entre le deux Il nous reste faire le lien entre la table et son affichage. A cet effet, il existe un composant reliant nimporte quel composant de base de donnes nimporte quel composant daffichage. Ce composant sappelle DataSource et il est situ dans la page AccsBD . Il suffit de prciser que son DataSet est Table1 qui est visible lorsque vous afficher les valeurs possibles par le boutons de descente. Concernant la grille, vous devez prciser que sa DataSource est DataSource1. Visualiser le rsultat la construction Il suffit dactiver la table en changeant sa proprit Active True. Vous obtenez alors ce qui suit :

Grer la base du programme Nous allons manipuler quelque peu la base afin de rpondre aux commandes du sous menu Personne. Commande Code Ajouter Table1.Append Enlever Table1.Delete

Tous les ensembles de donnes possdent ces mthodes qui permettent de manipuler leurs donnes. Une barre doutils pour les bases de donnes Nous allons maintenant placer une barre doutils qui permet de se dplacer parmi les enregistrements, den ajouter, den enlever, dannuler ou de confirmer une modification. Il suffit de placer dans un volet le composant navigateur de bases de donnes (DBNavigator) et de le relier aux informations en donnant la valeur DataSource1 sa proprit DataSource. Pour visualiser les conseils qui lui sont propres mettez la proprit ShowHints vrai. Changer de table pour le mme composant
Delphi et Kylix

160

L. Jourdan

MIAGE 2me anne

Nous allons maintenant implmenter les commandes classiques de sous menu. Commande Ouvrir : Il nous faut tout dabord une bote de dialogue douverture des fichiers que nous dposerons dans la fiche avec un filtre (Filter) Rpertoires|*.DBF , lextension par dfaut (DefaultExt) DBF et la vrification de lexistence du fichier (option ofPathMustExist et ofFileMustExist vrai). Avant daffecter un fichier au composant table, il faut sassurer que celui-ci nest pas actif. Nous allons donc mettre la table non active. Voici le code : if OpenDialog1.Execute then begin with Table1 do begin Active := False; DatabaseName := ExtractFilePath(OpenDialog1.FileName); TableName := ExtractFileName(OpenDialog1.FileName); Active := True; end; Commande Enregistrer sous : Dposons une bote de dialogue denregistrement avec les mmes filtre et extension que la bote douverture et les option suivante vrai : ofOverWritePrompt et ofHideReadOnly. Il nous faut aussi un composant spcifique aux oprations en masse sur les donnes : BatchMove ( AccsBD ). Ce composant sert effectuer des oprations gnrales entre deux tables (copie, mise jour, effacement ). Pour cela, il existe deux proprits rfrenant des tables Source et Destination, et la proprit Mode indiquant lopration effectuer. Nous allons donc dposer ce composant ce composant dans la fiche et lier Table1 la source. Nous prciserons (batCopy) dans la proprit Mode. Il va nous falloir un seconde Table dans laquelle nous copierons la premire, qui sera relie la proprit Destination du composant Action groupe (BatchMove). Enfin, il ne reste plus qu raliser le lien entre le BatchMove et le menu en dfinissant une mthode de raction la commande Enregistrer sous if SaveDialog1.Execute then with Table2 do begin Table2.DatabaseName := ExtractFilePath(SaveDialog1.FileName); Table2.TableName := ExtractFileName(SaveDialog1.FileName); BatchMove1.Execute; end; end; Cration dune table Nous commencerons par demander lutilisateur le nom du fichier qui sera cr par la bote de dialogue denregistrement qui existe dj dans notre fiche pour initialiser les proprits DatabaseName et TableName de Table2. Nous recopierons ensuite la structure de la table1 dans la table2 et nous crerons la table correspondante au composant Table2. Il nous restera ouvrir la table1 avec le fichier crer : procedure TForm1.Nouveau1Click(Sender: TObject); begin SaveDialog1.Title := 'Crer un rpertoire dans'; if SaveDialog1.Execute then with Table2 do begin DatabaseName := ExtractFilePath(SaveDialog1.FileName); TableName := ExtractFileName(SaveDialog1.FileName); { Cration de la nouvelle table } FieldDefs := Table1.FieldDefs; IndexDefs.Clear; CreateTable; end; { Ouverture de la nouvelle table } Table1.Active := False;
Delphi et Kylix

161

L. Jourdan

MIAGE 2me anne

Table1.DatabaseName := Table2.DatabaseName; Table1.TableName := Table2.TableName; Table1.Active := True; end; Amlioration : Recherche Nous allons implmenter une recherche sur le nom dans le rpertoire. Ajouter la commande Personne|Rechercher et le composant dialogue de recherche (FinDialog) de la page Dialogues du panneau des composants. Nous mettons ses options frHideMatchCase, frHideWholeWord et frHideUpDown vrai pour limiter la bote la chane de caractre rechercher. 1- ragir lexcution de la bote FindDialog1.Execute 2- ragir lvenement OnFind de la bote : with Table1 do begin SetKey; Fields[0].AsString := FindDialog1.FindText; GotoKey; end; La mthode SetKey du composant Table sert prciser la proprit Fields et la mthode FieldByName seront utiliser pour dfinir non pas les valeurs des champs de lenregistrement courant mais les valeurs rechercher. La mthode GotoKey sert ensuite effectuer cette recherche. La proprit Fields et la mthode FielsByName reprennent ensuite leur rle normal.

Ralisation dune messagerie Vous allez crer une application de messagerie qui utilise plusieurs tables. Trois tables : une pour reprsenter les clients une pour les personnes que lon contacte chez les clients ( contacts ) une pour les appels tlphoniques 1. Table des clients

Format : paradox 5.0 pour windows.

Delphi et Kylix

162

L. Jourdan

MIAGE 2me anne

Remplissez la avec la description de quelques clients. Le type + dune table paradox reprsente un nombre entier long , attribu aux lments de la table lors de leur insertion de manire squentielle et unique. Une fois assign, ce nombre reste jamais. 2. Table des contacts

Cette table reprsente lensemble des contacts de tous les client de la table prcdente. Elle a donc un lien vers cette tableci grce au numro de client No Client comme le montre la figure suivante.

Enregistrer cette table sous le nom Contacts et remplissez-la avec quelques contacts pour les diffrents clients de la premire table. Il nest pas obligatoire de reprendre le mme nom de champ pour tablir un lien entre deux champs de tables diffrentes, mais cela facilite la comprhension et permet aussi des reconnaissance automatique de lien. a) Dfinition dun index secondaire

Dfinissez un index secondaire, i.e. un index qui permet de retrouver les diffrents enregistrements suivant un autre ordre : suivant le numro de client No Client par exemple. Ainsi, vous pourrez observer, au moyen dune prsentation comme grilles, les contacts suivant lordre des numros de clients.

Delphi et Kylix

163

L. Jourdan

MIAGE 2me anne

3.

Table des appels

La table des appels reprsente les appels des contacts qui seront relis par le numro de contact No Contact.

Vous allez dfinir un index secondaire suivant le champ No Contact sous le nom Appels .

Delphi et Kylix

164

L. Jourdan

MIAGE 2me anne

4.

Crer lapplication

Crer un nouveau projet avec une fiche principale. 5. Les pages multiples de contrles

Notre application comportera 2 pages : 1. Contacts Clients pour visualiser la base des clients et les contacts de chacun des clients. 2. Appels Contacts pour visualiser les appels de chaque contact Le composant Classeur ou Notebook permet de reprsenter plusieurs pages pour une mme zone dans une fentre, chaque page pouvant contenir ses p ropres contrles. Il est possible de dfinir les diffrentes pages grce la proprit Pages , la page active tant alors dfinie par la proprit ActivePage. Dposez un composant Notebook sur la fiche et donnez lui le reste de la zone cliente. Dfinissez les 2 pages grce lditeur de classeur.

Le composant Onglets ou TabSet sert reprsenter un ensemble donglets. Sa proprit Tabs sert dfinir les diffrents intituls des onglets alors que Tab prcise lequel est actif. Placez un composant TabSet dans la fiche et dfinissez le pour quil remplisse le bas de la zone cliente. Il faut maintenant raliser le lien entre les 2 composants. Il nexiste pas de mthode automatique, il faut donc le faire lexcution. A la cration de la fiche, on indique que les onglets correspondent aux pages du classeur (NoteBook) que la page active du classeur (PageIndex) doit tre celle correspondant longlet actif (TabIndex). procedure TForm1.FormCreate(Sender: TObject); begin TabSet1.Tabs := Notebook1.Pages; Notebook1.PageIndex := TabSet1.TabIndex; end; Il faut ensuite faire en sorte quune fois longlet slectionn, la page associe saffiche. procedure TForm1.TabSet1Click(Sender: TObject); begin Notebook1.PageIndex := TabSet1.TabIndex; end; 6. La page Contacts Clients

Nous allons remplir la page Contacts Clients afin de reprsenter les clients et contacts associs au client actif. Nous utilisons 2 grilles de bases de donnes, nous aurons donc 2 sources de donnes (DataSource) et videmment 2 Table. Il faut vous assurer que le page active du classeur est relative aux Contacts Clients . Ensuite, vous pourrez y dposer les diffrents composants. Delphi et Kylix 165 L. Jourdan

MIAGE 2me anne

La table concernant les clients est nomme LesClients , la source de donnes correspondantes Client ; mme chose pour les contacts nommes respectivement LesContacts et Contacts . Nous ajoutons 2 libells afin didentifier les 2 grilles. Vous devez obtenir la fentre suivante :

7.

Crer un lien entre les deux tables

Nous allons utiliser lindex Par Client de la table Contacts. Pour utiliser cet index, il faut que la table soit non active. Choisissez lindex Par Client dans la proprit IndexName de la table LesContacts. Vous pouvez ractiver la table. Maintenant lordre des 2 tables correspond (tri par ordre croissant sur le numro de client), nous pouvons indiquer que lune est le matre de lautre grce deux proprits : MasterSource : indique une source de donnes qui sera mettre de la table MasterFields : lorsquun enregistrement de la table matre sera activ, seuls les enregistrement de la table correspondant au lien dfini par la proprit MasterFields seront visibles dans la table de dtail La table LesContacts devient le dtail de la source Clients afin de ne visualiser que les contacts un client donn. Client devient matre (MasterSource) de la table LesContacts puis on cre un lien grce au No client, valeur affect la proprit MasterFields. Dans le cas o aucun lien ne stablit vous pouvez en dfinir un explicitement.

Delphi et Kylix

166

L. Jourdan

MIAGE 2me anne

Aprs avoir activ cette bote, seuls les contacts correspondant au client activ dans la premire grille apparaissent lcran et ce mme lors de la construction. 8. La page Appel Contacts

Vous remarquez quil y a accessibilit permanente aux donnes, quelle que soit la page active. Placez une table et une source de donnes et reliez les (les noms respectifs sont Les Appels et Appels ). Lindex Par cOntact doit tre utilis (IndexName). Chaque champs de la source sera reprsent par un composant adquat. a) Les contrles des bases de donnes

Le champ No Appel est reprsent par un texte de base de donnes (DBText), les champs Date et Heure par des saisies de base de donnes (DBEdit), les champs Retour, Urgent et Appeler par des cases cocher de bases de donnes (DBCheckBox), le champ A qui par une bote option de donne et enfin le champs Message par un mmo de base de donnes. Le champ No Contact quant lui nest pas reprsent directement car il nest pas significatif pour lutilisateur. Nous visualiserons donc le nom du contact correspondant au numro. De plus nous voulons revoir tous les appels de ces contacts, il va donc falloir que le curseur de la table se positionne sur le nom slectionn afin de retrouver son numro qui servira retrouver les appels lui correspondant. Tous les composants spcifiques aux bases de donnes fonctionnent comme les composants auxquels ils correspondent sauf quils possdent les proprits DataSource et DataField qui permettent de les relier au champ visualiser. b) Les composants Lookup Nous devons ajouter une autre source et une autre table : TouslesContacts et TousContacts. Tous les composants font appel la source Appels except la grille de base de donnes qui fait rfrence TousContacts. Il faut aussi faire les lien entre les 2 tables en utilisant lindex de la table 4appels et en tous contact comme source principale.

Delphi et Kylix

167

L. Jourdan

MIAGE 2me anne

TousContacts,

LesClients, Clients.db

LesContacts, contact.db Index : parclient

Les appels, appels.db Index : lesappels

TousLesContacts, contact.db Index : aucun

9.

Utiliser un DBGrid comme une liste de positionnement

Nous devons personnaliser le DBGrid pour quil ralise ce que nous voulons. Il faut limiter laffichage des noms des contacts. a) Grer les champs lexcution

Il faut grer les champs date et heure lexcution. Les composants Table et dataSource ont une proprit State en lecture seule qui reprsente ltat courant de lutilisation de la table ou la source. Le composant DataSource a 3 vnements qui permettent de grer les changements dans une source : OnDataChange, OnStateChange et OnUpDateDate. Ce qui donne : procedure TForm1.AppelsStateChange(Sender: TObject); begin with LesAppels do begin
Delphi et Kylix

168

L. Jourdan

MIAGE 2me anne

if State <> dsInsert then Exit; FieldByName('No Contact').AsInteger := TousLesContacts.FieldByName('No Contact').AsInteger; FieldByName('Date').AsDateTime := Date; FieldByName('Heure').AsDateTime := Time; end; end;

G.

TP7 DELPHI : Le dessin et la souris

But : construire un petit logiciel de dessin 1. Crer un projet

Fiche contenant un composant Image (de la page supplment ) nomm Image qui permet de visualiser une bitmap (une image point point) dans lequel lutilisateur peut dessiner. Proprit intressante : picture : reprsente la bitmap qui sera affiche autosize : permet dadapter la taille du composant celle de limage label : permet dadapter la taille du composant celle du texte Donc soit crer une image blanche.bmp avec paintbrush soit crer tout autre image + matre autosize vrai. 2. Ragir la souris

Lvnement OnMouseDown permet de dterminer la position de la souris sur un composant et lorsquun bouton est enfonc. La position de la souris est alors connue grce aux paramtres X et Y, le bouton (gauche, milieu ou droite) par Button et les touches mortes ([Maj],{Alt],[Ctrl]) par Shift . Lvnement OnMouseUp est semblable lvnement OnMouseDown ceci prs quil est dclench lorsquun bouton est relch. Proprit Canvas qui est aussi un objet reprsente la zone cliente des composants. Un Canvas possde notamment la proprit Pixels qui reprsente chaque pixel du composant auquel il est rattach. (cf. Aide). Elle ncessite des paramtres : il faut lui donner les coordonnes du point en question entre crochet. Nous obtenons le code suivant : Image.canvas.Pixels[X, Y] := clBlack ; Nous affectons la couleur noire au point de coordonnes X et Y. Il est cependant contraignant de toujours devoir rappuyer sur le bouton ! ! ! Il existe un vnement qui traque le mouvement de la souris : OnMouseMove : cet vnement se produit au niveau dun composant lorsquon survole ce composant. La position de la souris est connue grce aux paramtres X et Y. Les boutons et les touches enfonces grce Shift. If ssLeft in Shift then Image.canvas.Pixels[X, Y] := clBlack ;

Exercice : Remarque nous ne pouvons effacer ce que nous faisons : Fates en sorte quun point blanc saffiche lorsque le bouton droit de la souris est enfonc. Perfectionnement : Combinez toutes vos connaissances pour amliorer cet exemple : charger une image enregistrer une image bote de dialogue vous permettant de choisir les couleurs associes aux boutons droit et gauche un menu une bote A propos

Delphi et Kylix

169

L. Jourdan

MIAGE 2me anne

Exercice : Le glisser - dplacer

1-

Crer un nouveau projet :

2 botes listes (ListeBox) boite 1 : article de bureau dun magasin boite 2 : achats

Label Name : Total

Spcifier un alignement droite pour le libell (Label) de titre 0 correspondant au calcul du montant payer. 2Autoriser le glisser- dplacer (Proprit Dragmode) 2 faons : manuel (dmManuel) : vous devez alors appeler la mthode BeginDrag au moment o vous voulez commencer le drag&drop. automatique (dmAutomatic) : mettre pour Magasin. Lorsque lutilisateur clique avec le bouton gauche sur le composant acceptant le drag&drop automatique et quil dplace la souris de plus de 5 pixels, le drag&drop est enclench. Autoriser ou non le dplacement (drop) Evnement OnDragOver de la bote Liste Achats Il suffit donc de crer une mthode de raction cet vnement pour le recepteur. Les paramtres disponibles pour cette mthode : Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean Explication sur ces paramtres : sender : composant qui dclenche lvnement source : le composant do commence lopration glisser-dplacer X et Y : les coordonnes de la position de la souris State : loccurrence de la requte pour le composant rcepteur (premire, dernire ou intermdiaire) Accept : lacceptation du dplacement dans le composant rcepteur (par dfaut le rcepteur naccepte pas le dplacement). Dans notre exemple : il faut accepter le dplacement lorsque le glisser-dplacer provient du magasin : procedure TForm1.AchatsDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin Accept := Source = Magasin; end;
Delphi et Kylix

3-

170

L. Jourdan

MIAGE 2me anne

Rem : regarder le changement dtat du curseur de Magasin vers Achats.

4-

Effectuer le dplacement : La demande de dplacement dclenche lvnement OnDragDrop Nous voulons que larticle slectionn dans la bote liste du magasin sajoute nos achats et que son prix sadditionne la somme payer. Ajouter la liste dachats : Achats.Items.Add( Magasin.Items[Magasin.ItemIndex] ); Comptabiliser le montant de lachat : Total.Caption := RealToStr( StrToReal(Total.Caption) + StrToReal(Magasin.Items[Magasin.ItemIndex]) );

Il faut pour cela une unite nouvelle qui contient StrToReal et RealToStr : unit StrReal; interface function RealToStr( reel : Real ): String; function StrToReal( chaine : string ): Real; implementation function RealToStr( reel : Real ): String; var s : string; begin Str( reel:10:2, s ); Result := s; end; function StrToReal( chaine : string ): Real; var r : Real; pos : integer; begin Val( chaine, r, pos ); if pos > 0 then Val( Copy(chaine, 1, pos-1), r, pos ); Result := r; end; end. Amlioration : Une amlioration vidente est la possibilit denlever des articles des Achats en appuyant sur [Suppr] par exemple. Cet vnement est OnKeyDown . procedure TForm1.AchatsKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin { VK_Delete est le nom interne de la touche [Delete] en Windows } if Key = VK_Delete then begin Total.Caption := RealToStr( StrToReal(Total.Caption) - StrToReal(Achats.Items[Achats.ItemIndex]) ); Achats.Items.Delete( Achats.ItemIndex ); end; end; Exercice :
Delphi et Kylix

171

L. Jourdan

MIAGE 2me anne

Autorisez le glisser-dplacer de Achats vers Magasin en ayant pour raction leffacement de larticle achet, comme si lutilisateur appuyait sur la touche [Suppr].

H.
1.

TP 8 : Drag & Drop suite + Application Console Graphique


Drag et drop dans une stringgrid : le taquin torique

Ralisation dun taquin torique : Le taquin est un jeu classique de dplacement de pice. Vous raliserez un taquin torique comme sur la figure suivante et les coups seront effectus grce des drag and drop sur une stringgrid. Une vrification de la faisabilit du coup est bien sr intgrer.

On peut dplacer sa pice uniquement si une case vide contigue est disponible, la grille tant torique dans notre case les dplacement suivant sont autoriss : X X X X X X X X X X X X X X X

Pour initialiser la grille vous utiliser la gnrateur alatoire de nombre prsent dans la librairie Math :

RandG, fonction Random, fonction RandomFrom, fonction Randomize, procdure


Delphi et Kylix

Gnre des nombres alatoires avec une distribution gaussienne. Gnre des nombres alatoires dans une tendue spcifie. Renvoie un lment choisi au hasard dans un tableau. Initialise le gnrateur interne de nombres alatoires avec une valeur alatoire. 172 L. Jourdan

MIAGE 2me anne

RandomRange, fonction RandSeed, variable

Renvoie un entier choisi au hasard dans l'intervalle spcifi. RandSeed stocke la matrice du gnrateur de nombres alatoires.

Une grille de type stringgrid permettra de plus de visualiser le nombre de dplacement de chaque pice. Dans la barre de statut vous indiquerez si un coup est faisable ou non.

2.

Application Console / Graphique

Il est facile de raliser des applications possdant une reprsentation graphique des lments sous Delphi grce aux forms . Le but de cet exercice est de refaire une application existante avec son forms pour quelle fonctionne sans. Vous tlchargerez lapplication initiale sous www.lifl.fr/~jourdan dans la partie enseignement Delphi Miage 2me Anne. Cette application ncessite : un dbgrid, un datasource et une table de donnes.

Delphi et Kylix

173

L. Jourdan

MIAGE 2me anne

Comment raliser la mme chose en se passant du forms ? Il faut dclarer un dfm, les datasources, les dbgrids. rogram Project1; uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids, DBGrids, DB, DBTables, ExtCtrls; type TFake = class (TDBGrid) ; ma_dts = class(TDataSource) end; ma_TDBGrid = class(TDBGrid) end; tform1=class(tform) panel1 : tpanel; label1 : tlabel; label2 : tlabel; label3 : tlabel; Table1 : TTable; DataSource1 : ma_dts; DBGrid1 : ma_TDBGrid; procedure DBGrid1ColEnter(Sender: TObject); procedure DataSource1DataChange(Sender: TObject; Field: TField); end; procedure tform1.DBGrid1ColEnter(Sender: TObject); var i :byte; begin Label1.Caption := Format ( 'ligne: %2d; colonne: %2d', [TdrawGrid (DbGrid1).Row, // on a le choix TFake(DbGrid1).Col]); // cf ci-dessus Label2.Caption :=DbGrid1.Columns.Grid.Fields[TFake(DbGrid1).col-1].AsString ; Label3.Caption :=DbGrid1.Columns.Grid.Fields[0].AsString ; for i:= 1 to DbGrid1.FieldCount-1 do Label3.Caption :=Label3.Caption+', '+ DbGrid1.Columns.Grid.Fields[i].AsString ; end; procedure tform1.dataSource1DataChange(Sender: TObject; Field: TField); begin DBGrid1ColEnter (sender); end; var Form1 : tform1; {$R Project1.dfm} //ou *.dmf obligatoire pour CreateForm(Tform1... // le fichier texte Project1.dmf doit au moins contenir : object Form1: TForm1 end begin Application.Initialize; Application.CreateForm(TForm1, Form1); with Form1 do begin Left := 198; Top := 107; Width := 630; Height := 430;
Delphi et Kylix

174

L. Jourdan

MIAGE 2me anne

Caption := 'Form1'; Color := clBtnFace; Font.Charset := DEFAULT_CHARSET; Font.Color := clWindowText; Font.Height := -11; Font.Name := 'MS Sans Serif'; Font.Style := []; OldCreateOrder := False; PixelsPerInch := 96; panel1:= TPanel.Create(form1); with panel1 do begin Parent:=Form1; Left := 0 ; Top := 0; Width := 494 ; Height := 49 ; Align := alTop ; TabOrder := 1 ; end; label1:=TLabel.Create(panel1); ????????????????? A complter pour tous les labels with label1 do begin Parent:=panel1; Left := 16 ; Top := 8 ; Width := 3 ; Height := 16 ; Caption := 'Label2'; end;

????????????????? A complter pour tous les labels Table1:= TTable.Create(form1); with Table1 do begin DatabaseName := 'DBDEMOS'; TableName := 'COUNTRY.DB'; Active := True; end ; DataSource1:= ma_dts.Create(form1); with DataSource1 do begin DataSet := Table1; OnDataChange := DataSource1DataChange; end ; // attention l'ordre !!! DBGrid1:= ma_TDBGrid.Create(form1); with DBGrid1 do begin Parent:=Form1; Left := 0; Top := 49; Width := 494; Height := 235 ; Align := alClient; DataSource := DataSource1 ; TabOrder := 0 ; TitleFont.Charset := DEFAULT_CHARSET; TitleFont.Color := clBlack ; TitleFont.Height := -13 ; Delphi et Kylix 175

L. Jourdan

MIAGE 2me anne

TitleFont.Name := 'MS Sans Serif'; TitleFont.Style := []; OnColEnter := DBGrid1ColEnter; end; DBGrid1ColEnter (nil);// pour initialiser les labels end; Application.Run; end.

I.

TP9 DELPHI : Communication OLE et DDE

DDE : Dynamic Data Exchange OLE : Object Linking and Embedding Delphi permet dutiliser ces facilits en fournissant un composant qui gre ce genre de lien sans crire une ligne de code (du moins pour le lien). 1. DDE : Dynamic Data Exchange

Prsentation DDE est une interdace entre 2 applications destine les faire communiquer entre elles. De ces 2 application, lune est le serveur, elle fournit des informations ou des services lautre qui est le client. Cette communication est dynamique, cest dire quelle stablit lxecution des 2 applications impliques et peut faire lobjet dune mise jour ds que les informations du serveurs sont modifies. Un serveur DDE est rfrenc par un client au moyen de 3 informations : 1- le nom de lpplication serveur (sans le .exe ). 2- Le nom du sujet (topic). 3- Le nom de llment (item). Ainsi, il faut spcifier ces 3 informations pour accder une donne. 2. Le projet Serveur

Nous allons crer une horloge qui affiche lheure. Nous en ferons un serveur DDE qui donne lheure tout client DDE. 1- Crer un nouveau projet Projet Horloge avec une fiche contenant un libell (label) nomm Heure et un composant Timer (page Systme ). Composant Timer dclenche lvnement OnTimer intervalles rgulier spcifis en ms par sa proprit Interval. Crer une raction toute les 1s lvenement Ontimer qui placera lheure courante dans le titre du libell heure Heure.Caption := TimeToStr(Time) ; Pour plus de lisibilit, dimensionnez le libell pour afficher lheure avec une fonte (Font) assez grande.

Transformer en serveur DDE Pour transformer cette horloge en serveur DDE, il suffit dajouter deux composants situs dans la page systme : composant conversation serveur DDE ou DdeServerConv qui permet de transformer votre application en un serveur DDE. Son nom (Name) sera celui du sujet de la liaison DDE. Composant lment serveur DDE ou DdeServerItem qui reprsente llment que vous rendez disponible aux clients en le reliant au composant DdeServerConv par la proprit ServerConv. Son nom sera celui de llment de la liaison DDE. Vous allez donc nommer Horloge le composant conversation serveur DDE et Temps le composant lment serveur DDE . Pour obtenir :
Delphi et Kylix

176

L. Jourdan

MIAGE 2me anne

Il ne reste plus qu rendre disponible linformation (lheure) aux clients en initialisant la proprit Text du Temps . Pour cela ajouter 2 lignes la mthode du Timer : Temps.Text := Heure.Caption; Temps.CopyToClipboard; La proprt Text prpare la chane envoyer au client, lchange rel se fait au moyen de la mthode CopyToClipboard, mettant ainsi disposition du client les donnes par le moyen de communication de Windows le plus courant : le press-papier. Vous pouvez tester votre horloge sous Excel avec la formule =Horloge|Horloge !Temps . Noubliez pas de donner un format daffichage dheure ( hh :mm :ss ). 3. Le projet Client

Les composants qui grent le client : composant de conversation client DDE ou DdeClientConv permet de transformer votre application en un client DDE. Le serveur et le sujet de la liaison DDE sont spcifis dans les proprits DdeService et DdeTopic. Composant lment client DDE ou DdeClientItel reprsente linformation ou le service du serveur auquel vous voulez accder. Il est reli au composant DdeCleintConv par la proprit DdeConv. Cette information ou ce service est dsign par la proprit DdeItem. 4. Crer le projet

Un projet client. Dans sa fiche, placez un libell (Label) du mme genre que celui du serveur, nomm Temps . Ajouter les 2 composants DdeClientConv et DdeClientItem en les reliant par la proprit DdeConv de ce dernier. 5. Faire un lien avec le serveur DDE Commencez par excuter lhorloge directement partir du gestionnaire de fichiers par exemple. Ensuite, vous navez plus qu spcifier le serveur et le sujet au niveau du DdeClientCOnv en activant la bote de liaison DDE par un double clic dans la zone ddition de sa proprit DdeTopic ou en cliquant sur .

Vous consatez que le bouton [Coller avec liaison] est actif, il vous suffit de cliquer dessus pour que les valeurs correctes apparaissent. Validez avec [ok]. Lvnement OnChange du composant DdeClientItem se produit chaque changement du contenu qui lui est li. Il suffit dcrire une mthode de raction cet vnement : procedure TForm1.DdeClientItem1Change(Sender: TObject); begin Heure.Caption := DdeClientItem1.Text; end;

OLE : Object Linking & Embedding Prsentation OLE est un mcanisme qui permet de manipuler des informations et des services de diffrentes applications dans dautres applications. La version 2.0 permet mme de manipuler ces infos et services sur place , cest dire de les rassembler et de les manipuler directement dans lapplication courante. Lutilisateur peut ainsi intgrer des documents dautres applications dans une application sans la quitter en tablissant : Delphi et Kylix 177 L. Jourdan

MIAGE 2me anne

1. 2.

Soit des liens (linking) : les donnes sont enregistres dans des fichiers spars. Le document receveur fait rfrence aux autres documents. soit des incorporations (embedding) : les donnes sont enregistres dans le mme fichier que celui du document receveur mais par lapplication dorigine de ces donnes.

M La notion dobjet dans OLE ne correspond pas exactement celle de lorient objet. DELPHI donne la possibilit de crer des application conteneurs pour lOLE grce au composant OleContainer de la page systme . OleContainer transforme une application en une application conteneur pour des objets OLE 2.0 Crer un projet Dposer une conteneur OLE de la page systme dans la fiche. Nous lui donnons toute la zone cliente en positionnant sa proprit Align alClient ; nous lui enlevons sa bordure (BorderStyle bsNone). Transformer en conteneur OLE Nous allons manipuler une image paintbrush. OleContainer possde 3 proprits pour spcifier lobjet OLE quil reprsente : ObjClass, ObjDoc et Objitem. ObjClass reprsente le type dobjet OLE, li ou incorpor par son application gnratrice. ObjDoc reprsente le doc contenant linfo qui est lie ObjItem reprsente lobjet OLE li lui-mme Double Clic sur la partie valeur de la proprit ObjClass (ou ObjDoc). Chois ir Image PaintBrush Quitter lapplication, votre chef duvre est maintenant dans votre fiche. Excuter lapplication Importation sous Word Lobjectif de cet exercice est de raliser un gestionnaire de facture qui importe la facture formate sous word. Delphi possde dans ses librairies des objets permettants de communiquer avec word. 6. Cration de la base de donnes Vous crerez une base de donnes Paradox (par exemple, mais vous pouvez utiliser acces ou tout autre type de base de donnes). Cette base contient 4 champs Numero, Nom, Date et Montant. La date est dclare en type date. Vous compltez la base de donnes avec quelques enregistrements.

Delphi et Kylix

178

L. Jourdan

MIAGE 2me anne

7.

Le projet Delphi a) Formulaire Votre formulaire doit contenir une table relie la base de donnes et un Datasource reli cette table. Pour communiquer avec word vous devez utiliser le composant WordDocument qui se situe dans longlet Serveur .

Dbtext

Dbedit

Une fois votre formulaire complt, il faut associer une vnement au click sur le bouton Exporter sous Word . Ce bouton va contenir les instructions ncessaire au formatage de la facture sous word de la facture courante. Le bouton Exporter toute les factures permettra au magasin de garder une trace papier de toutes les transactions effectues. Le code delphi va alors contenir les lments visual basic permettant de communiquer avec word, ces lments sont prsents dans word mais pas dans delphi (en tout cas dans la version actuelle de delphi6). Pour connatre comment appeler certaines fonctions on peut par exemple raliser des macrowords puis regarder le nom de la fonction correspondante . Nous utiliserons les lments word suivants : Range.Text qui reli lobjet WordDocument permet dcrire du texte dans le document Range.Font.Size : qui permet dindiquer la taille de la fonte Range.InsertParagraphAfter : qui permet dinsrer un saut de paragraphe ConvertToTable (#9, 1, 4) : qui permet de formater une slection en tableau dans la sparation est code par #9, de nombre de ligne 1 et de nombre de colonne 4. Cells.Merge : permet de fusionner les cellules dun tableau que lon a slectionne. Nous aurons besoins des types de variables suivants : Variant : peuvent tout contenir sauf les types structurs et les pointeurs. Cela permet de dfinir un objet dont on ne connat pas le type la compilation Tbookmark : identifie un enregistrement dans un ensemble de donnes, pour une navigation ultrieure. OleVariant contient uniquement des types de donnes compatibles avec Ole Automation, ce qui signifie que ces types de donnes peuvent tre transfrs entre programmes ou sur le rseau sans qu'il soit ncessaire de savoir si l'autre extrmit saura manipuler les donnes. b) var
Delphi et Kylix

Gestion des vnements (1) Exporter sous Word 179 L. Jourdan

MIAGE 2me anne

RangeW: Word2000.Range; v1: Variant; ov1: OleVariant; Row1: Word2000.Row; begin WordDocument1.Activate; // inserer titre WordDocument1.Range.Text := 'Facture n ' + Table1.fieldbyname ('Montant').AsString; // Indiquer la police WordDocument1.Range.Font.Size := 14; WordDocument1.Range.InsertParagraphAfter; // Crer la ligne de facturation WordDocument1.Paragraphs.Last.Range.Text := Table1.FieldByName ('Nom').AsString + #9 + A COMPLETER AVEC TOUS LES CHAMPS DE LA BASE DE DONNEES // Selection tout le document RangeW := WordDocument1.Content; v1 := RangeW; // le convertir en tableau v1.ConvertToTable (#9, 1, ); // rcuprer la premiere ligne et changer sa fonte et son aspect Row1 := WordDocument1.Tables.Item(1).Rows.Get_First; Row1.Range.Bold := 1; Row1.Range.Font.Size := 30; Row1.Cells.Merge; Row1.Range.InsertParagraphAfter; ov1 := ' '; (2) Exporter toutes les factures

De la mme faon on peut crer un document word et y copier tous les enregistrements. On vous aidant des routines suivantes ralisez lvnement associ au bouton. // disable the UI Table1.DisableControls; try // sauvegarde de la position dans la base Bookmark := Table1.GetBookmark; try // passage Table1.First; while not Table1.EOF do finally // on revient la position courante et on dtruit le bookmark Table1.GotoBookmark (Bookmark); Table1.FreeBookmark (Bookmark); end; finally // on r-autorise lacces la base Table1.EnableControls; end; Importation sous Excel Formater une grille pour limporter sous excel De la mme faon que lon peut exporter les champs sous Word, on peut les exporter sous excel. Vous crerez un bouton tout exporter sous Excel et associerez un venement au click sur le bouton ralisant lexport. Pour cela vous vous servirez des routines suivantes :
Delphi et Kylix

180

L. Jourdan

MIAGE 2me anne

var RangeE: Excel2000.Range; I, Row: Integer; Bookmark: TBookmarkStr; begin // crer et rendre visible excel ExcelApplication1.Visible [0] := True; ExcelApplication1.Workbooks.Add (NULL, 0); // remplir la premier ligne avec les nom des champs RangeE := ExcelApplication1.ActiveCell; for I := 0 to Table1.Fields.Count - 1 do begin RangeE.Value := Table1.Fields [I].DisplayLabel; RangeE := RangeE.Next; end; // remplir les lignes suivantes avec les enregistrements Table1.DisableControls; try Bookmark := Table1.Bookmark; try Table1.First; Row := Table1.RecordCount+1; while not Table1.EOF do begin RangeE := ExcelApplication1.Range ['A' + IntToStr (Row), 'A' + IntToStr (Row)]; for I := 0 to Table1.Fields.Count - 1 do begin RangeE.Value := Table1.Fields [I].AsString; RangeE := RangeE.Next; end; Table1.Next; Inc (Row); end; finally Table1.Bookmark := Bookmark; end; finally Table1.EnableControls; end; // formater le tableau pour que cela fasse joli RangeE := ExcelApplication1.Range ['A1', 'E' + IntToStr (Row - 1)]; RangeE.AutoFormat (3, NULL, NULL, NULL, NULL, NULL, NULL); end;

Et voil un joli tableau sous excel !!!


Numero Nom Date Montant

1 USTL 24/07/2002 10:39:18 2 USTL 24/07/2002 13:40:20

1000 500

J.
1.

TP10 DELPHI : Fioritureset amlioration des exemples


Editeur de texte amlior

Il existe 2 groupes dinstruction qui reviennent souvent : Police.Caption := Edition.Font.Name + ' ' + IntToStr(Edition.Font.Size);
Delphi et Kylix

181

L. Jourdan

MIAGE 2me anne

if fsBold in Edition.Font.Style then Police.Caption := Police.Caption + ' gras'; if fsItalic in Edition.Font.Style then Police.Caption := Police.Caption + ' italique'; if fsUnderline in Edition.Font.Style then Police.Caption := Police.Caption + ' soulign'; if fsStrikeOut in Edition.Font.Style then Police.Caption := Police.Caption + ' barr'; Si nous voulons modifier linformation ou en rajouter dautres (couleur de la police par exemple), nous devons modifier toutes les lignes correspondantes. Nous allons crer notre propre mthode MAJBarreStatut 2. Crer des mthodes simples

Dclaration Il faut les dclarer soit dans public (si nous voulons que dautres objets y aient aussi accs) soit dans private. Dans notre cas dans les dclarations prives : Procedure MAJBarreStatut Dfinition Il suffit de prendre les lignes rpte x fois et de les mettre dans le corps de notre mthode. Procedure Tform1.MAJBarreStatut ; Begin Police.Caption := Edition.Font.Name + ' ' + IntToStr(Edition.Font.Size); if fsBold in Edition.Font.Style then Police.Caption := Police.Caption + ' gras'; if fsItalic in Edition.Font.Style then Police.Caption := Police.Caption + ' italique'; if fsUnderline in Edition.Font.Style then Police.Caption := Police.Caption + ' soulign'; if fsStrikeOut in Edition.Font.Style then Police.Caption := Police.Caption + ' barr'; end; Il faut maintenant faire rfrence ce traitement en appelant la nouvelle mthode l o il y avait les lignes de codes. MAJBarreStatut ; De la mme faon on peut crer MAJBarreOutils ; procedure TForm1.MAJBarreOutils; begin Gras.Down := fsBold in Edition.Font.Style; Italique.Down := fsItalic in Edition.Font.Style; Souligne.Down := fsUnderline in Edition.Font.Style; Barre.Down := fsStrikeOut in Edition.Font.Style; end; 3. Crer des mthodes avec paramtres

Nous nous apercevons que le traitement effectu pour chaque bouton est le mme ( ceci prs que le bouton et le style change). Mais le principe reste mme : if gras.Down then Edition.Font.Style := Edition.Font.Style + [fsbold] else Edition.Font.Style := Edition.Font.Style - [fsbold]; MAJBarreStatut; Nous pouvons crer une mthode mme si les boutons et les styles sont diffrents. La mthode ncessite 2 paramtres : le bouton (TSpeedbutton) impliqu le style (Tfontstyle) correspondant procedure AppuieBoutonStyle( leBouton : Tspeedbutton ; leStyle : TfontStyle) ; begin if leBouton.Down then Edition.Font.Style := Edition.Font.Style + [leStyle] else Edition.Font.Style := Edition.Font.Style - [leStyle]; MAJBarreStatut; Il ne reste plus qu replacer les lignes dans les fonctions correspondantes. Ex : Delphi et Kylix 182

L. Jourdan

MIAGE 2me anne

Procedure Tform1.Barreclick(Sender : Tobject) ; Begin AppuieBoutonStyle( Barre, fsStrikeout) ; End ; On peut encore simplifier : Nous constatons que les 4 boutons nous appelons le mme mthode AppuieBoutonStyle avec des paramtres diffrents. 4. Paramtre sender

Il existe un paramtre Sender qui fait rfrence au composant qui a cre un vnement. Sender est de type Tobject qui est la classe de base tout objet et notre paramtre est de type TspeedButton. Nous pouvons utiliser le mot rserv is pour nous assurer que lobjet plac sa gauche est compatible avec la classe place sa droite (cest dire quil est une instance de cette classe ou dune classe drive). Une faon plus efficace de changer le type en sassurant du bien fond est dutiliser le mot rserv as qui sert effectuer un changement de type dun objet en sassurant quil est rellement du type en question. Sil ne lest pas une exception sera dclenche. Ex : AppuieBoutonStyle( Sender as TspeedButton, ) Met comment prendre en compte le clic sachant quun seul paramtre existe pour les mthodes de type XXXClick ??? La proprit Tag de sender ne sert rien dans notre cas. Nous allons y conserver le style. 5. Proprit Tag

Tag proprit de tous les composants, il est de type longint. Nous y mettons le style. Le style conserver est de type TfontStyle nous devons effectuer une conversion de style. procedure TForm1.BoutonStyleClick(Sender: TObject); begin if (Sender as TspeedButton).Down then Edition.Font.Style := Edition.Font.Style + [TfontStyle((Sender as TspeedButton).Tag)] else Edition.Font.Style := Edition.Font.Style - [TfontStyle((Sender as TspeedButton).Tag)] End; Noubliez pas daffecter cette nouvelle mthode vos clicks sur les boutons et de placer les valeurs correspondant au numro dordre des style (gras=0, italique=1, ) dans la proprit Tag de chaque bouton. 6. Variable locale

Nous pouvons encore simplifier ce code en dclarant des variables locales la mthode BoutonStyleClick. procedure TForm1.BoutonStyleClick(Sender: TObject); var { dclaration de variables locales cette procdure } leBouton: TSpeedButton; leStyle: TFontStyle; begin { Conversion des informations } leBouton := Sender as TSpeedButton; leStyle := TFontStyle(leBouton.Tag); { Traitement } if leBouton.Down then Edition.Font.Style := Edition.Font.Style + [leStyle] else Edition.Font.Style := Edition.Font.Style - [leStyle]; MAJBarreStatut; end;

Delphi et Kylix

183

L. Jourdan

MIAGE 2me anne

Les barres doutils et dtat Reprendre lditeur de texte pour lui ajouter 2 barres : 1- Une barre dtat en bas qui donnera des explication sur ltat de lditeur de texte 2- Une barre doutils en haut qui prsentera des raccourcis aux commandes du menu sous forme de boutons La barre de statut 1- Ajouter un composant volet (Panel) la fiche 2- Le placer en bas de la fiche en faisant en sorte quil sadapte au changement de dimension de la fentre 3- Placer diffrents composants pour reprsenter les diffrents indicateurs voulus Crer la barre de statut Placer un volet (Panel) pour reprsenter une barre de statut nommme BarreStatut et lui enlever son titre, Align=Albottom. Ajouter 2 autres volets nomms Modifie et Police (sans titre) et mettre un effet de relief en creux : BevelOuter=bvLowered. Trouver une font adapte pour visualiser correctement les statuts. Placer les informations dans la barre dtat Il faut que le texte Modifi s affiche dans le volet Modifie lorsque le contenu de lditeur de texte est modifi. Dans ce but, nous allons ragir lvnement OnChange du mmo : Modifie.Caption := Modifi ; Il faut aussi faire en sorte que ce message disparaisse lorsque le texte est enregistr. Il faut donc ajouter une instruction dans la mthode de raction lenregistrement pour quelle devienne : procedure TForm1.Enregistrersous1Click(Sender: TObject); begin if SaveDialog1.Execute then begin Edition.Lines.SaveToFile( SaveDialog1.FileName ); Modifie.Caption := ''; { enlve l'indicateur de modification } end; end; Nous devons procder de la mme faon pour la police utilise. Nous supposons que nous voulons : le nom de la police, sa taille, puis son style : procedure TForm1.Police1Click(Sender: TObject); begin if FontDialog1.Execute then begin Edition.Font := FontDialog1.Font; { Mise jour de la barre de statut } Police.Caption := Edition.Font.Name + ' ' + IntToStr(Edition.Font.Size); if fsBold in Edition.Font.Style then Police.Caption := Police.Caption + ' gras'; if fsItalic in Edition.Font.Style then Police.Caption := Police.Caption + ' italique'; if fsUnderline in Edition.Font.Style then Police.Caption := Police.Caption + ' soulign'; if fsStrikeOut in Edition.Font.Style then Police.Caption := Police.Caption + ' barr'; end; end; Amlioration Pb : au dmarrage rien ne saffiche dans la barre de statut concernant la police. Nous pouvons le faire manuellement mais aussi lautomatiser grce lvnement OnCreate. procedure TForm1.FormCreate(Sender: TObject); begin { Mise jour de la barre de statut } Police.Caption := Edition.Font.Name + ' ' + IntToStr(Edition.Font.Size); if fsBold in Edition.Font.Style then Police.Caption := Police.Caption + ' gras'; if fsItalic in Edition.Font.Style then Police.Caption := Police.Caption + ' italique';
Delphi et Kylix

184

L. Jourdan

MIAGE 2me anne

if fsUnderline in Edition.Font.Style then Police.Caption := Police.Caption + ' soulign'; if fsStrikeOut in Edition.Font.Style then Police.Caption := Police.Caption + ' barr'; end; La barre dOutils Crer la barre doutils Placer un Panel dans la fiche, nommez-le BarreOutils , affecter la valeur alTop sa proprit Align et redimensionnez-le pour lui donner une hauteur raisonnable. Placer des boutons de commande 3 boutons : Couper, Copier et Coller. Pour cela ajouter 3 fois le composant TurboBouton (SpeedButton) sur la barre doutils. Affecter leur une image qui leur conviennent (image des oprations du presse papiers). .

Il faut ragir lvnement OnClick sur ces boutons et donc reprendre les mthodes existantes qui sont les mthode de raction aux commandes du menu. Pour raffecter une mme mthode de raction plusieurs vnement, il suffit de la dfinir une premire fois et de la choisir pour les autres vnements partir de la bote options de la zone de saisie des vnement en question. (Donc ne pas rcrire la mthode !). Placer des boutons dtat Nous pouvons placer des boutons pour indiquer si la police est grasse, italique, souligne et/ou barre. Ces boutons doivent rester enfoncs pour marquer ltat, de plus, lutilisateur peut agir directement sur ces boutons pour changer ltat de la police. 4 turboboutons (SpeedButton) nomms Gras , Italique , Souligne et barre dans une font de 14 points en Times new roman.

Proprits intressantes : GroupIndex : regroupe logiquement des SpeedButton pour quils se comportent comme des radio boutons (un seul enfonc la fois) AllowAllUp : autorise ou non que tous les boutons soient relevs la fois (e.i. : aucun slectionn) Down : indique si le bouton est ltat enfonc ou non Pour notre cas : les boutons peuvent tre individuellement slectionns ou non, nous devons donc leur affecter un numro de groupe diffrent. Nous allons de plus autoriser que tous les boutons soient relevs en rendant vraie leur proprit AllowAllUp Lorsque la police est modifie, nous devons mettre jour notre barre doutils dans les mthodes de raction aux vnements OnCreate de la fiche et OnClick de la commande Texte|Police Gras.Down := fsBold in Edition.Font.Style; Italique.Down := fsItalic in Edition.Font.Style; Souligne.Down := fsUnderline in Edition.Font.Style; Barre.Down := fsStrikeOut in Edition.Font.Style;
Delphi et Kylix

185

L. Jourdan

MIAGE 2me anne

Ltat de la police est maintenant reflt. Il reste ragir aux clics sur ces boutons pour reporter les modifications adquates dans la police : procedure TForm1.GrasClick(Sender: TObject); begin if Gras.Down then Edition.Font.Style := Edition.Font.Style + [fsBold] else Edition.Font.Style := Edition.Font.Style - [fsBold]; { Mise jour de la barre de statut } Police.Caption := Edition.Font.Name + ' ' + IntToStr(Edition.Font.Size); if fsBold in Edition.Font.Style then Police.Caption := Police.Caption + ' gras'; if fsItalic in Edition.Font.Style then Police.Caption := Police.Caption + ' italique'; if fsUnderline in Edition.Font.Style then Police.Caption := Police.Caption + ' soulign'; if fsStrikeOut in Edition.Font.Style then Police.Caption := Police.Caption + ' barr'; end; procedure TForm1.ItaliqueClick(Sender: TObject); begin if Italique.Down then Edition.Font.Style := Edition.Font.Style + [fsItalic] else Edition.Font.Style := Edition.Font.Style - [fsItalic]; { Mise jour de la barre de statut } Police.Caption := Edition.Font.Name + ' ' + IntToStr(Edition.Font.Size); if fsBold in Edition.Font.Style then Police.Caption := Police.Caption + ' gras'; if fsItalic in Edition.Font.Style then Police.Caption := Police.Caption + ' italique'; if fsUnderline in Edition.Font.Style then Police.Caption := Police.Caption + ' soulign'; if fsStrikeOut in Edition.Font.Style then Police.Caption := Police.Caption + ' barr'; end; procedure TForm1.SouligneClick(Sender: TObject); begin if Souligne.Down then Edition.Font.Style := Edition.Font.Style + [fsUnderline] else Edition.Font.Style := Edition.Font.Style - [fsUnderline]; { Mise jour de la barre de statut } Police.Caption := Edition.Font.Name + ' ' + IntToStr(Edition.Font.Size); if fsBold in Edition.Font.Style then Police.Caption := Police.Caption + ' gras'; if fsItalic in Edition.Font.Style then Police.Caption := Police.Caption + ' italique'; if fsUnderline in Edition.Font.Style then Police.Caption := Police.Caption + ' soulign'; if fsStrikeOut in Edition.Font.Style then Police.Caption := Police.Caption + ' barr'; end; procedure TForm1.BarreClick(Sender: TObject); begin if Barre.Down then Edition.Font.Style := Edition.Font.Style + [fsStrikeOut] else Edition.Font.Style := Edition.Font.Style - [fsStrikeOut]; { Mise jour de la barre de statut } Police.Caption := Edition.Font.Name + ' ' + IntToStr(Edition.Font.Size); if fsBold in Edition.Font.Style then Police.Caption := Police.Caption + ' gras'; if fsItalic in Edition.Font.Style then Police.Caption := Police.Caption + ' italique'; if fsUnderline in Edition.Font.Style then Police.Caption := Police.Caption + ' soulign'; if fsStrikeOut in Edition.Font.Style then Police.Caption := Police.Caption + ' barr'; end; Lignes permettant de mettre jour la barre dtat : procedure TForm1.FormCreate(Sender: TObject); begin { Mise jour de la barre de statut } Police.Caption := Edition.Font.Name + ' ' + IntToStr(Edition.Font.Size); Delphi et Kylix 186 L. Jourdan

MIAGE 2me anne

if if if if

fsBold in Edition.Font.Style then Police.Caption := Police.Caption + ' gras'; fsItalic in Edition.Font.Style then Police.Caption := Police.Caption + ' italique'; fsUnderline in Edition.Font.Style then Police.Caption := Police.Caption + ' soulign'; fsStrikeOut in Edition.Font.Style then Police.Caption := Police.Caption + ' barr';

{ Mise jour de la barre d'outils } Gras.Down := fsBold in Edition.Font.Style; Italique.Down := fsItalic in Edition.Font.Style; Souligne.Down := fsUnderline in Edition.Font.Style; Barre.Down := fsStrikeOut in Edition.Font.Style; end; Les conseils daide Les meilleures applications prsentent des explications quant la fonctions des boutons des barres doutils et des commandes des menus. Tout composant visuel (contrle) a une proprit Hint reprsentant une chane de caractres nous informant sur sa fonction. La proprit ShowHints du volet (Panel) permet dautoriser ou non laffichage des conseils daide (Hint) des contrles quil contient. Lvnement OnHint du composant Application (qui reprsente votre application) permet de ragir au changement de contrle point par la souris pour afficher le conseil daide associ de la faon que vous voulez. Dans notre cas : Pour chaque bouton, ajouter des conseils daide et mettre la proprit ShowHints de la barre doutil vrai. Idem pour la barre de statut. Exercice : Rependre la visualisateur de forme : ajouter une barre de statut qui reprend les proportions des marges ajouter une barre doutils contenant des boutons avec leur conseil daide pour activer les diffrentes botes

Les menus surgissants Un menu surgissant = menu qui saffiche lorsque lutilisateur slectionne un composant et clique sur le bouton droit de la souris. Composant : PopupMenu , sa proprit AutoPopup lui permet de se dclencher automatiquement en laffectant la proprit PopupMenu du composant auquel il se rapporte. Placer un menu surgissant dans lditeur de texte et dfinir des entres pour le press-papier et associez le la proprit PopupMenu du mmo Edition. Nous dfinissons les commandes du press-papiers dans le menu surgissant ajout comme dans le menu principal : couper2 , copier2 et coller2 .

Delphi et Kylix

187

L. Jourdan

MIAGE 2me anne

Pour dfinir les ractions ces commandes, vous pouvez rutiliser les mthoes de raction aux commandes du presspapiers du menu principal (Couper1Click.). Vous pouvez y accder directement dans le volet vnement de lexplorateur de composant et accder aux ractions dj dfinies. Exercice : Ajouter au visualisateur de forme un menu surgissant qui appelle les botes de changement de police et de changement de marge.

K.

TP11 DELPHI : Applications SDI et MDI

Tous les exemples tudis jusqu prsent sont des application SDI (Simple Document Interface) cest dire quelles ne comportent quune seule fentre Toutes les fentres que nous avons utilis er jusqu aujourdhui se grent sparment dans le temps. Nous allons maintenant tudier comment grer plusieurs fentre en mme temps dans le cadre de palettes doutils flottantes ainsi que dans le cadre dapplication MDI (Multiple Document Interface). 1. Palette doutils

Les palettes doutils contrairement au barre doutils sont dans leur propre fentre. Nous allons reprendre le TP de lditeur de texte et nous allons crer une autre barre doutils qui pourra se transformer en palette doutils par un simple glisser dplacer et vice versa. a) Modification de la fiche

Ajouter un panel BarrePolice et y placer les 4 boutons de style. Pour dplacer dun panel vers un autre les composants il faut les slectionner et les couper puis les coller Vous obtenez la fiche suivante :

Delphi et Kylix

188

L. Jourdan

MIAGE 2me anne

BarrePolice

Pour transformer la barre doutils en palette doutils, nous allons utiliser le glisser-dplacer automatique en mettant la proprit DragMode de la barrePolice dmAutomatic. Cette transformation se ralise en dplaant la barre de police de la fentre dans une autre fentre. Cration de la palette : Crer une fentre de nom PalettePolice et de titre Police. Enregistrer sous le nom Palette et lajouter dans la liste des units du main. Fixer ses dimension : BorderStyle = bsSingle Supprimer le bouton dagrandissement de la barre de titre (borderincons ..) Lobliger rester toujours visible FormStyle=fsStayOnTop b) Dfinition du glisser-dplacer Rappel : nous devons dfinir 2 mthodes pour prciser si le drop peut se faire (OnDragOver) et si oui comment il se fait (OnDragDrop). Le drop est autoris sur le mmo. procedure TForm1.EditionDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin Accept := Source = BarrePolice; end; Il y a 2 origines au drop de la barre de police : soit elle va de la fentre principale vers la palette, soit elle va de la palette pour retourner la fentre principale. Dans le premier cas, nous plaons la barre dans la palette, ajustons la taille de cette dernire et la rendons visible : BarrePolice.Parent := PalettePolice; PalettePolice.ClientHeight := BarrePolice.Height + 1; PalettePolice.ClientWidth := Barre.Left + Barre.Width + 5; PalettePolice.Visible := True; Dans le second cas, nous cachons la palette et replaons la barre sa place dans la fentre principale : PalettePolice.Visible := False; BarrePolice.Parent := Self;

Le problme de cette faon doprer est que notre barre vient se placer en haut de la fentre principale au lieu de reprendre sa place habituelle. Une solution est denlever cette dernire barre pour la replacer dans la fentre principale : BarreOutils.Parent := PalettePolice; BarreOutils.Parent := Self; Delphi et Kylix 189 L. Jourdan

MIAGE 2me anne

Il nous reste dterminer dans quel sens le dplacement a lieu. Une solution simple est de tester si le parent de BarrePolice est la fentre principale. Ce qui nous donne finalement le code suivant : procedure TForm1.EditionDragDrop(Sender, Source: TObject; X, Y: Integer); begin if BarrePolice.Parent = Self then begin { de la barre la palette } BarrePolice.Parent := PalettePolice; PalettePolice.ClientHeight := BarrePolice.Height + 1; PalettePolice.ClientWidth := Barre.Left + Barre.Width + 5; PalettePolice.Visible := True; end else begin { de la palette la barre } PalettePolice.Visible := False; BarrePolice.Parent := Self; BarreOutils.Parent := PalettePolice; BarreOutils.Parent := Self; end; end ;

c)

Applications MDI

Les applications MDI (Multiple Document Interface) sont courantes en Windows, bien que Delphi nen soit pas une. Vous pouvez en dvelopper en Delphi de 3 faons : 1 Gnration Automatique Il existe un modle (template) pour gnrer automatiquement des applications SDI et MDI de la mme manire que nous avions une modle de bote Propos. Crer un nouveau projet MDI, choisissez un rpertoire. 2- Construction de toutes pices (1) Unit principale : Main, projet TP10b (2) Fentre principale MDI Crer un nouveau projet

Transformez la fiche actuelle en fentre principale MDI : FormStyle=fsMDIForm. Name=Principale Caption=Editeur Menu dentres classique : Fichier (Nouveau,Ouvrir ) Menu Fentre avec les commandes Cascade, Mosaque et Arrange icnes. (3) Crer une fentre fille

Crez une autre fiche nomme FilleMDI dont la proprit FormStyle aura la valeur fsMDIChild. Ajoutez la rfrence cette unit dans la partie Uses de lunit principale (main). Nous allons maintenant faire en sorte que la fentre fille ne soit pas cre automatiquement au dbut du programme. (4) Choisir la cration automatique ou non des fiches

Pour empcher des fiches de se crer automatiquement au moyen de la bote option du projet accessible par le menu Option|Projet

Delphi et Kylix

190

L. Jourdan

MIAGE 2me anne

Cette bote nous permet de rpartir, au moyen des boutons flchs ou du glisser dplacer, toutes les fiches disponibles dans 2 listes : 1. La liste des fiches devant tre automatiquement cres ( Auto-crer fiches ) 2. La liste des fiches ne devant pas tre automatiquement cres ( Fiches disponibles ) Dplaons dans FilleMDI vers la liste Fiches disponibles . La fentre principale ( Fiche principale ) devient alors automatiquement Principale cest--dire la premire fiche que nous avons cre, puisque cest la seule qui soit cre au dmarrage de lapplication. (a) Personnaliser la fentre fille

Plaons donc un composant mmo vide dans la fiche de la fentre fille MDI avec le nom Edition . Nous affichons les barres de dfilement verticale et horizontale. Enfin, nous modifions quelque peu le comportement de la fentre fille lorsquelle est ferme : par dfaut, elle devient invisible mais nest pas dtruite pour autant. Ce que nous voulons, cest quelle soit dtruite lorsquelle est ferme. Nous ajoutons donc une mthode de raction lvnement OnClose : procedure TFilleMDI.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; { demande la destruction } end; Lors de la fermeture dune fentre vous avez la possibilit de la rendre invisible caHide, de ne pas la fermer caNone ou de la dtruire caFree. (b) Rpondre au menu principale

Savoir ragir Fichier|Quitter et toute les commande du menu fentre ; Nous obtenons : procedure TPrincipale.Quitter1Click(Sender: TObject); begin Close; { Ferme la fentre principale } end; procedure TPrincipale.Cascade1Click(Sender: TObject); begin Cascade; { rpartie en cascade les fentres filles } end; Delphi et Kylix 191

L. Jourdan

MIAGE 2me anne

procedure TPrincipale.Mosaque1Click(Sender: TObject); begin Tile; { rpartie en mosaque les fentres filles } end; procedure TPrincipale.Arrangeicnes1Click(Sender: TObject); begin ArrangeIcons; { rpartie les icnes des fentres filles } end; Commandes Fichier|Nouveau et Fichier|Ouvrir Pour ces 2 commandes, nous devons crer une fentre fille (une instance de FilleMDI) et lafficher. Dans le 1er cas : titre = le numro dordre Dans le 2nd cas : titre = nom du fichier ouvert Nous allons regrouper le comportement commun de ces 2 commandes en crant une mthode CreerFenetreFille qui prendra le nom du fichier ouvrir ou la chane vide si il ny a pas de nom. procedure TPrincipale.CreerFenetreFille(nomFichier: string); var fille: TFilleMDI; begin fille := TFilleMDI.Create( Self ); { Cr la fentre fille } if nomFichier <> '' then begin { il existe un nom de fichier : charge le fichier } fille.Edition.Lines.LoadFromFile( nomFichier ); fille.Caption := nomFichier; end else begin { nouvelle fentre } Inc( Numero ); fille.Caption := 'Inconnu ' + IntToStr( Numero ); end; fille.Visible := True; end; Il reste dclarer dans la partie Private cette mthode et la variable Numro qui comptabilise le nombre de fentre cres par le commande nouvelle. Numero: Integer; procedure CreerFenetreFille(nomFichier: string); Rpondre aux vnements : procedure TPrincipale.Nouveau1Click(Sender: TObject); begin CreerFenetreFille( '' ); end; procedure TPrincipale.Ouvrir1Click(Sender: TObject); begin if OpenDialog1.Execute then CreerFenetreFille( OpenDialog1.FileName ); end; Il faut de plus vrifier que le fichier existe bien ofPathMustExist et ofFileMustExist vrai. Amlioration : Enregistrement : procedure TPrincipale.Fichier1Click(Sender: TObject); begin Enregistrer1.Enabled := MDIChildCount > 0;
Delphi et Kylix

192

L. Jourdan

MIAGE 2me anne

Enregistrersous1.Enabled := MDIChildCount > 0; end; procedure TPrincipale.Enregistrer1Click(Sender: TObject); begin if Copy(ActiveMDIChild.Caption, 1, 7) = 'Inconnu' then { pas encore de nom => comme Enregistrer sous } EnregistrerSous1Click( Sender ) else (ActiveMDIChild as TFilleMDI).Enregistrer; end; procedure TPrincipale.Enregistrersous1Click(Sender: TObject); begin if SaveDialog1.Execute then begin ActiveMDIChild.Caption := SaveDialog1.FileName; Enregistrer1Click( Sender ); end; end; Vous pouvez reprendre ce principe pour griser les commandes Cascade, Mosaque et Arranges icnes du sous menu Fentre : procedure TPrincipale.Fentre1Click(Sender: TObject); begin Cascade1.Enabled := MDIChildCount > 0; Mosaque1.Enabled := MDIChildCount > 0; Arrangeicnes1.Enabled := MDIChildCount > 0; end;

L.

TP 12 : Crer un composant

Calendrier Vous allez crer un calendrier, non pas partir dune grille mais de TgraphicControl qui est une spcialisation de Tcontrol, lequel possde un canvas pour son affichage. Nous devons donc dterminer la faon dont il saffiche, dont il ragit au clic de la souris 1. Crer un nouveau composant Le dmarche pour crer le squelette de tout nouveau composant est exactement la mme, seule la classe de base peut tre plus ou moins leve dans la hierarchie de classes des composants. Appelons ce nouveau composant TDLICalendar . Il est bas sur le composant TgraphicControl et se placera dans la page DLI 551 . 2. Dclaration

Une fois le squelette gnr, il faut ajouter les proprit et les vnement au composant. a) Evnements existants

Les plus vidents sont les vnements habituels OnClick et OnDblClick qui sont dclenchs lorsquun clic, simple ou double, est effectu sur une date. Traditionnellement, un composant peut aussi grer le glisser-dplacer (OnDragOver et OnDragDrop) et la souris (OnMouseDown, OnMouseMove et OnMouseUp). Ces vnements existent dans la partie protge de la classe Tcontrol. Pour les utiliser, il suffit de changer leur droit daccs en les redclarant partiellement dans la partie publie : published
Delphi et Kylix

193

L. Jourdan

MIAGE 2me anne

{ Published declarations } property OnClick; property OnDblClick; property OnDragOver; property OnDragDrop; property OnMouseDown; property OnMouseMove; property OnMouseUp; b) Evnement ajouts

On fournit habituellement le moyen de prvenir tout changement au sein du composant par lvnement OnChange. Ajoutez aussi un autre vnement OnVisibleChange dclench lorsque le mois visualis dans le calendrier change. Ainsi, il faut dclarer 2 autres variables dinstances pour ces deux vnements : private { Private declarations } FOnChange: TNotifyEvent; FOnVisibleChange: TNotifyEvent; Ainsi que les 2 vnements eux-mmes : property OnChange: TNotifyEvent read FOnChange write FOnChange; property OnVisibleChange: TNotifyEvent read FOnVisibleChange write FOnVisibleChange; Pour traiter les appels aux mthodes rfrences par les variables reprsentant les vnements, nous allons dfinir deux mthodes protges pour que les classes drives (si un jour elles existent) puissant aussi y accder : protected { Protected declarations } procedure Changed; procedure VisibleChange ; Il reste maintenant declarer un nouveau constructeur qui initialise, entre autres, les variables dinstances nil : public { Public declarations } constructor Create(AOwner: TComponent); override; c) Proprits existantes

En ce qui concerne les proprits, le principe est le mme : nous pouvons constater que certaines proprits sont hrites de Tcontrol, en particulier Name et Tag publies pour tout composant (dfinies au niveau de TComponent) ainsi que Cursor, Hint et les coordonnes Top, Left, Height et Width publies pour les composant visuels. Il existe beaucoup dautres proprits protgs suivantes : Color, DragCursor, DragMode, Font, ParentColor et ParentFont. Pour rutiliser ces proprits dj existantes, il suffit de redclarer partiellement au niveau daccs suprieur voulu, en loccurrence : publi. published { Published declarations } property Color; property DragCursor; property DragMode; property Font; property ParentColor; property ParentFont; d) Proprits ajoutes

Puisque nous crons un calendrier, nous avons la proprit Date. Nous nous donnons aussi la possibilit de changer le mois afficher au moyen des touches [PgUp] et [PgDn] ainsi que les flches visualises. Nous devons donc dfinir les proprits VisibleMonth et VisibleYear. Enfin, nous limitons laccs entre deux dates : DateMin et DateMax.
Delphi et Kylix

194

L. Jourdan

MIAGE 2me anne

En ce qui concerne la prsentation du calendrier, nous pouvons afficher avec une autre fonte le jour courant (TodayFont) et le jour slectionn (SelectedDayFont). Enfin, pour rendre ce comp osant indpendant de la lange de lutilisateur, nous ajoutons une proprit Labels qui est un ensemble de chanes de caractres reprsentant les mois de lanne suivis des jours de la semaine. Pour pouvoir implmenter ces diffrentes proprits, nous devons dclarer des variables dinstances pour conserver leur valeur, ainsi que des mthodes permettant laccs ces valeurs : FDate: TDateTime; FVisibleMonth: Word; FVisibleYear: Word; FDateMin: TDateTime; FDateMax: TDateTime; FSelectedDayFont: TFont; FTodayFont: TFont; FLabels: TStrings; function GetDate: string; procedure SetDate(ADate: string); procedure SetVisibleMonth(AMonth: Word); procedure SetVisibleYear(AYear: Word); function GetDateMin: string; procedure SetDateMin(ADate: string); function GetDateMax: string; procedure SetDateMax(ADate: string); procedure SetSelectedDayFont(AFont: TFont); procedure SetTodayFont(AFont: TFont); procedure SetLabels(Value: TStrings); protected { Protected declarations } LastVisibleMonthDay: Word; FirstVisibleDate, LastVisibleDate: TDateTime; procedure Changed; procedure VisibleChange(Sender: TObject); Etant donne que nous avons des vnements signalant des changements, nous devons dfinir des mthodes en criture pour les proprits afin dappeler les mthodes Changed et VisibleChanged dfinies prcdemment : published property Date: string read GetDate write SetDate; property VisibleMonth: Word read FVisibleMonth write SetVisibleMonth; property VisibleYear: Word read FVisibleYear write SetVisibleYear; property DateMin: string read GetDateMin write SetDateMin; property DateMax: string read GetDateMax write SetDateMax; property SelectedDayFont: TFont read FSelectedDayFont write SetSelectedDayFont; property TodayFont: TFont read FTodayFont write SetTodayFont; property Labels: TStrings read FLabels write SetLabels; Puisque certaines variables font reference des objets (FselectedDayFont et FtodayFont) leur initialisation ncessite de crer ces objets par leur constructeur Create dans le constructeur de notre composant. Nous devons ensuite les dtruire dans notre destructeur : public { Public declarations } constructor Create(AOwner: TComponent); override; destructor Destroy; override; 3. Implmentation

Il nous faut maintenant implmenter toutes ces mthodes. Commenons par le constructeur et le destructeur : constructor TDLICalendar.Create(AOwner: TComponent); var jour: Word; begin Delphi et Kylix 195 L. Jourdan

MIAGE 2me anne

inherited Create(AOwner); FOnChange := nil; FOnVisibleChange := nil; FDate := SysUtils.Date; DecodeDate(FDate, FVisibleYear, FVisibleMonth, jour); FDateMin := 0; FDateMax := 0; FSelectedDayFont := TFont.Create; FSelectedDayFont.OnChange := VisibleChange; FTodayFont := TFont.Create; FTodayFont.OnChange := VisibleChange; FLabels := TStringList.Create; TStringList(FLabels).OnChange := VisibleChange; FLabels.Add('Janvier'); FLabels.Add('Fvrier'); FLabels.Add('Mars'); FLabels.Add('Avril'); FLabels.Add('Mai'); FLabels.Add('Juin'); FLabels.Add('Juillet'); FLabels.Add('Aot'); FLabels.Add('Septembre'); FLabels.Add('Octobre'); FLabels.Add('Novembre'); FLabels.Add('Dcembre'); FLabels.Add('Di'); FLabels.Add('Lu'); FLabels.Add('Ma'); FLabels.Add('Me'); FLabels.Add('Je'); FLabels.Add('Ve'); FLabels.Add('Sa'); UpdateVars; end; destructor TDLICalendar.Destroy; begin FSelectedDayFont.Free; FTodayFont.Free; FLabels.Free; inherited Destroy; end; Lajout de la raction lvnement OnChange des fontes et de la liste permet de mettre jour laffichage du calendrier lorsque celle-ci sont modifies. Nous sommes cependant obligs dajouter une autre mthode (VisibleChange) qui soit du bon type pour une raction ie avec un seul paramtre Sender. Cette mthode doit tre dclare dans la partie protge et implmente en appelant notre mthode VisibleChanged : procedure TDLICalendar.VisibleChange(Sender: TObject); begin VisibleChanged; end; Les mthodes de gestion de date sont trs simple : unction TDLICalendar.GetDate: string; begin Result := DateToStr(FDate); Delphi et Kylix 196

L. Jourdan

MIAGE 2me anne

end; procedure TDLICalendar.SetDate(ADate: string); var date: TDateTime; begin date := StrToDate(ADate); if (FDate = date) or ((date < FDateMin) or ((FDateMax > 0) and (date > FDateMax))) then Exit; FDate := date; Changed; end;

function TDLICalendar.GetDateMin: string; begin if FDateMin = 0 then Result := '' else Result := DateToStr(FDateMin); end; procedure TDLICalendar.SetDateMin(ADate: string); var date: TDateTime; begin if ADate = '' then date := 0 else date := StrToDate(ADate); if (FDateMin = date) or ((FDateMax > 0) and (date > FDateMax)) then Exit; FDateMin := date; Changed; end; function TDLICalendar.GetDateMax: string; begin if FDateMax = 0 then Result := '' else Result := DateToStr(FDateMax); end; procedure TDLICalendar.SetDateMax(ADate: string); var date: TDateTime; begin if ADate = '' then date := 0 else date := StrToDate(ADate); if (FDateMax = date) or ((date > 0) and (date < FDateMin)) then Exit; FDateMax := date; Changed; end;

Delphi et Kylix

197

L. Jourdan

MIAGE 2me anne

En ce qui concerne SetVisibleMonth et SetVisibleYear, il faut appeler la mthode VisibleChanged et non pas Changed : procedure TDLICalendar.SetVisibleMonth(AMonth: Word); begin if (FVisibleMonth = AMonth) or (AMonth < 1) or (12 < AMonth) then Exit; FVisibleMonth := AMonth; UpdateVars; VisibleChanged; end; Les mthodes SetSelectedDayFont, SetTodayFont et SetLabels ne font que changer la valeur de la variable, leur vnement OnChange permettant de rafficher le composant : procedure TDLICalendar.SetSelectedDayFont(AFont: TFont); begin FSelectedDayFont.Assign(AFont); end; procedure TDLICalendar.SetTodayFont(AFont: TFont); begin FTodayFont.Assign(AFont); end; procedure TDLICalendar.SetLabels(Value: TStrings); begin FLabels.Assign(Value); end; Il reste dfinir les mthodes Changed et VisibleChanged : procedure TDLICalendar.Changed; begin if Assigned(FOnChange) then FOnChange(Self); VisibleChanged; end; procedure TDLICalendar.VisibleChange(Sender: TObject); begin VisibleChanged; end; procedure TDLICalendar.VisibleChanged; begin if Assigned(FOnVisibleChange) then FOnVisibleChange(Self); Refresh; end; Refresh permet de rafficher le composant aussitt. 4. Grer son affichage

Laffichage se fait en utilisant la proprit Canvas du contrle dans sa mthode Paint. a) Dclaration

Nous avons donc une seule ligne de dclaration dans la partie protge : procedure Paint; override;

Delphi et Kylix

198

L. Jourdan

MIAGE 2me anne

b)

Implmentation

procedure TDLICalendar.Paint; var largeurJour, hauteurJour: Integer; jourSel, jourHui: Word; jour, mois, annee: Word; j, l, c: Integer; ecart: Integer; minimal, maximal: Boolean; chaine: string; r: TRect;

7 colonnes et 8 lignes

procedure afficheJours(debut, fin: Word; var ligne, colonne: Integer; sel, hui: Word); var jour: Word; begin with Canvas do for jour := debut to fin do begin if jour = sel then begin { Affichage du jour slectionn } Font := FSelectedDayFont; TextOut(c*largeurJour-ecart, l*hauteurJour, IntToStr(jour)); Font := Self.Font; end else if jour = hui then begin { Affichage d'aujourd'hui } Font := FTodayFont; TextOut(c*largeurJour-ecart, l*hauteurJour, IntToStr(jour)); Font := Self.Font;
Delphi et Kylix

199

L. Jourdan

MIAGE 2me anne

end else TextOut(c*largeurJour-ecart, l*hauteurJour, IntToStr(jour)); if colonne < 7 then { Change de jour dans la semaine } Inc(colonne) else begin { Change de semaine } colonne := 1; Inc(ligne); end; end; end; begin largeurJour := ClientWidth div 7; hauteurJour := ClientHeight div 8; with Canvas do begin { Remplissage du fond } Brush.Color := Color; r := GetClientRect; Rectangle(r.left, r.top, r.right, r.bottom); { Affichage du mois } MoveTo(0, hauteurJour); LineTo(Width, hauteurJour); Font := Self.Font; chaine := FLabels[FVisibleMonth-1] + ' ' + IntToStr(FVisibleYear); r := Rect(largeurJour+1,0,Width-largeurJour-1,hauteurJour-1); SetBkMode(Canvas.Handle, TRANSPARENT); DrawText(Canvas.Handle, @chaine[1], Length(chaine), r, DT_CENTER or DT_SINGLELINE or DT_VCENTER); { Affichage des noms des jours } MoveTo(0, 2*hauteurJour); LineTo(Width, 2*hauteurJour); r := Rect(0, hauteurJour+1, largeurJour, 2*hauteurJour-1); for j := 12 to 18 do begin chaine := FLabels[j]; DrawText(Canvas.Handle, @chaine[1], Length(chaine), r, DT_CENTER or DT_SINGLELINE or DT_VCENTER); r.left := r.right; inc(r.right, largeurJour); end; { Affichage des jours } minimal := FirstVisibleDate <= FDateMin; maximal := (FDateMax <> 0) and (LastVisibleMonthDay >= FDateMax); ecart := largeurJour div 10; DecodeDate(SysUtils.date, annee, mois, jourHui); if (annee <> FVisibleYear) or (mois <> FVisibleMonth) then jourHui := 0; DecodeDate(FDate, annee, mois, jourSel); if (annee <> FVisibleYear) or (mois <> FVisibleMonth) then jourSel := 0; SetTextAlign(Canvas.Handle, TA_RIGHT); j := 1; c := DayOfWeek(FirstVisibleDate);
Delphi et Kylix

200

L. Jourdan

MIAGE 2me anne

l := 2; if minimal then begin { Affiche les premiers jours invalides } Font.Color := clGrayText; DecodeDate(FDateMin, annee, mois, jour); afficheJours(1, jour-1, l, c, 0, 0); Font := Self.Font; j := jour; end; if maximal then DecodeDate(FDateMax, annee, mois, jour) else jour := LastVisibleMonthDay; { Affiche les jours valides } afficheJours(j, jour, l, c, jourSel, jourHui); if maximal then begin { Affiche les derniers jours invalides } Font.Color := clGrayText; afficheJours(jour+1, LastVisibleMonthDay, l, c, 0, 0); Font := Self.Font; end; { Bouton mois prcdent } if minimal then Brush.Color := clSilver else Brush.Color := clWhite; MoveTo(largeurJour, 0); LineTo(largeurJour, hauteurJour); Polygon([Point(largeurJour div 4, hauteurJour div 2), Point(largeurJour*3 div 4, hauteurJour *3 div 4), Point(largeurJour*3 div 4, hauteurJour div 4)]); { Bouton mois suivant } ?????? A faire end; end; 5. Grer les clics

Pour grer nous-mmes les clics, nous allons redfinir la mthode qui gre lvnement OnMouseDown. Redfinissez, dans la mesure du possible, la mthode qui gre un vnement pour modifier son occurrence. Cette mthode sappelle MouseDown. Elle a pour paramtres le bouton appuy a) Dclaration Nous allons redclarer la mthode qui gre lvnement OnMouseDown dans la partie protgz mais avec la directive de redirection Override : procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; Nous avons besoin des variables suivantes : 1- le dernier jour du mois visible 2- date du premier jour du mois visible 3- date du dernier jour du mois visible Ces variables doivent tre recalcules grce une mthode UpdateVars : Nous avons besoin de dclarer : protected
Delphi et Kylix

201

L. Jourdan

MIAGE 2me anne

{ Protected declarations } LastVisibleMonthDay: Word; FirstVisibleDate, LastVisibleDate: TDateTime; procedure UpdateVars; b) Implmentation

procedure TDLICalendar.UpdateVars; const JoursMois: array[1..12] of Integer = (31,29,31,30,31,30,31,31,30,31,30,31); begin LastVisibleMonthDay := JoursMois[FVisibleMonth]; if (FVisibleMonth = 2) and (FVisibleYear mod 4 <> 0) then Dec(LastVisibleMonthDay); FirstVisibleDate := EncodeDate(FVisibleYear, FVisibleMonth, 1); LastVisibleDate := EncodeDate(FVisibleYear, FVisibleMonth, LastVisibleMonthDay); end;

procedure TDLICalendar.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var l, c: Integer; j: Integer; mois, annee: Word; begin l := Y div (Height div 8); c := X div (Width div 7); case l of 0: begin { On a cliqu sur la premire ligne } case c of 0: { Mois prcdent } if FirstVisibleDate > FDateMin then { changement possible } if FVisibleMonth > 1 then VisibleMonth := FVisibleMonth - 1 else begin { On change d'anne } Dec(FVisibleYear); VisibleMonth := 12; end; 6: { Mois suivant } if (FDateMax = 0) or (LastVisibleDate < FDateMax) then { Changement possible } if FVisibleMonth < 12 then VisibleMonth := FVisibleMonth + 1 else begin { On change d'anne } Inc(FVisibleYear); VisibleMonth := 1; end; end; end; 2..7: { On a cliqu dans les jours } begin
Delphi et Kylix

202

L. Jourdan

MIAGE 2me anne

j := (l-2) * 7 + c - DayOfWeek(FirstVisibleDate) + 2; if (1 <= j) and (j <= LastVisibleDate) then Date := DateToStr(EncodeDate(FVisibleYear, FVisibleMonth, j)); end; end; inherited MouseDown(Button, Shift, X, Y); end; Installez ce nouveau composant et tester le !!!! Vous pouvez le tlcharger sur www.lifl.fr/~jourdan

Delphi et Kylix

203

L. Jourdan

Delphi et KyliX : des descendants de Pascal

L. Jourdan

D. Mailliet