IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Blog de Serge Girard (aka SergioMaster)

[Delphi][VCL]Carnet de Plongées : TControlList - Un peu de boite de nuit pour la soirée

Noter ce billet
par , 11/03/2021 à 15h27 (1105 Affichages)
Au départ, je voulais trouver à quoi servaient les divers évènements OnBeforeDrawItems, OnBeforeDrawItem, OnAfterDrawItems, OnAftrerDrawItem du TControlList.

Pour ce faire, un design simple avec un TControlList et un TMemo. J'ai aussi "stylé" le programme (Projet/Option/Application/Apparence : Golden Graphite) pour voir comment se comportait les couleurs indiquées dans les propriétés ItemSelectionOptions de TControlList.

Nom : Capture.PNG
Affichages : 3053
Taille : 9,8 Ko

et un peu de code pour tracer les divers évènements.
Code Delphi : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
procedure TForm14.ControlList1AfterDrawItem(AIndex: Integer; ACanvas: TCanvas;
  ARect: TRect; AState: TOwnerDrawState);
begin
// Memo1.Lines.Add('AfterDrawItem index '+AIndex.ToSTring);
end;
 
procedure TForm14.ControlList1AfterDrawItems(ACanvas: TCanvas; ARect: TRect);
begin
 Memo1.Lines.Add('AfterDrawItems'); //
end;
 
procedure TForm14.ControlList1BeforeDrawItem(AIndex: Integer; ACanvas: TCanvas;
  ARect: TRect; AState: TOwnerDrawState);
begin
Memo1.Lines.Add('BeforeDrawItem index '+AIndex.ToString);
Label1.Caption:='Elément '+AIndex.ToString;
Shape1.Brush.Color:=Random($FFFFFF); // une petite couleur aléatoire
end;
 
procedure TForm14.ControlList1BeforeDrawItems(ACanvas: TCanvas; ARect: TRect);
begin
Memo1.Lines.Add('BeforeDrawItems');
end;
 
procedure TForm14.FormCreate(Sender: TObject);
begin
ControlList1.Enabled:=False;
COntrolList1.ItemCount:=20;
memo1.Lines.Clear;
ControlList1.Enabled:=True;
end;

Nom : Capture_.PNG
Affichages : 134
Taille : 25,1 Ko

La surprise vient surtout du comportement du programme. Jouez cette vidéo https://serge-girard.developpez.com/...rolList_1.webm et vous vous retrouverez au sein de la boite de nuit

  • OnBeforeDrawItems, apparemment est levé lorsque la partie visible de la liste doit être redessinée.
  • OnBeforeDrawItem, je l'ai assez souvent utilisé pour que vous ayez deviné qu'il s'agit du dessin d'un élément, ce qui était moins clair c'est qu'il s'agit seulement des éléments qui seront visibles.
  • OnAfterDrawItems, levé lorsque tous les éléments pouvant être visibles (même partiellement) auront été dessinés.
  • OnAfterDrawItem, cet évènement, par contre, me pose encore des soucis, vous constaterez que dans mon code, l'instruction est commentée, dans le cas contraire seul deux éléments s'affichent. Troublant, il faut certainement utiliser les arguments de cette procédure et agir dessus.

ATTENTION Ces constations ne sont pas gravées dans le marbre, ce qui est valable pour ce premier test ne l'est pas par la suite
Outre cette découverte accidentelle, cela explique en grande partie, le problème, lors de ma "plongée piscine", du ralentissement observé dans ma liste.
Il semblerait que les éléments soient souvent redessinés
Citation Envoyé par Debriefing entrainement piscine
Revoir. L'utilisation des jpg ralenti considérablement le programme.
Du coup, je me suis posé la questions sur les arguments ACanvas et ARect de la procédure OnBeforeDrawItem. Même si les noms semblent assez évidents au programmeurs chevronnés, à quoi pouvaient-ils bien servir ? Du coup, au sortir de ma boite de nuit j'ai envisagé de mettre des boules dans un sapin de Noël !

Rien de bien spécial au niveau design, j'ai juste utilisé le précédent en y ajoutant un commutateur pour "allumer" le sapin. Le seul signalement que je pourrais faire est que , j'ai fait en sorte que l'élément soit un carré de 70x70 et taillé le TControlList en conséquence pour avoir une sorte de grille de 5x6. (la sixième ligne c'est pour les cadeaux ).

Nom : Capture_2.PNG
Affichages : 146
Taille : 28,7 Ko

Tout se joue, là encore, au niveau du code.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
procedure TForm15.ControlList1BeforeDrawItem(AIndex: Integer; ACanvas: TCanvas;
  ARect: TRect; AState: TOwnerDrawState);
  procedure sommet;
  begin
    ACanvas.Pen.Color:=clGreen;
    ACanvas.Brush.Color:=clGreen;
    ACanvas.Polygon([TPoint.Create(ARect.Width div 2,Arect.Top),
                     TPoint.Create(0,ARect.Bottom),
                     ARect.BottomRight])
  end;
  procedure brancheGauche;
  begin
    ACanvas.Pen.Color:=clGreen;
    ACanvas.Brush.Color:=clGreen;
    ACanvas.Polygon([TPoint.Create(ARect.width,ARect.top),
                     TPoint.Create(0,ARect.Bottom),
                     ARect.BottomRight])
  end;
  procedure BrancheDroite;
  begin
    ACanvas.Pen.Color:=clGreen;
    ACanvas.Brush.Color:=clGreen;
    ACanvas.Polygon([ARect.TopLeft,
                     TPoint.Create(0,ARect.Bottom),
                     ARect.BottomRight])

  end;

begin
    // le canvas se dessine avant les controles
    case AIndex of
      2:
        sommet;
      6, 11, 15, 20:
        brancheGauche;
      8, 13, 19, 24:
        BrancheDroite;
      7, 12, 16, 17, 18, 21, 22, 23:
        begin
          ACanvas.Brush.Color := clGreen;
          ACanvas.FillRect(ARect);
        end;
    end;

  // Dessin des "boules"
  case AIndex of
    0, 1, 3, 4, 5, //7,
    9, 10,11,13,14,
    15, 19:
      Shape1.Visible := False;
  else
    begin
      if AIndex>24 then Shape1.Shape:=stRoundSquare
                   else Shape1.Shape:=stCircle;
      Shape1.Visible := true;
      Shape1.Brush.Color := Random($FFFFFF); // couleur aléatoire
    end;
  end;
  memo1.Lines.Add('BeforeDrawItem '+AIndex.ToString)
end;

procedure TForm15.ControlList1BeforeDrawItems(ACanvas: TCanvas; ARect: TRect);
begin
  memo1.Lines.Add('beforedrawitems');
end;

procedure TForm15.ToggleSwitch1Click(Sender: TObject);
begin
  memo1.Lines.Clear;
  ControlList1.Enabled := False;
  ControlList1.ItemCount := 0;
  if ToggleSwitch1.State = tssOn then
    ControlList1.ItemCount := 30;
  ControlList1.Enabled := False;
end;
Nom : Capture_1.PNG
Affichages : 132
Taille : 22,8 Ko

Important à savoir : le canvas est dessiné avant les contrôles.
Par contre, j'ai été tout d'abord déçu, ce programme ne se comportait pas comme celui au dessus, pas de clignotement des boules ! Il m'a fallu assez longtemps pour trouver une différence qui semble être la responsable : dans le programme "boite de nuit" le TControlList est aligné à la zone cliente contrairement au programme "sapin de Noël" que je n'ai pas aligné pour n'avoir toujours que cinq colonnes. Par contre, j'ai ancré ce dernier de cette manière [alLeft,alBottom], pour voir les cadeaux et voir clignoter il faut retailler la fenêtre. (voir cette vidéo https://serge-girard.developpez.com/...sapinnoel.webm )

En conclusion de cette "soirée" : quelques gadgets sympatiques, à explorer en profondeur. Rien ne se trouvant dans l'aide il y a là des zones entières à explorer dans le code source (de la plongée profonde avec paliers ?)

Envoyer le billet « [Delphi][VCL]Carnet de Plongées : TControlList - Un peu de boite de nuit pour la soirée » dans le blog Viadeo Envoyer le billet « [Delphi][VCL]Carnet de Plongées : TControlList - Un peu de boite de nuit pour la soirée » dans le blog Twitter Envoyer le billet « [Delphi][VCL]Carnet de Plongées : TControlList - Un peu de boite de nuit pour la soirée » dans le blog Google Envoyer le billet « [Delphi][VCL]Carnet de Plongées : TControlList - Un peu de boite de nuit pour la soirée » dans le blog Facebook Envoyer le billet « [Delphi][VCL]Carnet de Plongées : TControlList - Un peu de boite de nuit pour la soirée » dans le blog Digg Envoyer le billet « [Delphi][VCL]Carnet de Plongées : TControlList - Un peu de boite de nuit pour la soirée » dans le blog Delicious Envoyer le billet « [Delphi][VCL]Carnet de Plongées : TControlList - Un peu de boite de nuit pour la soirée » dans le blog MySpace Envoyer le billet « [Delphi][VCL]Carnet de Plongées : TControlList - Un peu de boite de nuit pour la soirée » dans le blog Yahoo

Catégories
Programmation , Delphi

Commentaires