VI. Mise en oeuvre des options▲
Le chapitre précédent a exposé les différentes formes que le code peut donner au curseur pour mettre en évidence la position de la souris dans une grille.
Ces options peuvent être sélectionnées facilement à l'aide de boîtes à cocher.
VI-1. Liste des options disponibles▲
Le projet a présenté les méthodes permettant de surligner la case survolée par la souris :
- En changeant la couleur du fond de la case ;
- En encadrant la case ;
- En changeant la couleur de toute la ligne ;
- En changeant la couleur de toute la colonne ;
- En dessinant une horizontale à la hauteur de la souris ;
- En dessinant une verticale à la hauteur de la souris.
Soit six options de base, auxquelles seront ajoutées, à titre d'illustration, la mise en couleur du fond de la grille et le remplissage des cases par des nombres aléatoires. Pour autoriser un choix multiple, la solution la plus simple est d'utiliser le composant CheckBox, soit huit cases à cocher qui porteront les noms suivants (Caption) :
- Case ;
- Cadre ;
- Ligne ;
- Colonne ;
- Horizontale ;
- Verticale ;
- Fond couleur ;
- Aléatoire.
Avec Lazarus, glisser successivement les huit checkbox dans le formulaire, au-dessous de la grille. Modifier la propriété Caption pour donner à chacun la valeur ci-dessus.
VI-2. Curseurs▲
Les six premières options sont conditionnées par l'identité d'un paramètre détecté par la souris (sCol par exemple) avec le paramètre traité par la procédure OnDrawCell, aCol en l'occurence.
Pour simplifier l'écriture du code, on remplacera :
If (aCol=sCol) Then...par une expression raccourcie :
If Colonne Then...
Ceci suppose que la variable Colonne soit un booléen, qui sera déclarée en local, et définie par :
Colonne:=(aCol=sCol);Au cours de l'exécution de la procédure DessinGrille, le programme compare les deux variables aCol et sCol. Si elles sont identiques, la variable Colonne bascule sur Vrai. Sinon, elle bascule sur Faux. Avec la même affectation pour la variable Ligne, l'ensemble des conditions qui feront apparaître un fond de couleur dans la case survolée par la souris devient :
If CheckBox1.Checked And Ligne And Colonne Then...Pour que la ligne entière soit surlignée, la condition sera :
If CheckBox3.Checked And Ligne Then...Et pour la colonne :
If CheckBox4.Checked And Colonne Then...
L'instruction qui suit le mot Then attribue la couleur de son choix à la variable Brush.Color.
Sauf à imposer des couleurs différentes, cette instruction va se répéter trois fois.
Pour l'éviter, simplifier l'écriture du code et gagner en délai d'exécution, il suffit d'introduire Or.
Le code devient, pour les trois options :
If (CheckBox1.Checked And Ligne And Colonne) Or
(CheckBox3.Checked And Ligne) Or
(CheckBox4.Checked And Colonne) Then...Pour les lignes, il est nécessaire de définir la couleur de Pen.Color, puis de décider du point de départ et de l'arrivée. Avec l'option Cadre, le code s'écrira :
If CheckBox2.Checked And Ligne And Colonne Then
begin
Largeur:=MaGrille.ColWidths[aCol]-2;
Hauteur:=MaGrille.RowHeights[aRow]-2;
MoveTo(aRect.Left, aRect.Top);
LineTo(aRect.Left+Largeur, aRect.Top);
LineTo(aRect.Left+Largeur, aRect.Top+Hauteur);
LineTo(aRect.Left, aRect.Top+Hauteur);
LineTo(aRect.Left, aRect.Top);
end;Avec les options Horizontale et Verticale, le code devient à son tour :
If CheckBox5.Checked And Ligne Then
begin
MoveTo(0, cooY);
LineTo(MaGrille.Width, cooY);
end;
If CheckBox6.Checked And Colonne Then
begin
MoveTo(cooX, 0);
LineTo(cooX, MaGrille.Height);
end;VI-3. Remplissage de la grille▲
Dans l'état actuel du projet, les cases sont remplies avec leur numéro, et le fond de chaque case a conservé sa couleur d'origine, à l'exception des ligne et colonne fixes et des cases retenues par les options curseurs précédentes.
Les CheckBox 7 et 8 seront utilisées en exploitant leur propriété OnChange : chaque changement d'état déclenche une procédure qui réalisera l'effet recherché.
VI-3-A. Couleur de la grille▲

Dans le formulaire MonFormulaire, cliquer sur le composant CheckBox7.
L'inspecteur d'objets fait apparaître ses propriétés ; dans l'onglet Evénements, cliquer sur OnChange et saisir ChangeCouleur, puis appuyer sur Entrer.
Dans l'éditeur de source apparaît la nouvelle procédure et compléter le code pour alterner entre l'affichage par défaut et la couleur de votre choix :
procedure TMonFormulaire.ChangeCouleur(Sender: TObject);
begin
With MaGrille do
begin
If Color=clWindow Then Color:=$00FEFFE6
Else Color:=clWindow;
end;
end;
Le test porte sur la couleur par défaut, clWindow.
La couleur proposée en échange est un bleu très pâle, mais toute autre couleur claire fera l'affaire.
Pour modifier la couleur des cellules fixes, il faut utiliser la propriété FixedColor dont la valeur par défaut est clBtnFace.
VI-3-B. Texte des cellules▲
Dans le formulaire MonFormulaire, cliquer sur le composant CheckBox8.
L'inspecteur d'objets fait apparaître ses propriétés ; dans l'onglet Evénements, cliquer sur OnChange et saisir ChangeRemplissage, puis appuyer sur Entrer.
Dans l'éditeur de source apparaît la nouvelle procédure ; compléter le code pour alterner entre l'affichage des numéros et l'affichage de nombres aléatoires :
Les affichages Caption sont modifiés systématiquement pour que l'utilisateur ait toujours un choix clair à sa disposition.
Le remplissage de la grille est maintenant affecté à une procédure spécialisée.
Le code initialement inscrit dans la procédure CreationGrille peut être supprimé.
Mais en conséquence la grille apparaîtra vide au démarrage et il faudra cliquer sur Aléatoire pour provoquer son remplissage.
VI-4. Bilan▲

Le projet avait pour objectif de créer un curseur réellement pratique dans une grille ; l'objectif est maintenant atteint.
Les mouvements de la souris sont suivis selon le souhait de l'utilisateur par la mise en surbrillance d'une ligne, d'une colonne, ou d'une case de six façons différentes.
Le code exploite cinq types d'événements différents et aboutit à un affichage clair et stable.
L'article suivant abordera les usages pratiques du composant StringGrid, avec la mise en valeur de cellules particulières, indépendamment de la position de la souris.
Voici le code de l'unité EssaiGrille.pas :
unit EssaiGrille;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Fileutil, Lresources, Forms, Controls, Graphics, Dialogs,
Grids, StdCtrls;
type
{ TMonFormulaire }
TMonFormulaire = class(TForm)
Button1: TButton;
Checkbox1: Tcheckbox;
Checkbox2: Tcheckbox;
Checkbox3: Tcheckbox;
Checkbox4: Tcheckbox;
Checkbox5: Tcheckbox;
Checkbox6: Tcheckbox;
Checkbox7: Tcheckbox;
Checkbox8: Tcheckbox;
MaGrille: TStringGrid;
procedure Button1click(Sender: TObject);
procedure Changecouleur(Sender: TObject);
procedure Changeremplissage(Sender: TObject);
procedure Coordsouris(Sender: TObject; Shift: Tshiftstate; X, Y: integer);
procedure Creationformulaire(Sender: TObject);
procedure Dessingrille(Sender: TObject; Acol, Arow: integer;
Arect: Trect; Astate: Tgriddrawstate);
private
{ Private Declarations }
public
{ Public Declarations }
end;
var
MonFormulaire: TMonFormulaire;
var
sCol, sLig, cooX, cooY: integer;
implementation
{ TMonFormulaire }
procedure Tmonformulaire.Button1click(Sender: TObject);
begin
with MaGrille do
if Cells[1, 1] = '' then
Cells[1, 1] := 'Bonjour'
else
Cells[1, 1] := '';
end;
procedure Tmonformulaire.Changecouleur(Sender: TObject);
begin
with MaGrille do
begin
if Color = clWindow then
Color := $00FEFFE6
else
Color := clWindow;
end;
end;
procedure Tmonformulaire.ChangeRemplissage(Sender: TObject);
var
i, j: integer;
begin
with MaGrille do
for i := 1 to ColCount - 1 do
for j := 1 to RowCount - 1 do
if CheckBox8.Checked then
Cells[i, j] := IntToStr(i + (RowCount - 1) * (j - 1))
else
Cells[i, j] := IntToStr(1 + Random(10000));
if (CheckBox8.Caption = 'Numéros') then
CheckBox8.Caption := 'Aléatoire'
else
CheckBox8.Caption := 'Numéros';
end;
procedure Tmonformulaire.Coordsouris(Sender: TObject; Shift: Tshiftstate;
X, Y: integer);
begin
with MaGrille do
begin
cooX := X;
cooY := Y;
Cells[1, 2] := 'X =' + IntToStr(X);
Cells[1, 3] := 'Y =' + IntToStr(Y);
MouseToCell(X, Y, sCol, sLig);
Cells[0, 0] := 'C ' + IntToStr(sCol) + ' - L ' + IntToStr(sLig);
Repaint;
end;
end;
procedure Tmonformulaire.Creationformulaire(Sender: TObject);
var
i, j: integer;
begin
Randomize;
with MaGrille do
begin
for i := 1 to ColCount - 1 do
Cells[i, 0] := 'Col ' + IntToStr(i);
for i := 1 to RowCount - 1 do
Cells[0, i] := 'Lig ' + IntToStr(i);
for i := 1 to ColCount - 1 do
for j := 1 to RowCount - 1 do
Cells[i, j] := IntToStr(i + (RowCount - 1) * (j - 1));
//Cells[i,j]:=IntToStr(1+Random(10000));
end;
end;
procedure Tmonformulaire.Dessingrille(Sender: TObject; Acol, Arow: integer;
Arect: Trect; Astate: Tgriddrawstate);
var
Largeur, Hauteur: integer;
Ligne, Colonne: boolean;
begin
Ligne := aRow = sLig;
Colonne := aCol = sCol;
with MaGrille.Canvas do
begin
if (CheckBox1.Checked and Ligne and Colonne) or (CheckBox3.Checked and Ligne) or
(CheckBox4.Checked and Colonne) then
begin
Brush.Color := clYellow;
FillRect(aRect);
end;
if CheckBox2.Checked and Ligne and Colonne then
begin
Pen.Color := clRed;
Largeur := MaGrille.ColWidths[aCol] - 2;
Hauteur := MaGrille.RowHeights[aRow] - 2;
MoveTo(aRect.Left, aRect.Top); //angle supérieur gauche
LineTo(aRect.Left + Largeur, aRect.Top);//1ère horizontale
LineTo(aRect.Left + Largeur, aRect.Top + Hauteur);//1ère verticale
LineTo(aRect.Left, aRect.Top + Hauteur);//2ème horizontale
LineTo(aRect.Left, aRect.Top); //retour
end;
if CheckBox5.Checked and Ligne then
begin
Pen.Color := clRed;
MoveTo(0, cooY);
LineTo(MaGrille.Width, cooY);
end;
if CheckBox6.Checked and Colonne then
begin
Pen.Color := clRed;
MoveTo(cooX, 0);
LineTo(cooX, MaGrille.Height);
end;
end;
end;
initialization
{$I EssaiGrille.lrs}
end.

