Personnalisationdu DBNAVIGATOR
(Testéet mis en ½uvre sous Delphi 6 pro et windows XP sp2)
Augmentonsl'attrait du composant TDBNavigatoravecdu graphisme modifié (des glyphes), des titres personnalisésde bouton et plus. Controle de l'événementOnMouseUp/Down pour chaque bouton.
L'ancien DBNavigator
LeDBNAVIGATOR est THE composant pour les bases de données;il fournit une interface semblable au MAGNÉTOSCOPE pournaviguer dans les données et gérer des enregistrementspour des applications de base de données. Il évite delongues heures d'écriture.
LeDBNAVIGATOR fournit pour les enregistrements, les fonctions suivantes:
0 - Premier (First)
1 - Précédent (Prior)
2 - Suivant (Next)
3 - Dernier (Last)
4 - Nouveau (Insert)
5 - Supprimer (Delete)
6 - Modifier (Edit)
7 - Enregistrer (Post)
8 - Annuler (Cancel)
9 - Actualiser (Refresh)
Celareprésente un ensemble complet pour gérer facilementvos données.
Cependantle DBNavigator manque de quelquesfonctions comme des glyphes personnalisés, des titres debouton, etc... qui le rendrait encoreplus puissant et attrayant.
Beaucoupde composants Delphis ont des propriétés utiles et desméthodes qui sont marquées invisibles (protégée)par le développeur Delphi.
D'abord,nous ajouterons un titre à chaque bouton de DBNavigator,puis nous ajouterons le graphisme personnalisé et finalementen plus nous piloterons l'action de la souris et de la touche CTRLsur le navigateur.
Pourqu'il n'y est plus de DBNAVIGATOR "ennuyeux"
Graphisme standard + texte
Texte seulement
Graphisme personnalisé +texte ( modifiable à souhait ) (bitmap de 16 x16)
Graphisme personnalisé N°2(bitmap de 10 x10)
Pourne pas afficher un bouton utiliser la propriétéVisibleButtons (la vue ci-dessus ne possède pas"Actualiser")
Le DBNavigator a des propriétés protégéede Buttons. Ce membre est un tableau deTNavButton, descendant deTSpeedButton.
Puisquechaque bouton dans cette propriété protégéehérite de TSpeedButton, nousserons capables de travailler avec les propriétés du"standard " TSpeedButtoncomme :
Caption (une chaîne qui identifie le contrôlepour l'utilisateur),
Glyph (le bitmap qui apparaît surle bouton),
Layout (détermine la position de l'image etdu texte sur le bouton)...
Del'unité DBCtrls (oùDBNavigator est défini) on nous déclare lapropriété protégée de Buttons comme"Lecture" (Read)
Buttons: array[TNavigateBtn] ofTNavButton;
OùTNavButton hérite de TSpeedButtonet TNavigateBtn, et est uneénumération, définie comme :
TNavigateBtn=
(nbFirst,nbPrior, nbNext, nbLast, nbInsert,
nbDelete,nbEdit, nbPost, nbCancel, nbRefresh);
Notezque TNavigateBtn contient 10valeurs, identifiant chaque bouton différent sur un objetTDBNavigator. Maintenant, voyonscomment modifier notre TDBNavigator:
Premièrement,mettre en place un ensemble de données simple sur la Form, enplaçant au moins un DBNavigator,un DBGrid, unDataSourceet un objet d'Ensemble de données devotre choix (ADO, BDE, dbExpres...).Assurez-vous que tous les composants sont "connectés"pour le test.
Deuxièmement,modifier le DBNavigator endéfinissant une classe "factice" héritée,au-dessus de la déclaration de Form, comme :
typeTMyDBNav = class(TDBNavigator);
type
TForm1= class(TForm)
...
Ensuite,pour être capable d'afficher des titres personnalisés etle graphisme sur chaque bouton de DBNavigator,nous devrons mettre en place quelques glyphes.
Trucset Astuces :
Pouravoir des images impécables utiliser des bitmaps de 16 x 16pixels.
(vouspouvez uriliser des bitmaps de 10 x 10 pixels mais c'est l'extrêmelimite.choisir l'option Centre).
(àl'inverse, des bitmaps plus grands déformerons les images).
Pourvoir l'image en grisée (lorsque le bouton est inactif)utiliser du noir pour le contour du dessin.
Choisirde préférence une couleur transparente qui ne soit pasutiliser dans votre image.
Ilfaut savoir que seuls le pixel en bas à gauche de l'imagedetermine la couleur de transparence, l'idéal étant delaisser le pixel de contour de l'image en couleur de transparence.
Jevous suggère d'utiliser le composant TimageList
et assigner 10 images (bmp), chaqueimage représente une action d'un bouton particulier d'unDBNavigator. (utiliser l'éditeur d'images :clique droit sur TimageList)
ATTENTIONà l'ordre des boutons : 0 est le premier bouton àgauche (First) 9 est le dernier bouton à droite(Refresh).
Troisièmement,dans l'événement OnCreatepour le Form1 (feuille ou se trouve le DBNavigator),ajouter un appel comme
procedureTForm1.FormCreate(Sender: TObject);
---
SetupMyDBNav(DBNavigator1,ImageList1);
end;
ATTENTIONles noms d'objet DBNavigator1 et ImageList1 sonr les noms d'origine àla création..
Assurez-vousque vous ajoutez la déclaration de cette procédure dansla partie privée de la déclaration de Form, comme :
type
TForm1= class(TForm)
...
private
procedureSetupMyDBNav(const Navigator : TDBNavigator;
constGlyphs : TImageList);
...
Quatrièmement,ajoutez la procédure SetupMyDBNav.La procédure SetupMyDBNav ajoute legraphisme personnalisé à chaque bouton et assigne letitre personnalisé à chaque bouton.
usesButtons; // N'oubliezpas de vérifier qu'il existe bien dans la déclaration!!!
procedureTForm1.SetupMyDBNav(const Navigator : TDBNavigator; const Glyphs :TImageList);
const
//En standard :
Captions: array[TNavigateBtn] of string =
('First','Prior', 'Next', 'Last', 'Insert',
'Delete','Edit', 'Post', 'Cancel', 'Refresh');
//En français :
//Captions : array[TNavigateBtn] of string =
//('Premier', 'Précédent', 'Suivant', 'Dernier','Nouveau',
//'Supprimer', 'Modifier', 'Enregistrer', 'Annuler', 'Actualiser');
//Toutes les dérives d'imagination sont possibles
var
btn: TNavigateBtn;
begin
forbtn := Low(TNavigateBtn) to High(TNavigateBtn) do
withTMyDBNav(Navigator).Buttons[btn] do
begin
//titres des boutons, tableau Captionsdans l'ordre (si pas de titre mettre vide '' dans tableau)
Caption:= Captions[btn];
//Le numéro de l'image dans lapropriété Glyph
NumGlyphs:= 1;
//Supprime l'ancien Glyphe.
Glyph:= nil;
//Ajoute le Glyph personnalisé(si pas de Glyphes dans la barre, on saute cette ligne et lasuivante)
Glyphs.GetBitmap(Integer(btn),Glyph);
//Glyphes au-dessus du texte (le plusfréquent)
Layout:= blGlyphTop;
//Gestion de la souris et des touches(voir ci-après) (si pas utilisé on saute cette ligne)
OnMouseUp:= MyNavMouseUp;
end;
end;
Pourne pas avoir de Glyphes sur un bouton, il faut le supprimer dansl'éditeur d'images.
Rappelez-vousque la propriété protégée de chaquebouton est accessible par le tableau des "Buttons", doncutilisé par la classe TMyDBNav.Puisque le type du tableau "Buttons" est TNavigateBtnnous allons "du premier bouton " (l'utilisation dela fonction Basse) "au dernier" (l'utilisation de lafonction Haute). Pour chaque bouton nous supprimons simplement "levieux" glyphe, assignons le nouveau (et le numéro deGlyphes), ajoutons le Titre (du tableau des titres) et déterminonsla disposition du glyphe.
Notezque vous pouvez contrôler quels boutons sont affichéspar un DBNavigatorpar sa propriétéVisibleButtons. Une autre propriétédont la valeur par défaut que vous pouvez vouloir changer estcelle des "Hints". On l'utilise pour fournir les "petitesaides" de votre choix pour le bouton individuel du navigateur.Vous pouvez contrôler l'affichage des "Hints" enéditant la propriété ShowHints.
Voilà.."C'est pourquoi nous programmons en Delphi"
Encoreplus!
Pourquois'arrêter ici ? Vous savez que lorsque vous cliquez sur lebouton 'nbNext' la position actuelle del'ensemble des données est avancée a l'enregistrementsuivant. Et si vous vouliez vous déplacer, disons de 5enregistrements en avant en tenant touche CTRL appuyée etcliquant sur le bouton 'nbNext' ?...Comment de cela ?..
Ctrl + Clic : = 5 rangées enavant!
"Lanorme" DBNavigator n'a pas d'évènementOnMouseUp (paramètres utiliséspar le type TshiftState) vous ne pouvezdonc pas l'utiliser pour tester l'état des touches deALT, CTRL et MAJ. Le DBNavigatorvous fournit seulement l'événement OnClickpour manipuler.
Cependant,le TMyDBNavigator peut quand mêmelire l'événement OnMouseUp etvous permettre "de voir" l'état des touches contrôleet même la position du curseur au-dessus du bouton particulierquand il est appuyé!
Pourutiliser l'OnMouseUp vous assignezsimplement votre événement personnalisé traitantde la procédure à l'événement OnMouseUpdu bouton du DBNavigatormodifié.C'est exactement ce qui est fait dans la procédureSetupMyDBNav :
OnMouseUp: = MyNavMouseUp;
Maintenant,la procédure MyNavMouseUp pourraitressembler :
procedureTForm1.MyNavMouseUp(Sender:TObject; Button: TMouseButton;
Shift:TShiftState; X, Y: Integer);
constMoveBy : integer = 5;
begin
ifNOT (Sender is TNavButton) then Exit;
caseTNavButton(Sender).Index of
nbPrior:
if(ssCtrl in Shift) then
TDBNavigator(TNavButton(Sender).Parent).DataSource.DataSet.MoveBy(-MoveBy);
nbNext:
if(ssCtrl in Shift) then
TDBNavigator(TNavButton(Sender).Parent).DataSource.DataSet.MoveBy(MoveBy);
end;
end;
Notezque vous devez ajouter la déclaration de la procédureMyNavMouseUp à l'intérieur dela partie privée de la déclaration de Form (aprèsla déclaration de la procédure SetupMyDBNav):
type
TForm1= class(TForm)
...
private
procedureSetupMyDBNav(const Navigator : TDBNavigator; const Glyphs :TImageList);
procedureMyNavMouseUp(Sender:TObject; Button: TMouseButton; Shift:TShiftState; X, Y: Integer);
...
Expliquons,encore une fois. La procédure MyNavMouseUpmanipule l'événement OnMouseUppour chaque bouton de DBNavigator. Si l'utilisateurtient la touche de CRL appuyée tandisqu'il clique sur le bouton "nbNext",vous vous déplacez en avant de 5 enregistrements à lafois. (défini par la constante avec la valeur de 5).
Ilsuffit maintenant d'appliquer cette théorie dans l'événement"ordinaire" OnClick deDBNavigator.
Ilexiste 10 variables qui répondent aux évènementsde chaque boutons :
caseButton of
nbFirst: .....; //Premier
nbPrior: .....; //Précédent
nbNext: .....; //Suivant
nbLast: .....; //Dernier
nbInsert: .....; //Nouveau
nbDelete: .....; //Supprimer
nbEdit: .....; //Modifier
nbPost: .....; //Enregistrer
nbCancel: .....; //Annuler
nbRefresh:.....; //Actualiser
end;
Voyonsla procédure :
procedureTForm1.DBNavigator1Click(Sender: TObject; Button: TNavigateBtn);
functionCtrlDown : Boolean;
var
State: TKeyboardState;
begin
GetKeyboardState(State);
Result:= ((State[vk_Control] And 128) <> 0);
end;
constMoveBy : integer = 5;
begin
caseButton of
nbPrior:
ifCtrlDown then
DBNavigator1.DataSource.DataSet.MoveBy(-MoveBy);
nbNext:
ifCtrlDown then
DBNavigator1.DataSource.DataSet.MoveBy(MoveBy);
nbEdit:
DBNavigator1.Controls[0].Enabled :=False; //si vous voulez désactiver nbFirst
end; //fin de case
end;
Encoreune petite idée :
4boutons dans un carré montrent que vous ne voulez qu'un boutonpour remplacer les boutons nbFirst,nbPrevious, nbNext etnbLast. Vous pouvez utiliser les paramètresX et Y à l'intérieur de la procédureMyNavMouseUppour trouver laposition du curseur quand le bouton est relaché. Maintenant,vous pouvez attacher une image qui a 4 secteurs à celui-ci,chaque secteur est supposé imiter un des boutons dunavigateur. Il suffit de délimiter en X et Y les zones ou sesitue le pointeur de la souris pour activer tel ou tel boutons.(utiliser les propriétés Left, Top, Height et Width dubouton pour délimiter les zones et ce, quelques soit laposition du bouton).
Jevous laisse le soin d'imaginer le code et ces quelques formulesmathématiques.
Enrésumé, juste pour customiser le DBNavigator :
(vous pouvez utiliser le "Copier- Coller" à partir de ce document)
(attention au nom des composant,Form, Objet.)
1Placer un composant TimageList sur votre Form et inscrire vos10 images dans celui-ci.
2Ecrire le nouveau type sur votre Form : type TMyDBNav =class(TDBNavigator);
3Placer la déclaration de procédure dans la partie"private"
private
procedure SetupMyDBNav(constNavigator : TDBNavigator; const Glyphs : TImageList);
4 Ecrire la procédure SetupMyDBNav sur votre Form ( la procedure suivante ne fait QUE customiser le DBNavigator )
( n'oubliez pas de modifier TForm1par le nom de votre fenêtre )
procedureTForm1.SetupMyDBNav(const Navigator : TDBNavigator; const Glyphs :TImageList);
const
Captions : array[TNavigateBtn]of string =
('Premier', 'Précédent','Suivant', 'Dernier', 'Nouveau',
'Supprimer', 'Modifier','Enregistrer', 'Annuler', 'Actualiser');
var
btn : TNavigateBtn;
begin
for btn := Low(TNavigateBtn)to High(TNavigateBtn) do
withTMyDBNav(Navigator).Buttons[btn] do
begin
Caption := Captions[btn];
NumGlyphs := 1;
Glyph := nil;
Glyphs.GetBitmap(Integer(btn),Glyph);
Layout := blGlyphTop;
end;
end;
5 Déclarer votre procédure à l'ouverture de la fenêtre ( dans FormCreate )
procedureTForm1.FormCreate(Sender: TObject);
---
SetupMyDBNav(DBNavigator1,ImageList1);
---
end;
Laporte est ouverte pour toutes autres modifications ou sujétions.
Pourquoipas un composants DBNavigateur Hyper personnalisé ?.....