Académique Documents
Professionnel Documents
Culture Documents
ISIMA 1988-1999
3. ETUDE DE LA VCL 17
7.1 GNRALITS 71
7.2 CRATION DUN NOUVEAU COMPOSANT 71
7.2.1 LEXPERT COMPOSANT 72
7.2.2 DE QUEL COMPOSANT DRIVER ? 74
7.3 EXERCICE RSOLU : CRATION DU COMPOSANT TLISTBOXCOOL 76
Figures
Programmes
Programme 3.1 Ajout dune ligne saisie dans une bote combo..................................................................................27
Programme 3.2 Affichage de styles de traits dans une bote combo............................................................................29
Programme 3.3 Lvnement OnMeasureItem de calcul de hauteur dun lment de bote combo .............................30
Programme 3.4 trac dun trait dpaisseur variable dans une bote combo ..............................................................31
Programme 3.5 Dclarations relatives la mise en place de la liste des derniers fichiers ouverts .............................36
Programme 3.6 Code dimplmentation du remplissage de la liste ............................................................................37
Programme 7.1 Programme daffichage des index et des lments slectionns dune bote de liste ..........................77
Programme 7.2 Vers une utilisation plus simple des botes de listes...........................................................................77
Programme 7.3 Dclaration de la code TListBoxCool ...............................................................................................80
Programme 7.4 Implmentation de la mthode daccs getIndices ......................................................................81
Programme 7.5 Utilisation de la proprit Indices ................................................................................................82
Programme 7.6 Mise en place dattributs de stockage des proprits ........................................................................85
Programme 7.7 Dclaration de mthodes daccs et des proprits ...........................................................................85
Programme 7.8 dclaration simplifie de la classe Set ............................................................................................88
Programme 7.9 Constructeur du composant Calculette..............................................................................................91
Programme 7.10 Publication des proprits caches .................................................................................................91
Programme 7.11 code dimplmentation des mthodes daccs en criture aux proprits financires ..................92
Programme 7.12 Prototype des vnements de type Notification................................................................................94
Programme 7.13 Prototypes des vnements associs au clavier ...............................................................................95
Programme 7.14 implmentation dun gestionnaire dvnement interne...................................................................96
Programme 7.15 Utilisation de la bote de dialogue de saisie du taux de lEuro........................................................98
Programme 7.16 Code du constructeur....................................................................................................................100
Programme 7.17 Code de Paint ...............................................................................................................................101
Programme 7.18 Dclaration et publication dvnements utilisateur .....................................................................102
Programme 7.19 Code associ aux vnements externes du composant de saisie de date.........................................103
Programme 7.20 Code gnrique de prise en compte dun gestionnaire utilisateur..................................................104
Programme 7.21 Prise encompte des vnments spcifiques ..................................................................................104
Programme 7.22 Mise en place du composant .........................................................................................................107
Programme 7.23 Cration des proprits du nouveau composant ............................................................................108
Programme 7.24 la mthode Execute ...................................................................................................................108
Tableaux
Tableau 2.1 Quelques prfixes de nommage pour les composants VCL ......................................................................13
Tableau 3.1 Codes de retour des boutons modaux......................................................................................................20
Tableau 3.2 Quelques proprits du contrle TTrackBar .......................................................................................39
Tableau 3.3 Proprits fondamentales des ascenceurs (TScrollBar).....................................................................41
Tableau 4.1 Correspondance entre oprations dalgbre relationnel et oprations C++ Builder...............................53
Tableau 7.1 Les mthodes de la classe Set ...............................................................................................................89
1.1.1 Philosophie
Tout dabord C++ est un outil RAD, cest dire tourn vers le dveloppement
rapide dapplications (Rapid Application Development) sous Windows. En un mot,
C++ Builder permet de raliser de faon trs simple linterface des applications et de
relier aisment le code utilisateur aux vnements Windows, quelle que soit leur
origine (souris, clavier, vnement systme, etc. )
Pour ce faire, C++ Builder repose sur un ensemble trs complet de composants
visuels prts lemploi. La quasi totalit des contrles de Windows (boutons, botes de
saisies, listes droulantes, menus et autres barres doutils) y sont reprsents,
regroups par famille. Leurs caractristiques sont ditables directement dans une
fentre spciale intitule diteur dobjets. Lautre volet de cette mme fentre permet
dassocier du code au contrle slectionn.
1.1.2 Limitations
Tout dabord, il faut savoir que la technologie RAD ne sapplique quau squelette
ou linterface dune application. Bien entendu, toute la partie spcifique votre
projet reste votre charge.
Du point de vue portabilit, le code C++ Builder nest pas compatible C++ ANSI.
Ceci est du la gestion de la bibliothque des composants visuels et en particulier de
leurs proprits. Pour lheure, il suffit de savoir quune proprit dun objet est
assimilable un attribut auquel on accde par affectation directe dans le code
utilisateur. Toutefois, cet accs apparemment direct masque lutilisation de mthodes
daccs en lecture et / ou criture. Ce systme de proprit a t mis au point par
Loin dtre exhaustive, cette partie ne vise qu placer C++ Builder dans le
cadre des outils RAD les plus prsents sur le march. Ayant peu travaill avec
Visual C++, je prfre ne pas prsenter de comparatif avec cet outil par soucis
dquit. Je prciserai mme, au bnfice de Visual C++, que ce dernier accorde une
bien meilleure place au modle Document/Interface/Contrleur que son rival, au
dtriment dune interface un peu plus complexe utiliser au premier abord.
Tout dabord, il faut savoir que, pour un mme problme, lexcutable fourni par
C++ Builder est toujours un peu plus gros que celui issu de Delphi. Ceci tient au fait
que la bibliothque de composants visuels utilise par les deux reste nativement celle
de Delphi, aussi lexcutable C++ Builder contient-il un module supplmentaire
destin faire le lien avec des objets au format Delphi.
En dehors de a, les deux outils sont trs similaires. Mon choix se portera tout
de mme sur C++ Builder car ce dernier permet une meilleure intgration des
contrles ActiveX et autres mcanismes issus dOLE.
Les diffrences par rapport Borland C++ sont assez nombreuses. La premire
rside dans la nature du code produit. Si OWL, la bibliothque de gestion de la
programmation sous Windows et Borland C++ tait 100% compatible C++ ANSI, la
gestion de la VCL ne lest pas pour les raisons exprimes au paragraphe prcdent.
En outre, C++ Builder pose les problmes communment lis aux outils de haut
niveau. Par exemple, il est trs difficile daccder directement aux messages Windows.
En effet, sil est toujours possible dutiliser les primitives de lAPI Windows, ces
dernires ont elles - mme t encapsules dans une API de plus haut niveau,
fournissant certaines valeurs par dfaut des paramtres clef.
Sil se rvle trs agrable utiliser pour concevoir un micro outil usage
unique ou une macro-commande dans lun de vos logiciels prfrs, son utilisation
vaste chelle devient, mon avis, vite pnible. Deux syntaxes daffectation,
lutilisation quasi systmatique du fameux type variant, linefficacit des commandes
arithmtiques sont autant darguments brandis par les dtracteurs de Visual Basic
(dont je suis) et qui, tout chauvinisme mis part, cartent ce langage des
dveloppements importants.
Cette interface est assez droutante au premier abord car elle noccupe pas tout
lcran. De fait, une partie des crans des autres applications que vous utilisez (ou du
bureau !) est visible.
Thoriquement, C++ Builder se charge de grer les imports et les exports des
diffrentes librairies dynamiques (DLL) utilises. Toutefois, vous pouvez grer cela
manuellement (notamment pour viter quune de vos propres DLL nexporte toutes ses
dfinitions, ce qui est le comportement par dfaut) en ditant manuellement le fichier
des dfinitions (.DEF) puis en appelant lutilitaire implib.
Proprits et leurs
valeurs
Selon le type de la proprit, ldition se fera sous forme dune bote ddition de
texte simple, dans une liste drouler ou mme une fentre spcialise.
Permettez-moi, sil vous plait, de jouer au prof gavant (je sais, je fais a trs
bien) et dinsister sur la proprit Name. Celle-ci est terriblement important car elle
vous permet daccder vos composants lintrieur de votre programme. Par dfaut,
lorsque vous ajoutez un composant une fiche, C++ Builder lui confre un nom
automatique du genre TypeNumro, par exemple le premier label que vous poserez
sur une fiche aura pour nom Label1 ce qui nest gure explicite !
Le type du composant
Sa fonction
Lusage veut que la fonction soit dans le corps du nom alors que le type est
indiqu par un prfixe. La table suivante donne ( titre purement indicatif) quelques
uns des prfixes utiliss dans ce manuel.
pl : panel me : mmo
Tableau 2.1 Quelques prfixes de nommage pour les composants VCL
Objet TImage
slectionn
Liste de mthodes que
lon pourrait affecter
lvnement
Typiquement, ces derniers seront rassembls dans une fentre de groupe. Avec
Borland C++, il tait possible de rediriger les vnements gnrs par les boutons
radio vers la fentre de groupe et de les traiter ainsi avec une seule mthode. Avec la
mthode C++ Builder, tous les vnements tant automatiquement redescendus au
niveau de la fiche, il faudra grer individuellement les vnements ou ruser comme un
sioux.
Une mme mthode peut grer plusieurs vnements si son prototype le permet.
Le comportement de C++ Builder vis vis des exceptions peut paratre parfois
droutant. En effet, la mise en place dun gestionnaire dexceptions, par exemple, pour
lexception EConvertError se traduit dabord par laffichage dun message du genre :
Le plus important est de savoir que ce comportement nexiste que dans lEDI.
En effet, en excution indpendante, ce message napparatrait que si lexception
dclenche ntait pas traite ; si vous fournissez un handler dexception, celui-ci
serait activ normalement.
Dans de nombreux cas, ce fonctionnement de lEDI est plus une gne quun
atout. Il est toutefois possible de le dsactiver grce la bote de dialogue prsente
sur la page suivante directement issue du menu Outils Options denvironnement,
onglet Dbogueur.
Ainsi, toutes les catgories marques dun petit rond (de couleur rouge !) voir
la figure prcdente sont gres, dabord par lEDI et dans un second temps par le
programmeur. Il est trs facile de modifier ce comportement en slectionnant le
bouton radio Programme utilisateur.
La fentre dhistorique des vnements est lun des mcanismes de traage des
programmes les plus mconnus de Windows. C++ Builder nous permet de consulter
ltat de cette fentre en lactivant dans le menu Voir.
La taille de lhistorique
Illimit
) Le rcepteur du message
) Les paramtres (WPARAM et LPARAM)
Attention, si ce comportement peut se rvler trs pratique, il peut crer des
traces normes. En effet, on imagine rarement le volume considrable de
messages traits par les applications Windows.
La VCL (Visual Component Library) livre par Inprise avec C++ Builder ou
Delphi est un ensemble de classes orientes vers le dveloppement rapide
dapplication. Toutes les classes prsentes partagent un anctre commun : la classe
TObject. Elles possdent galement une caractristique particulire : elles ne
peuvent pas possder dinstances statiques : seules les instances dynamiques cres
avec new sont acceptes. Ceci est ncessaire pour assurer la compatibilit avec Delphi
qui ne reconnat que les instances dynamiques. Toutes les classes de la VCL sont
implmentes en Pascal Objet. En fait, la librairie dexcution de C++ Builder est celle
de Delphi, ce qui implique un certain nombre de gymnastiques pour assurer une
dition de liens correcte.
Pour finir, notons que les composants que vous crez avec Delphi ou
C++ Builder sont compatibles avec les deux environnements : autrement dit, il est tout
fait possible dutiliser dans C++ Builder un composant cr avec Delphi et
rciproquement.
1En effet, la classe TComponent, linstar de toutes les autres classes de la VCL est
implmente en langage Pascal Objet, lequel saccommode assez mal de la notion de classe virtuelle
pure.
Par exemple, les boutons (TButton), les tiquettes (TLabel) ou les images sont
des contrles. En revanche, les menus (TMenu) ou les botes de dialogue communes
(TCommonDialog) de Windows qui sont reprsentes par une icne sur les fiches ne
sont pas des contrles.
Comme leur nom lindique, les contrles fentrs sont bass sur une fentre
Windows. Ceci leur confre plusieurs caractristiques :
Ils peuvent contenir dautres contrles. Par exemple, les botes de groupe
(TGroupBox) sont des contrles fentrs.
En outre, ltat visuel (ou apparence graphique) dun contrle graphique nest
pas gre par le systme :
Il sera plus rapide de dessiner dans un contrle graphique que dans un contrle
fentr car dans ce cas, seul laffichage est concern. Il ny a pas de sauvegarde de
ltat dans la mmoire du systme.
Lorsquun contrle graphique est masqu puis raffich, le systme lui envoie
un vnement WM_PAINT lui indiquant quil doit mettre jour son apparence visuelle.
Le programmeur doit donc intercepter cet vnement (OnPaint) pour redessiner la
zone client de son composant. Pour cela, il dispose de la proprit Canvas qui fournit
une plate-forme de dessin des plus agrables utiliser. Il faut galement savoir que le
gestionnaire dvnement OnPaint est appel par la mthode virtuelle Paint
directement dclenche par lvnement Windows WM_PAINT. De fait, la cration dun
nouveau contrle graphique passe le plus souvent par la redfinition de cette mthode.
La plupart des composants purement orients vers laffichage sont des contrles
graphiques. Citons par exemple TLabel (affichage pur et simple dun texte), TImage
(affichage dun graphique) ou TBevel (affichage dune ligne, dune forme en creux ou
en relief).
Les botes de dialogue standard de Windows sont des objets partags par toutes
les applications et permettant deffectuer des oprations de routine telles que la
slection dun nom de fichier, la configuration de limprimante ou le choix dune
couleur. C++ Builder encapsule la plupart dentre elles dans des classes non visuelles
dont les composants sont regroups au sein de la palette Dialogues. Les classes
associes drivent de TCommonDialog, classe servant tablir le lien entre les classes
de C++ Builder et les ressources Windows incluses dans la DLL COMMONDLG.DLL.
Ces composant ne sont pas des contrles : ils napparaissent pas sous leur forme
dfinitive lorsquils sont insrs sur une fiche mais plutt au travers dune icne. Cette
dernire napparat pas lors de lexcution, au contraire de la bote qui elle sera
invoque laide de sa mthode Execute. Licne pose sur la fiche ne sert qu
rserver une ressource Windows et permet de modifier les proprits associes la
bote. La figure suivante illustre la palette dialogues.
Ces botes de dialogue sont toujours excutes en mode modal laide de leur
mthode Execute. Cela signifie quelles monopolisent la souris et le clavier tant que
lutilisateur ne les a pas fermes. Le rsultat de Execute indique linvocateur
laide de quel bouton lutilisateur ferm la bote. Les constantes (aux noms trs
explicites) sont les suivantes :
Insistons sur le fait que lutilisation de ces classes dpend fortement de la DLL
standard de Windows COMMDLG.DLL, leur aspect et leur comportement peuvent donc
varier lgrement dun systme un autre.
Filtre
Rpertoire d'ouverture
initial
l'ouverture
Titre de la bote
de dialogue
Bien que lon puisse trs bien la saisir ainsi, il vaut mieux se reposer sur la
bote spciale qui apparat lorsque lon clique sur
Nom et
Extensions
description
associes
du filtre
Couleur initiale
puis slection de Icne de la
l'utilisateur bote sur
une fiche
Dfinitions des
couleurs
utilisateur
Une fois nest pas coutume, intressons nous aux options internes de la bote :
Cette bote, trs simple, permet de slectionner une police parmi celles
installes dans Windows. Toutes les informations slectionnes sont regroupes dans
la proprit Font qui elle mme peut se dplier pour donner des informations aussi
diverses que : le nom de la police, le jeu de caractres employ, le crnage, le style, la
couleur ou, tout simplement, la hauteur des caractres.
Enrichissements de style
Les options de la bote elle mme permettent de limiter lutilisateur dans ces
choix (par exemple, ne lautoriser qu choisir des fontes non proportionnelles) ou de
contrler laspect visuel de la bote.
Ce sont les botes les plus compliques utiliser. Tout dabord, ce sont les seules
pour lesquelles le comportement nest pas modal et binaire :
Par dfaut, les botes saffichent avec ltendue totale de leurs possibilits.
Toutefois, lutilisateur peut les limiter en activant des options dont le nom comprend
Hide ou Disable, par exemple frDisableMatchCase dsactive la case permettant
relative la casse des mots recherchs.
Comme la recherche elle mme, la prise en compte des options de recherche est
entirement la charge du programmeur. On ne rptera jamais assez que ces botes
ne sont que des outils de saisie des options !
Nous vous proposons de tester lutilisation des diffrentes botes de dialogue sur
le texte contenu dans un composant TRichEdit. Ce composant est trs proche de
TMemo dans le sens o il reprend la plupart de ses fonctionnalits en ajoutant celle de
lire un fichier .rtf et de le formater correctement. Malheureusement, il ne propose
pas ni proprit ni mthode permettant daccder la mise en forme de chaque
caractre. En revanche, il est possible de formater globalement le texte.
Quitter lapplication !
Rien dans cet exercice nest compliqu ! il y a juste beaucoup de code crire
Solution partielle
Composant TRichEdit
sur lequel appliquer les
modifications
Il est important de noter que la saisie dun nouvel lment nentrane pas pour
autant son inclusion dans la liste des possibilits. Cette dernire est laisse la
A la conception, il est possible de fixer le texte initial dune bote combo grce
sa proprit Text mais pas en spcifiant un numro dindex dans la liste. Ceci est
seulement ralisable par programmation, par exemple dans lvnement OnCreate de
la liste.
On dsire raliser une bote combo qui naccepte dinclure dans sa liste que des
nombres compris entre 0 et une limite indique dans une zone ddition. Raliser cette
interface sachant que la validation de la valeur se fait par lappui sur un bouton.
Solution partielle :
Programme 3.1 Ajout dune ligne saisie dans une bote combo
Commentaires :
Solution partielle
Pour rsoudre cet exercice il convient de se rendre compte que la bote combo
doit contenir autant dlments que lon doit en tracer. Cela peut paratre une
vidence mais il faut tout de mme y penser. Aussi, lors de la phase de conception de
linterface, vous noublierez pas de poser 6 lments dans la proprit Items de votre
bote combo (par exemple, les nombres de 0 5).
Commentaires :
Hors, en bon programmeur objet, vous savez trs bien quil est trs
dangereux deffectuer des conversions de promotion (aussi appeles
downcast). Utiliser loprateur C++ dynamic_cast permet de scuriser
lopration.
int Index : numro de llment dessiner. Dans notre cas, nous nous
dpchons de le convertir en TPenStyle (lutilisation de static_cast vous
montre un second oprateur de conversion du C++) afin de lutiliser pour
positionner loption Style de loutil Pen du canevas de la bote combo.
Le dernier paramtre indique si lon est vraiment sur quil faille redessiner.
Et contrairement au proverbe, dans le doute : redessine !
Vous noterez que lon a pris soin deffacer la zone de travail en la recouvrant
dun rectangle blanc (grce la mthode FillRect). Ceci permet de sassurer que lon
dmarre bien sur une surface vierge. En effet, lorsque vous faites dfiler la liste, les
diffrents lments doivent safficher au mme endroit ce qui occasionnerait des
collisions nfastes
Solution complte :
Solution partielle :
Notez au passage que lon utilise le fait que la coordonne verticale dun trait
est celle de son axe central.
Commentaire
Ici, le seul paramtre exotique est Height qui permet de renvoyer la hauteur
de llment dessiner.
Le trac du trait lui mme diffre peu de celui de lexercice prcdent et est
illustr par le code suivant.
Programme 3.4 trac dun trait dpaisseur variable dans une bote combo
Solution complte :
3.5.4 Exercice n4 ( )
Etendre la liste de lexercice n1 de manire ce que les 4 derniers lments
entrs soient prcds dun point noir.
Tout commence par linsertion dun composant non visuel TMainMenu sur la
fiche correspondant la fentre principale de votre application. Ensuite, il suffit de
double cliquer sur licne de celui-ci ou dactiver Concepteur de menus dans son
menu contextuel pour entrer dans lditeur de menu (commun au menu principal et
aux menus surgissants).
Raccourci clavier
associ au menu
Emplacement du prochain
lment vertical
Comme pour les boutons ou les labels de tout poil, il est possible dutiliser le
caractre & pour signaler la lettre active dun lment de menu. Si llment
en question fait partie de la barre horizontale du menu principal, la
combinaison Alt-lettre-active permettra daccder directement au
menu.
Lorsque lon dsire ajouter un sparateur dans un menu vertical ,il suffit
de taper le caractre tiret dans son Caption.
C++ Builder propose dutiliser des modles de menus dj prts. Vous pouvez y
accder par le menu contextuel attach au bouton droit de la souris dans le concepteur
de menus. La figure suivante illustre cette possibilit :
Les lments de menu nont quun seul vnement : OnClick auquel lon affecte
une mthode rpondant lvnement activation du menu . Il est ncessaire
daffecter la proprit Checked dun lment radio dans le gestionnaire si vous voulez
dplacer la marque radio dudit lment.
Nous allons profiter de cette aubaine pour construire une liste des 4 derniers
fichiers ouverts ayant les proprits suivantes :
Lorsque la liste nest pas vide, elle apparat en bas du menu fichier, juste
avant llment Quitter, divise du reste des lments par des sparateurs
Llment le plus ancien est remplac par le nouveau lorsque la liste est
pleine
Quatre emplacements
vides et un sparateur
sont rservs
Figure 3.14 Rservation des emplacements de menu pour la liste des derniers
fichiers ouverts
// Variables affectes individuellement aux lments de menu
// destins la liste des derniers fichiers ouverts
TMenuItem *MenuFich1;
TMenuItem *MenuFich2;
TMenuItem *MenuFich3;
TMenuItem *MenuFich4;
private: // Dclarations de l'utilisateur
// Dclaration d'une constante indiquant le nombre d'lments de la
liste
enum {NB_FICHIERS=4};
// Tableau permettant de manipuler facilement les lments de menu
// destins la liste des derniers fichiers ouverts
TMenuItem *MenuFichiers[NB_FICHIERS];
// Variable comptant le nombre d'lments prsents
int nbFichiers;
Les menus surgissants (popup menus) sont en tout point semblables (du moins
pour ce qui est de leur conception) au menu principal dapplication. La seule
diffrence rside dans leur activation qui est contrle par deux proprits.
PopupMenu est une proprit dfinie par tous les contrles et qui indique
lidentificateur du menu surgissant actif dans ce contrle. Ainsi, il est
possible de spcifier un menu surgissant par contrle. Si cette proprit
nest pas renseigne, alors le menu surgissant est celui du parent.
3.7.1 Gnralits
Partie visible
Etendue
Virtuelle
HorzScrollBar->Range
Supposons par exemple, que vous criviez une application dont certaines
options boolennes sont passes dans un fichier. Vous souhaitez associer une case
cocher chacune de ces options. Comme vous ne connaissez pas leur nombre
lavance, vous tes obligs de les construire la main lors de lexcution de votre
programme.
Afin de ne pas surdimensionner votre fentre, il est possible de les placer dans
une TScrollBox. Si vous activez la proprit AutoScroll, lespace virtuel sera
tendu automatiquement lorsque vous ajouterez des contrles dans votre bote
droulante. De toute faon, il vous est toujours possible de modifier les Range votre
guise.
( )
Lexemple que nous allons traiter utilise un TImage plac dans une
TScrollBox pour afficher un dessin de taille variable en fonction dun certain facteur
de zoom. Afin de ne pas compliquer inutilement lexercice, nous afficherons une suite
de 25 cercles concentriques.
Composant
Composant TMemo de trace
TScrollBox
Composant TTrackBar
responsable des changements
de facteur de zoom
Afficher le dessin
3.8.1 Gnralits
3.8.2 Exercice ( )
Enonc :
Solution partielle :
Un composant TImage que lon aura pris soin de poser sur un TPanel
TScrollBar
TImage
TScrollBar
Cette solution est un peu plus complique mettre en uvre mais beaucoup
plus souple au sens o elle autorise des documents dune taille de visualisation
virtuellement illimite.
La cration dune telle barre doutils se fait en utilisant la classe TToolBar. Par
dfaut, un objet de classe TToolBar se place en haut de sa fentre parent. Cest un
objet conteneur destin recevoir divers objets fils parmi lesquels on recense :
Des sparateurs
Ces deux dernires classes tant plus spcifiquement lies aux barres de
contrles ou autres palettes flottantes.
En revanche, si les contrles existent dj, il faut les dplacer par des
oprations Couper / Coller, le collage devant seffectuer barre doutils slectionne.
Ils sont crs en utilisant la commande New Button du menu rapide des objets
de classe TToolBar. A linstar des turbo boutons (qui taient prsents dans Delphi 2
pour les muler) ils peuvent tre de type commande ou settings et adopter un
comportement radio dans un groupe. Ici un groupe est un ensemble contigu de
boutons gadgets entour de sparateurs.
Les diffrents bitmaps associs aux boutons prsents dans une barre doutils
sont tous regroups au sein dune proprit de la barre doutils : ImageList. Chaque
bitmap est ensuite adress dans cette proprit via son index.
Voici donc la marche suivre pour crer une barre doutils avec des boutons
gadgets :
1. Crer tous les bitmaps en les enregistrant dans des fichiers .bmp. Vous
disposez pour cela, soit de lditeur intgr, soit de tout utilitaire capable de
gnrer des .bmp.
2. Rassembler tous les bitmaps dans un objet TImageList (on peut alors
dtruire les .bmp ...)
3. Crer lobjet TToolBar et lui associer la TImageList
4. Crer les boutons gadgets, leur adjoindre un style et leur associer leur
bitmap
Nous allons raliser un exercice sur une base de donnes traitant douvrages de
science fiction.
La premire tape consiste crer une base de donnes par lintermdiaire dun
alias de base de donnes.
Un lien SQL vers un serveur Oracle, Sybase, DB2, SQL Server etc. (option).
Dans le cas qui nous intresse, nous crons un alias pour lensemble de fichiers
au format Paradox situs dans le rpertoire c:\f2\Builder\donnees, alias que
nous nommerons TPF2ZZ2.
Ladministrateur BDE est un outil la fois trs simple et trs complet. Il est
capable dafficher soit lensemble des alias dj prsents (slectionnez longlet Bases
de donnes) soit des informations concernant le systme telles que lensemble des
formats de bases de donnes disponibles ou le format des nombres (slectionnez
longlet Configuration .
Onglets de
slection du
mode
Liste des alias
ou Configuration
Information sur
le systme (par
exemple nb de
bases ouvrables
simultanment)
Contrairement ce que lon pourrait penser, les performances dun pilote natif
sont toujours suprieures celles dun pont ODBC. En effet, certains ponts ODBC
sont dexcellentes factures alors que lon trouve des pilotes excrables. Aussi, il est
prfrable deffectuer quelques tests.
Bien que rudimentaire, cet outil permet de crer simplement des tables et de
leur associer des clefs primaires ou secondaires, des fichiers dindex secondaires ou des
contraintes dintgrit.
La premire chose faire est, bien entendu, de crer un projet C++ Builder.
Ensuite, il faut savoir que C++ Builder effectue une sgrgation forte entre les
variables qui reprsentent les donnes en tant que document et les lments visuels
(ou dinterface) qui permettent lutilisateur de les manipuler. Cest encore un bel
exemple dapplication du modle Document / Visualisation.
Il est prfrable de toujours regrouper les lments daccs aux donnes qui
sont des composants non visuels dans une unit spcialise connue sous le nom de
Module de Donnes. Celui-ci est cr par la commande Fichier
nouveau module de
donnes et se manipule ensuite comme une fiche / unit standard.
Alias de base de
donnes, une Composant TTable pos sur
liste droulante le module de donnes
donne accs
tous les alias
disponibles
Des requtes SQL (TQuery). Les requtes et les tables ont un anctre
commun nomm TDataSet dans le sens ou ces deux composant ont pour
rsultat des ensembles de donnes que lon pourra afficher. Les requte SQL
de C++ Builder sont paramtres et il est possible de rcuprer la valeur de
ces paramtres directement dans certains composants ou par jointure sur
une table ou le rsultat dune autre requte.
Bien que ce ne soit pas requis, il est prfrable de placer les TDataSource (ou
sources de donnes) dans le module de donnes. Personnellement, je recommande de
les placer la droite du composant TDataSet sur lequel ils travaillent.
La proprit
DataSet indique
l'ensemble de
donnes raccord
la source
Ce sont des versions spcialises dans ldition des bases de donnes des
contrles standard de Windows ou dOWL. On retrouve ainsi, par exemple, des botes
ddition, des listes ou des boutons radio orients bases de donnes. Le contrle le plus
important est nanmoins celui qui permet de prsenter une relation ou le rsultat
dune requte sous forme tabulaire : TDBGrid. Tous ces composants se trouvent dans
la palette Contrle BD .
Les contrles orients bases de donnes se placent sur les fiches et non pas sur
le module de donnes : ils constituent la partie interface du modle
Document / Visualisation de C++ Builder.
Tous sont relis aux composants non visuels via les sources de donnes. Afin
daccder ces dernires, il ne faut pas oublier dinclure lentte du module de bases
de donnes dans la ficher de prsentation (Fichier
Inclure lentte dunit).
Nous donnons ici lexemple de prsentation dune table mais ce qui suit
sapplique tout composant de type TDataSet, une requte par exemple. Le
composant TDBGrid prsente les donnes sous leur forme la plus naturelle celle dun
tableau o chaque colonne correspond un champ et chaque ligne un tuple.
Titre de colonne
Source de donnes
faisant le lien avec une
table ou une requte
Le meilleur moyen de crer des colonnes statiques consiste double cliquer sur
la grille pour faire apparatre la liste des colonnes statiques (initialement vide).
Ensuite, on gagnera activer Tous les champs pour ajouter la listes des colonnes
statiques lensemble de champs actuellement prsents dans la Table. Les diffrents
boutons
Champ de donnes
affich dans la colonne
A choisir parmir les
champs actuellement
disponibles
Proprits du titre
Diverses oprations ralisables sur la liste des
colonnes statiques.
En particulier, "Tous les champs" tablit la liste
des colonnes dynamiques en colonnes
statiques
La proprit Title est trs complexe et comprend tout ce qui est ncessaire la
manipulation dun titre, y compris une proprit Font permettant de spcifier un style
de caractres diffrent de celui de la colonne. En particulier, il est possible daligner
diffremment les donnes de la colonne et leur titre ou de choisir une fonte diffrente.
A lusage, ils savrent relativement dangereux car ils effectuent des oprations
dinsertion ou de prise en compte automatique des modifications particulirement
nocives la sant. Aussi, je ne prconise lutilisation que de deux composants de saisie
orients donnes : TDBLookupComboBox (que nous tudierons un peu plus loin) et
TDBNavigator.
Prendre en
compte les
Dernier tuple modifications
Dans notre exemple, nous aimerions voir apparatre les noms de lauteur et de
lditeur en lieu et place de leurs numros de rfrence dans la reprsentation
tabulaire de la relation uvres. Pour cela, nous allons ajouter des champs dits de
rfrence dans la relation. Ceux-ci ne sont pas autre chose que des jonctions limites.
Laccs aux champs dun ensemble de donnes est faussement similaire celui
des colonnes dun TDBGrid, aussi un avertissement solennel simpose. Il faut tout de
suite que vous fassiez la diffrence entre les champs prsents dans un TDataSet et la
liste des colonnes de prsentation prsentes dans un TDBGrid. Le premier reprsente
la liste des champs prsents dans lensemble de donnes, que soit des champs
endognes (prsents dans le fichier pour une table ou dans la dfinition pour une
requte) ou des champs exognes ajouts par jonction ou calcul. Le second ne dfinit
que des options daffichage de donnes. Le problme vient du fait que le vocabulaire
est trs similaire.
Une fois de plus, il nous faut distinguer entre champs dynamiques et statiques.
Afin daccder la liste des champs statiques prsents dans un ensemble de donnes,
il est ncessaire de double cliquer sur son icne ce qui finit daccentuer la confusion
possible avec la liste des colonnes dun TDBGrid.
Les champs de donnes sont les champs endognes de la table, cette option
ne prsente que peu dintrt car vous pouvez faire la mme chose avec le
menu Ajouter champs
Nom du champ
nouvellement cr
Slection du type
de donnes du
champ cr
Le nom du champ que vous dsirez ajouter. C++ Builder gre pour vous le
nom du composant TField gnr pour reprsenter votre nouveau champ.
Exercice (vident):
4.4.2 Le filtrage
Le filtrage est une opration qui permet de restreindre les tuples dune table
ceux qui respectent une certaine condition nomme Filtre. Pour activer un filtre, il
faut spcifier dans la proprit Filter une chane de caractres spcifiant les critres
de filtrage et positionner la proprit Filtered true. Ces proprits tant
modifiables tout instant, cette opration pourra seffectuer trs facilement et sous le
contrle dlments dinterface.
Seuls les champs endognes dun ensemble de donnes peuvent tre filtrs.
Supposez dsormais que vous souhaitiez accder aux donnes dun ensemble en
fonction du tuple slectionn dans une grille. Le meilleur exemple est sans doute celui
des nomenclatures o vous disposez des trois tables.
Vous pouvez alors dcider dafficher dans un premier TDBGrid lensemble des
produits complexes, puis, dans un second, la liste des pices le composant. Il sagit
La proprit
MasterSource
pointe sur une
DataSource
associe la
table Matre
Pour ajouter un tuple dans une table, il suffit de passer la table dans le mode
insertion, ce qui a pour effet de crer un nouveau tuple vierge. Dans un deuxime
temps, on modifie les valeurs des champs par une instruction du style :
Replaons nous dans le cas o chaque uvre peut navoir quun seul auteur,
nous allons effectuer lopration de saisie :
Sinon, un nouvel auteur est rajout dans auteur avant que son
numro ne soit ajout uvre
Il est interdit de rajouter un nouvel diteur : celui-ci devra tre choisi parmi
ceux dj prsents dans la base editeur . Nous utiliserons pour cela une
TDBLookupComboBox.
La partie de gauche est ddie au titre de luvre, elle est compose dun
TDBEdit permettant de saisir le titre, dun bouton nomm ajouter validant cette
action et dun bouton nomm annuler .
Une fois le titre valid, il sera possible de rajouter autant dauteurs que
ncessaire en les slectionnant un par un dans une liste (TDBLookupListBox) et en
appuyant sur un bouton nomm ajouter . Il ne sera pas possible dannuler avant
davoir ajout au moins un auteur.
Le composant TDBEdit est fort simple, il suffit de le connecter sur le bon champ
via une source de donnes (en loccurrence, la source de donnes est DSOeuvres et le
Exercice : ( )
Rajouter la possibilit davoir plusieurs auteurs.
Cet utilitaire permet, dditer les donnes prsentes dans des tables dj
existantes laide dune interface minimaliste. Ce nest toutefois pas l quil exprime
tout son potentiel.
En effet, il permet de crer des tables avec leurs index ventuels et mme, dans
certains cas, de gnrer des contraintes dintgrit rfrentielle. Ceci permet de
retrouver dans C++ Builder certaines des fonctionnalits qui lui manquaient par
rapport Access. Il faut toutefois insister sur le fait que le Module de Bases de
Donnes nest quun utilitaire qui ne saurait en aucun cas se comparer un systme
complet de gestion de bases de donnes tel quAccess.
Nous tudierons par la suite deux des fonctionnalits les plus utiles du MDD :
la cration de tables et la cration de requtes SQL.
Une fois le type de table slectionn, le MDD vous affiche sa fentre principale
telle quelle est prsente par la figure suivante :
Cette fentre se divise en deux grandes parties. A gauche, vous avez la liste des
champs de la table, dans leur ordre de stockage, accompagns de leur type, de la taille
si elle sapplique ainsi que dune colonne nomme Index et occupe par une toile si le
champ fait partie de la clef primaire.
Index secondaires : permet dajouter des index secondaires sur la table. Cette
fonctionnalit sera traite plus en dtail dans une section ultrieure.
5.3.1 Le nom
5.3.2 Le type
La figure suivante montre les diffrents types de donnes disponibles pour les
tables de type Paradox 7. Cette liste sobtient en tapant espace dans la case
rserve au type des donnes.
5.3.3 La taille
Si vous souhaitez quun champ soit prsent dans la clef primaire, il faut saisir
une toile dans la dernire colonne de la fentre comme prsent par la figure
suivante. Attention aux bugs du MDD, nessayez surtout pas de saisir un autre
-
caractre, cela peut faire planter sauvagement Windows (GPF ). Bien entendu, il est
possible de faire figurer plusieurs champs dans la clef primaire.
Boutons permettant de
modifier lordre des
Boutons dajout ou de champs dans lindex
suppression de champs
dans lindex
Les champs apparaissant en gris dans la liste de gauche sont dj inclus dans
lindex et ne peuvent donc plus y tre ajouts.
Lorsque lon spcifie plusieurs champs dans un index, celui-ci est multicritres
hirarchique. Les tuples sont ordonns dabord en fonction du premier champ, puis,
pour chaque valeur du premier champ, en fonction du second, puis pour chaque valeur
identique du couple (premier champ, second champ) en fonction du troisime et ainsi
de suite.
Unique : spcifie que cest un index sans collision : pour une mme valeur
dindex, il ne peut y avoir quun seul tuple
Maintenu : indique que lindex est mis jour chaque opration sur la table.
Ceci peut savrer coteux si de nombreuses oprations sont effectues mais
garantit les meilleurs temps daccs aux donnes.
Dcroissant : par dfaut, les tuples sont rangs par ordre croissant sur lindex,
moins que cette option ne soit coche !
Composant
slectionn
Liste de classes
associes au composant
slectionn
Rpertoire de cration
Palette dinstallation du des units associes aux
composant contrles ActiveX
Chemin de recherche
des units associes aux
contrles ActiveX dj
rfrencs
La premire partie de la fentre est occupe par la liste des composants ActiveX
installs sur votre ordinateur. Lorsque vous slectionnez un composant, deux cas
peuvent se produire :
Nanmoins, il se peut que votre composant soit dj prt lemploi mais que
C++ Builder nait pas t en mesure de trouver vos units si le chemin de
recherche (spcifi par la bote de saisie en bas de la fentre de dialogue) est
erron. Il est donc ncessaire de vrifier ce dernier si vous pensez quun
autre utilisateur de votre systme a dj effectu le travail de cration dune
unit.
Si le composant que vous dsirez utiliser napparat pas dans la liste, cela
signifie tout simplement quil nest pas rfrenc dans la base de registre ; opration
que nous allons maintenant expliciter.
Vous noterez que le nouveau composant est dornavant prsent dans la liste. Le
nom est celui denregistrement dans le fichier .ocx accompagn du numro de version
C++ Builder propose toujours un nom de classe finissant par Proxy. En effet,
en terminologie OLE, on appelle classe Proxy, toute classe reprsentant un objet
Automate OLE ou ActiveX et masquant lutilisation des diverses interfaces. Utiliser le
nom par dfaut prsentes les avantages de la clart et de lauto-documentation ;
toutefois, rien ne vous empche de le changer.
La prochaine tape consiste ajouter votre systme une unit (i.e. une
combinaison dun fichier .h et du fichier .cpp associ) qui permettront dutiliser
facilement votre composant dans une application.
La localisation des fichiers units est dfinie par la bote de saisie intitule
Nom du rpertoire unit . Celle-ci pointe naturellement sur le rpertoire o C++
Builder stocke ces fichiers de librairie. Personnellement, je recommande de crer un
autre rpertoire (par exemple, c:\activex\imports) o vous logerez toutes vos
nouvelles units ActiveX. Afin que C++ Builder sy retrouve, noubliez pas dajouter ce
rpertoire au chemin de recherche des units situ dans la bote de saisie du dessous.
La notion de paquet est quelque peu complique pour tre explique ici. Pour
lheure il vous suffit de valider systmatiquement toutes les options qui vous sont
prsentes.
En outre, vous pourrez noter la prsence dune nouvelle icne dans la palette de
composants que vous avez choisie pour recenser votre composant.
Notez la prsence de votre composant dans la palette !
Une fois lopration prliminaire ralise, vous tes pour ainsi dire sortie
daffaire. En effet, le contrle ActiveX sutilise comme nimporte quel composant de la
VCL. Il est muni dune reprsentation visuelle, et ces proprits saffichent tout fait
normalement dans linspecteur dobjet.
Dans la plupart des cas, vous pourrez lui associer des vnements utilisateurs.
Les figures suivantes montrent respectivement laspect du composant Calendrier pos
sur une fiche et les vnements qui lui sont associs. Les proprits les plus
intressantes ont pour nom Day, Month, Year et Value. Je vous laisse les examiner
vous mme.
Date courante
Evnements respectivement
appels aprs et avant le
redessin du composant lorsque
lon clique sur un bouton de
jour
7.1 Gnralits
Pour finir, notons que les composants de Delphi et de C++ Builder sont
compatibles : autrement dit, il est tout fait possible dutiliser dans C++ Builder un
composant cr avec Delphi et rciproquement.
2) Implmentation de la classe
2En effet, la classe TComponent, linstar de toutes les autres classes de la VCL est
implmente en langage Pascal Objet, lequel saccommode assez mal de la notion de classe virtuelle
pure.
3) Test de la classe
Palette dinstallation
Chemin utilis par
C++ Builder lors de la
Emplacement et nom des recherche du source
fichiers .h et .cpp gnrs des composants
Nom de classe : saisissez le nom que vous souhaitez donner votre classe de
composant.
Page de palette : nom de la palette dans laquelle vous souhaitez inclure votre
composant. Il est possible de crer de nouvelles palettes avec dautres
fonctionnalits de C++ Builder. Pour des raisons videntes (embrouille des
utilisateurs, manque de cohrence des composants prsents, etc.) je
dconseille de rajouter un composant personnalis dans une palette
standard de C++ Builder
Son rle est de spcifier le paquet dans lequel sera install le composant.
Brivement, il suffit de savoir que les paquets correspondent des DLL dans lesquels
sont rassembls les composants. Par dfaut, tout nouveau composant est rajout dans
un paquet nomm DCLUSR3, cest dire paquet utilisateur gnr par la version 3
de C++ Builder (ou, en Anglais Delphi Cluster User Version 3), lequel est situ dans
les rpertoires de larborescence de C++ Builder. Il vaut mieux utiliser un paquet situ
dans un rpertoire propre lutilisateur afin dviter toute dsinstallation
intempestive. De mme, si vous dsirez exporter votre composant, il sera
probablement ncessaire de crer un nouveau paquet (vous disposez pour cela dun
onglet spcialis) recueillant uniquement les composants destins votre client.
Nous verrons dans une prochaine phase que les paquets se manipulent trs
facilement la manire des projets. En outre, si vous tes dans le projet
Comportement spcialis
oui non
d'un composant existant ?
Driver du
composant
spcialiser ou de
sa forme abstraite
oui Composant visuel ?
non
Driver de Driver de
TWinControl TGraphicControl
Rsolvons en premier lieu le cas des composants non visuels, cest dire ceux
dont le placement sur une fiche nentrane que laffichage dune icne. Ils peuvent
avoir plusieurs rles. Citons notamment :
Reposez vous alors la question, suis-je bien certain que mon composant na
aucun lien avec lun de ceux existants ? si la rponse est oui , alors il vous faut
driver directement de TComponent, dans tous les autres cas essayez de trouver dans
larborescence de la VCL un anctre convenable qui permette de vous simplifier la
tche.
Rappelons galement que si votre composant non visuel est destin tre
dpos sur une fiche, il faudra fournir une icne de reprsentation.
Les composants visuels sont ceux dont la reprsentation sur une fiche reflte
exactement laspect lexcution. Bien quils drivent toujours de TControl, on peut
les discriminer en deux grandes catgories laide dun critre simple : le composant
doit il tre capable de recevoir la focalisation Windows ?
Si, oui, cest un composant actif et le plus simple consiste les driver de
TCustomControl et, travers ce dernier de TWinControl.
int indiceSelected=0;
for (int compteur=lbc->SelCount-1;compteur>=0;compteur--)
{
while (!lbc->Selected[indiceSelected])
indiceSelected++;
meStd->Lines->Add(IntToStr(indiceSelected)+" "+
Le rsultat visuel est illustr par la figure suivante o vous pourrez vrifier que
cela fonctionne !
Figure 7.4 Affichage des index et des lments slectionns dune bote de
liste par le Programme 7.8
Le but est dajouter une proprit nomme Indices qui permette daccder
directement aux indices des lments slectionns comme dans lexemple de code
suivant :
meCool->Lines->Clear();
for (int compteur=0;compteur < lbc->SelCount;compteur++)
{
meCool->Lines->Add(IntToStr(lbc->Indices[compteur])+" "+
lbc->Items->Strings[lbc->Indices[compteur]]);
}
Programme 7.2 Vers une utilisation plus simple des botes de listes
3. Utilisez le bouton ajouter pour ajouter votre paquet la liste des paquets
actifs.
Afin de nous simplifier la vie, cette proprit sera du type sans attribut de
stockage . Lorsque nous tenterons daccder la proprit Indices, nous relirons la
proprit Selected, automatiquement mise jour par les messages Windows. En
outre, nous ne donnerons accs cette proprit qu lexcution (elle est donc en accs
public) et en lecture seulement. Le code de dclaration de la classe TListBoxCool est
le suivant :
//---------------------------------------------------------------------------
#ifndef ListBoxCoolH
#define ListBoxCoolH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <StdCtrls.hpp>
//---------------------------------------------------------------------------
class PACKAGE TListBoxCool : public TListBox
{
private:
protected:
public:
__fastcall TListBoxCool(TComponent* Owner);
__published:
};
//---------------------------------------------------------------------------
#endif
Ce comportement est bien accord lesprit des proprits qui peuvent tre
modifies tout instant par un message Windows.
// Utilisation de Selected
int indiceSelected=0;
for (int compteur=lbc->SelCount-1;compteur>=0;compteur--)
{
while (!lbc->Selected[indiceSelected])
indiceSelected++;
meStd->Lines->Add(IntToStr(indiceSelected)+" "+
lbc->Items->Strings[indiceSelected]);
indiceSelected++;
}
// Utilisation de Indices
meCool->Lines->Clear();
for (int compteur=0;compteur < lbc->SelCount;compteur++)
{
meCool->Lines->Add(IntToStr(lbc->Indices[compteur])+" "+
lbc->Items->Strings[lbc->Indices[compteur]]);
}
}
Vous pouvez dornavant vrifier que votre composant est prsent sur la palette
Exemples comme le montre la figure suivante :
Comme nous navons pas fourni de nouvelle icne pour ce composant, il reprend
celle de son anctre le plus rcent : TListBox.
A partir de son installation sur la palette, vous pouvez utiliser votre composant
comme bon vous semble et comme sil sagissait dun composant natif de Delphi.
Il est possible dutiliser un composant non encore recens sur la palette. Il sagit
alors de procder comme sil sagissait dun objet tout ce quil y a de plus normal :
cration manuelle avec appel new, affectation des diverses proprits (noubliez pas
daffecter la proprit parent, sinon le composant ne saffichera pas ) et destruction
laide de delete. Toutes ces oprations vont tre vues plus en dtail dans la section
suivante ddie la cration du composant Calculette Francs Euros.
Il sagit ici de crer une calculatrice qui permette de convertir des Francs en
Euros et rciproquement. Dans ce cas l, nous nous simplifions lexistence en utilisant
le paquet des composants utilisateur : dclusr35.
Nous allons raliser un nouveau composant qui en inclut lui mme 5 autres :
Un label indiquant dans quelle bote saisir / afficher une somme en Francs
Un label indiquant dans quelle bote saisir / afficher une somme en Euros
Une fois dpos sur une fiche, le rsultat final ressemble la Figure 7.11
Les diffrents
widgets inclus
dans le composant
Les proprits sont trs importantes pour un composant car elles permettent de
spcifier des valeurs pour les attributs fondamentaux lors de la conception sur fiche.
Recensons les proprits inhrentes au fonctionnement de notre calculatrice :
Par convention, les noms des attributs de stockage des proprits commencent
tous par la lettre F suivie du nom de la proprit, nous obtenons donc :
private:
double FTaux; // Attribut de stockage du taux de change
double FFrancs; // Attribut de stockage de la somme en Francs
double FEuros; // Attribut (redondant) de stockage de la somme en Euros
Reste spcifier la politique daccs aux proprits. Dans notre cas, le plus
simple est dutiliser des mthodes dcriture sophistiques qui assurent la cohrence
des donnes entre elles ainsi que des vnements chargs de mettre jour les valeurs
des proprits lorsque du texte est saisi dans les botes ddition. Ainsi, on peut lire
directement la valeur des proprits dans lattribut de stockage.
private:
__fastcall void SetTaux (double value);
__fastcall void SetFrancs (double value);
__fastcall void SetEuros (double value);
__published:
__property double Taux = {read = FTaux,
write = SetTaux,
default = 6,
stored = true};
__property double Francs = {read = FFrancs,
write = SetFrancs,
default = 0,
stored = true};
__property double Euros = {read = FEuros,
write = SetEuros,
default =0};
Seules les valeurs des proprits Francs et Taux sont stockes sur disque
(stored = true). En effet, la valeur de Euros est immdiatement
dductible des deux autres.
Dans notre cas prcis, laspect visuel du composant est compos de trois grandes
parties :
csFramed :Le contrle a un cadre 3D, en creux par dfaut (linverse dun
TPanel standard dessin en relief)
Les classes de type Set ont t ajouts au C++ afin de simuler le type set of
du Pascal utilis pour modliser un ensemble non ordonn de valeurs numriques
distinctes. De telles constructions sont trs pratiques pour modliser les ensembles
doptions, telles que, par exemple, lensemble des boutons prsents sur une bote de
dialogue de Windows.
o :
valMin et valMax sont les valeurs extrmes autorises pour les lments de
lensemble.
La classe Set est pourvue des mthodes prsentes dans le tableau suivant.
Afin de gagner de la place, le spcificateur __fastcall3 prsent pour chacune des
mthodes nest pas prsent.
Set(void)
Constructeur par dfaut, conoit un ensemble vide
Set(const Set&)
Constructeur par copie
Set &operator=(const Set&)
Affectation brutale
Set &operator *=(const Set& )
Set &operator +=(const Set& )
Lensemble courant devient respectivement
Set &operator =(const Set& ) lintersection, la diffrence ensembliste et la
runion entre lui mme et un autre ensemble
pass en argument
bool operator==(const Set&) const
bool operator!=(const Set&) const
Comparaisons entre ensembles. Seules les
oprations tous lments identiques et son
3 Ce spcificateur traduit le mcanisme dappel rapide : les paramtres ne sont pas empils
mais placs dans des registres. Ceci permet de gagner un temps considrable lorsque de nombreux
appels sont ncessaires.
Vous noterez au passage que les gens de chez Borland nont pas du lire Coplien
car ils ont programm de nombreux oprateurs dyadiques en fonction membre ! En
outre, ils savent trs bien manipuler les fonctions externes comme le prouvent les
oprateurs dentres / sorties suivants :
Les entres / sorties sur les ensembles sont assez spciales dans le sens o elles
travaillent sur un mapping de la prsence de chaque valeur entre minVal et maxVal
vers [0, 1]. Pour clarifier, si la valeur i est prsente dans lensemble, cela sera signal
par un 1 lemplacement i-minVal dans la suite de 0 et 1 construite par
loprateur <<. Rciproquement loprateur >> construit en ensemble partir dune
suite de 0 et de 1 en ajoutant la valeur correspondant chaque fois quil trouve un 1.
Nous y apprenons donc que, par rapport au style standard, notre composant :
Rappelons que par dfaut, il accepte les vnements de la souris (y compris les
doubles clics), et du clavier.
En pratique il est agrable dutiliser le concepteur pour raliser une fiche qui a
le mme aspect que le composant que lon souhaite crer pour en dduire les valeurs
gomtriques des composants inclus.
Height=200;
Width=230;
Ajout des diffrents
labelFrancs = new TLabel(this); composants inclus
labelFrancs->Top=10;
labelFrancs->Left=10;
labelFrancs->Caption="Les Francs :";
labelFrancs->Parent=this;
boutonSaisieTaux=new TButton(this);
boutonSaisieTaux->Top=100;
boutonSaisieTaux->Left=40;
boutonSaisieTaux->Caption="Saisie";
boutonSaisieTaux->OnClick=OnClickBoutonSaisieTaux;
A ce titre elle est pourvue dun nombre impressionnant de proprits, qui, pour
la plupart sont dclares protected. Autrement dit, elle napparatraient pas dans
linspecteur dobjet des classes drives moins dtre publies par lhritier !
__published:
__property Align ;
__property Ctl3D ;
__property DragCursor ;
__property DragMode ;
__property Enabled ;
__property ParentCtl3D ;
__property ParentShowHint ;
__property PopupMenu ;
__property ShowHint ;
__property Visible ;
Maintenant que nous disposons des contrles daffichage des proprits, il nous
est possible de spcifier du code pour les mthodes daccs en criture des proprits.
En effet, ces dernires ne manqueront pas de mettre jour laffichage du composant
lorsque les sommes ou le taux change. Notons que pour viter tout conflit, lorsque le
taux change, les sommes en Francs et en Euros sont remises zro.
Euros= ;
Et, si, pour couronner lensemble, la mthode SetEuros contient une ligne
du style :
Francs= ;
3. Implmenter le gestionnaire
Par exemple, si lon dsire grer les changements de texte dun TEdit, on
recherche la rubrique vnements du TEdit et lon choisit OnChange comme le
montre le code suivant :
Nous y apprenons que les vnements sont des proprits ( accs direct de
surcrot). On sen doutait un peu car il est possible dassocier un gestionnaire un
vnement lors de la conception.
Le mot clef __closure est un modificateur interne C++ Builder qui permet
daffecter des pointeurs de mthodes une classe diffrente de celle spcifie. Cette
magouille tait ncessaire pour simplifier le mcanisme daffectation des
proprits. Il nest pas ncessaire de le comprendre pour grer les vnements . -
Il suffit de retenir que dans notre cas, la mthode doit avoir le prototype spcifi
par le type TNotifyEvent lexception du __closure, soit :
OnDblClick : gestion dun double clic. Notez bien que si vous fournissez une
gestion OnClick et OnDblClick, et quun double clic se produit, OnClick
sera appel avant OnDblClick. Moralit : laction associe un double clic
doit prolonger celle associe un clic simple !
Une fois les mthodes dclares avec le bon prototype, il ne reste plus qu
crire le code correspondant. Nous donnons ici, titre dexemple, le code associ
lvnement OnChange de la bote ddition de la somme en Francs.
La bote de dialogue est cre en tant que fiche ordinaire et prsentera laspect
illustr par la Figure 7.12. Veillez ce que le projet courant soit celui associ au
paquet lorsque vous crez la fiche !
Chaque unit dcrivant une fiche dfinit une variable externe qui est
habituellement cre au lancement de lapplication. Lorsque lon utilise une
fiche uniquement dans le cadre dun composant, cette instance nest pas
cre automatiquement. Aussi, vous devrez le faire vous mme, comme dans
le fragment de code suivant o vous noterez que nous passons au
constructeur de la fiche la variable Application comme composant pre.
Cette variable est dfinie par toute application VCL.
Bote combo de
saisie du mois Track Bar de
slection du jour
Label indiquant le nb
Bote d'dition de rcapitulation de la date
(lecture seulement) de jours du mois
courant
Comme dans le cas prcdent, les mthodes daccs en criture aux proprits
sont charges de mettre jour les proprits internes des composants inclus. Afin de
faciliter les mises jour, on utilisera une mthode nomme ReconstructionDate et
qui sera charge de mettre jour la valeur compile dans la date dans la bote
ddition idoine.
Rflchissons ensemble, quelle est la premire mthode qui sera appele aprs
le constructeur ? bien videmment, il sagit de Paint afin de mettre jour laspect
visuel du contrle !
// Proprits gomtriques
Width=675;
Height=250;
editAnnee=new TCSpinEdit(this);
editAnnee->Parent=this;
editAnnee->Left=16;
editAnnee->Top=8;
editAnnee->MinValue=1980;
editAnnee->MaxValue=2100;
editAnnee->OnChange=OnChangeAnnee;
editDate=new TEdit(this);
tbJour=new TTrackBar(this);
tbJour->Parent=this;
tbJour->Left=16;
tbJour->Top=88;
tbJour->Width=650;
tbJour->Min=1;
tbJour->Max=31;
tbJour->OnChange=OnChangeJour;
labelPremier=new TLabel(this);
labelPremier->Parent=this;
labelPremier->Left=16;
labelPremier->Top=136;
labelPremier->Caption="1";
labelDernier=new TLabel(this);
labelDernier->Parent=this;
labelDernier->Left=650;
labelDernier->Top=136;
SYSTEMTIME toutDeSuite;
GetLocalTime(&toutDeSuite);
La premire chose savoir est quun vnement est avant tout une proprit de
type closure. Comme nous lavons vu un peu plus haut, ce type est associ des
pointeurs de mthodes dans un objet fiche.
Ceux qui sont dj prvus par C++ Builder mais qui sont masqus, il suffira
de les rendre accessibles par le mcanisme de publication des proprits
protected que nous avons dj utilis afin de rendre visibles les proprits
standard des contrles.
Afin de rendre les choses simples, ces deux derniers vnements seront de type
notification : cest dire avec un seul paramtre correspondant lmetteur du
message. On se rfrera au chapitre pour de plus amples renseignements sur les
notifications.
...
TNotifyEvent FAvantChangementDate;
TNotifyEvent FApresChangementDate;
...
__published:
A titre indicatif, le code dvnements trs simple est fourni juste en dessous de
la figure, les diffrentes affichages de la date permettront de vrifier que lvnement
OnAvantChangementDate a bien lieu avant les modifications effectives des proprits
alors que OnApresChangementDate a lieu aprs.
Aucune hypothse ne doit tre faite sur le contenu du gestionnaire fourni par
votre utilisateur.
if (Propriete)
Propriete(arguments)
Dans notre cas, il suffit dappeler les gestionnaires dans chaque mthode
associe aux vnements internes de changement des composants comme le montre le
code suivant :
7.7.1 Motivation
Dans cette section, nous allons montrer comment encapsuler une bote de
dialogue dans un composant. Pour cela, nous allons nous appuyer sur lexemple dune
bote de saisie gnrique.
Titre de la bote
Sil est possible de raliser toutes ces oprations relativement facilement, vous
voyez quelles impliquent tout de mme dutiliser des proprits de composants de la
bote ce qui impose de connatre la structure du dialogue.
En crant des proprits dun composant englobant cette bote, vous nauriez
qu connatre ceux-ci. Nous allons donc crer 3 proprits de type texte pour notre
dialogue :
Vous noterez que nous avons respect les conventions habituelles de la VCL sur
les noms des proprits de texte. La figure suivante rcapitule cet tat de fait.
Caption
Label
Text
7.7.3 Ralisation
Drivez de TComponent
#include "ComposantSaisie.h"
#include "USaisieGenerale.h"
#pragma link "USaisieGenerale.obj"
Les proprits que nous utilisons sont toutes des chanes de caractres donc
du type AnsiString. En outre ce sont des proprits en accs direct ; en effet,
rappelez vous (section 7.7.2) que la bote de dialogue nest construite quau moment de
lappel de la mthode Execute, laquelle est charge de la mise en place des
proprits, aussi, dans notre cas, il nest point utile de crer des mthodes daccs
compliques. Le code obtenu est le suivant :
private:
AnsiString FTitre;
AnsiString FLabel;
AnsiString FTexte;
__published:
__property AnsiString Caption = {read=FTitre, write=FTitre, stored=true};
En outre, elle est souvent responsable des erreurs qui pourraient se produire et
gre les exceptions. Le code suivant traduit cet tat de fait :
boite->Caption=FTitre;
boite->labelEdition->Caption=FLabel;
boite->boiteEdition->Text=FTexte;
Le problme est ici totalement diffrent car lon ne construit plus un composant
capable de recevoir la focalisation. Pour parler plus technique, il ne sagit plus dun
Widget mais bel et bien dun Gadget.
Les sommets sont matrialiss par un rond bleu et les arcs (non orients) par
un trait vert.
5 Nombre d'arcs
7
1.0 2.0
2.0 4.0 Un sommet : coordonnes x et y
1.0 6.0
4.0 4.0
5.0 2.0
0 1 Un arc :index des sommets origine et destination
1 2
2 3
3 4
4 0
4 2
3 1
Le nom du fichier qui contient le graphe : cest une chane ANSI en lecture
et criture (Fichier).