Bonjour,
J'ai terminé l'étape de modification de mon composant TstringGrid et quelques questions restent sans réponse à mon niveau. En vrac,
j'ai dans un premier temps voulu overrider OnSelection. Impossible, ai-je lu. Certes, mais pourquoi ? [Question 1]
D'un autre côté, un code comme ceci semble fonctionner sous Windows. Ce n'est pas un override "classique" mais il semble rendre le même service. Est-ce le cas et ce code est-il acceptable ? [Question 2]
Mais pas sous Linux... Pour s'en convaincre, il suffit dans l'Inspecteur d'Objet du nouveau composant de créer un OnSelection.
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 unit myStringGrid; {$mode objfpc}{$H+} interface uses [...] type TmyStringGrid = class(TStringGrid) private { Private declarations } { --Modification de l'évènement................................... [partie 1a]} FOnSelection : TNotifyEvent; { --Modification de l'évènement................................... [partie 1b]} procedure SelfOnSelection(Sender : TObject; aCol, aRow: Integer); protected { Protected declarations } public { Public declarations } published { --Modification de l'évènement................................... [partie 1c]} property OnSelection : TNotifyEvent read FOnSelection write FOnSelection; { Published declarations } end; procedure Register; implementation procedure Register; begin [...] end; constructor TmyStringGrid.Create(AOwner: TComponent); var iLoc : integer; begin Inherited Create(AOwner); { --Modification de l'évènement................................... [partie 2]} FOnSelection := nil; Inherited OnSelection := @SelfOnSelection; end; { --Modification de l'évènement................................... [partie 3] } procedure TmyStringGrid.SelfOnSelection(Sender: TObject; aCol, aRow: Integer); begin [...] {Mon code} if Assigned(FOnSelection) then FOnSelection(Sender); //ou Self ? {Cette dernière ligne est à éliminer s'il s'agit d'un code de remplacement et non d'un code complémentaire précédant ou suivant le code de l'utilisateur. Suivant le cas on peut la placer avant Mon code ou après} end; end.
En Win on obtient : procedure TForm1.myStringGrid1Selection(Sender: TObject; aCol, aRow: Integer);
Alors que sous Linux : procedure TForm1.myStringGrid1Selection(Sender: TObject); Pourquoi cette différence de comportement ? [Question 3]
Bref, j'aimerais me mettre au clair avec ceci.
D'un autre côté, j'ai overridé à la place SelectCell, comme me l'avait suggéré mick605. J'ai voulu un peu optimiser le code en limitant les invalidates
Suivant le nombre de FixedCols, je ne comprends pas bien pourquoi, il y a une différence entre l'approche Windows et l'approche Linux. Cela ne fait pas l'objet de question.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 function TmyStringGrid.SelectCell(ACol: Integer;ARow: Integer) : Boolean; begin {$IFDEF Linux} if FixedCols + 1 < RowCount - 1 then if (aCol = FixedCols + 1) and (aRow >= FixedRows) then {$ENDIF} {$IFDEF MsWindows} if (aCol = FixedCols) and (aRow >= FixedRows) then {$ENDIF} invalidate; inherited; end;
Enfin, je rencontre toujours ce problème agaçant : Que faut-il faire pour que toutes les modifications soient prises en compte notamment au niveau des properties ? Un clean and rebuild de Lazarus me semble parfois insuffisant... au point que je préfère parfois désinstaller le composant puis le réinstaller dans l'IDE. Dans les 2 cas, quelle perte de temps. Là, non plus. C'est une constatation et comme j'ai déjà plusieurs fois posé la question...
Une dernière question, pour la prochaine étape : dans ma StringGrid multiselect, j'ai voulu utiliser des lignes de couleurs... Alors, le problème c'est qu'overrider DrawCell me semble "délicat". La colorisation ne pose pas de problème particulier... sauf si "en production", on utilise des images dans le OnDrawcell (de l'Insp. d'Objet du composant). Si on intègre le code de modification des couleurs dans DrawCell overridé du composant, je peux différencier le contexte (utilisation de Columns ou pas) mais comment peut-on différencier la présence d'une image de celle d'un texte à posteriori ?
Dans le composant, grosso-modo :
Je n'ai malheureusement plus de temps à consacrer à ces problèmes mais les éventuelles réponses m'intéressent... pour les prochaines vacances scolaires.
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 procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); {override;} var [...] begin inherited; if (aCol >= FixedCols) and (aRow >= FixedRows) then begin sTmp := Cells[aCol,Arow]; {On suppose ici DEJA que c'est du texte... mais si la Cell contient déjà une image (chargée par le inherited, c'est un post-traitement) comment la détecte-t-on ?} {Gestion des couleurs de fond} [...] { Dessin du fond } FillRect(aRect); { Les polices } [...] { Dessin du texte } [...] if Columns.Count > 0 then begin if Columns[aCol-1].Alignment = taLeftJustify then DrawText(Canvas.Handle, PChar(sTmp), length(sTmp), aRect, DT_SINGLELINE or DT_VCENTER or DT_LEFT or DT_END_ELLIPSIS)[...] end else {Pas de Tcolumn utilisé donc alignement à gauche} Canvas.TextRect(aRect, aRect.Left+3, aRect.Top-2, sTmp); end;
D'avance merci.
Cordialement. Gilles
Partager