[Delphi][VCL]Carnet de Plongées : TControlList - Un peu de boite de nuit pour la soirée
par
, 11/03/2021 à 15h27 (647 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.
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;
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![]()
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 !Envoyé par Debriefing entrainement piscine
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).
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;
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 ?)