[TSTringGrid] Rééxécuter l'evenement onDrawcell

Résolu
gazier20 Messages postés 9 Date d'inscription dimanche 22 janvier 2006 Statut Membre Dernière intervention 5 février 2006 - 4 févr. 2006 à 18:55
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 - 6 févr. 2006 à 00:37
Bonjour,

voila mon problème:

Je travaille sur StringGrid. Au lancement de mon programme, l'evenement ondrawcell se lance et dessine des trucs comme je le désire. Mais par la suite, je souhaiterais refaire appel à l'evenement on drawcell mais pas pour faire la meme chose (donc je ne peux utiliser repaint).

Je me suis dit, il faut que je cree une nouvelle procedure pour rediriger l'evenement ondrawcell vers la nouvelle procedure.

A un moment de mon programme j'ecris
StringGrid1.onDrawCell:=DrawCell(ACol,ARow,ARect,AState); // pr rediriger ondrawcell vers drawcell qui est la nvelle procedure

1er problème, je ne sais pas quoi mettre à ARect et surtout à Astate ???
2eme problème, l'evenement sera rediriger mais il faut que je lui dise de se relancer. Je ne peux pas utiliser repaint car cela va effacer ce qui a ete fait avant. Moi je veux que cela dessine en plus du reste.

J'attends vos réponses avec une grande impatience. Merci

19 réponses

cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
4 févr. 2006 à 19:52
Petite erreur qui n'est surement pas du goût du compilateur :
StringGrid1.onDrawCell:= DrawCell(ACol,ARow,ARect,AState);
Ca m'étonnerait que ça passe

Pour affecter une méthode à un évènement dans le code, il faut et il suffit que la signature de cette méthode soit compatible avec la signature de l'évènement.
En clair, si tu regardes le squelette de méthode généré par Delphi quand tu double cliques sur OnDrawCell dans l'onglet évènements, tu obtiens :

 procedure  TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
// procédure normale
end;

Il suffit alors de créer une méthode avec les mêmes arguments :

procedure TForm1.GridDrawCell2(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin

end;

Pour finir, tu peux affecter à l'évènement OnDrawCell l'une ou l'autre des deux méthodes ci-dessus quand le coeur t'en dit :

procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.OnDrawCell : = StringGrid1DrawCell;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  StringGrid1.OnDrawCell :=  GridDrawCell2;
 end ;

Explications :
OnDrawCell est en réalité un pointeur de méthode. Il suffit alors de lui affecter l'adresse d'une méthode (ou nil pour annuler le déclenchement d'un évènement). En aucun cas tu ne dois fournir les paramètres au moment de l'affectation. Ca n'a pas de sens pour le compilateur et il a bien raison.

<HR color =#008000>
Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
3
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
5 févr. 2006 à 10:16
1-> Eh bien, il suffit de réaffecter StringGrid1DrawCell à StringGrid1.OnDrawCell

Rien de plus à faire !
Quand une cellule a besoin d'être redessinée, le composant fera appel à la méthode indiquée lors de l'affectation. Si cette méthode a changé en cours d'exécution, le composant s'en moque du moment que c'est une méthode compatible (TDrawCellEvent dans le cas présent).
<hr color="#008000">Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
3
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
5 févr. 2006 à 13:19
Salut,
Essaye comme ceci :

procedure TForm1.Button1Click(Sender: TObject);
begin
StringGrid1.OnDrawCell := StringGrid1DrawCell2;
StringGrid1.Invalidate;
end;

@+
Cirec
3
gazier20 Messages postés 9 Date d'inscription dimanche 22 janvier 2006 Statut Membre Dernière intervention 5 février 2006
5 févr. 2006 à 02:35
Merci beaucoup pour cette réponse mais je ne suis pas totalement
satisfaisait. J'ai bien compris l'histoire de la redirection mais
lorsque je vais indiquer une nouvelle adresse de methode soit

StringGrid1.OnDrawCell := GridDrawCell2;



Il faut par la suite que je fasse executer 
StringGrid1.OnDrawCell comment faire ? Au lancement, il s'est executer mais comment le r&#233;executer ???



2&#232;me probl&#232;me: que mettre pour le parametre state:TGridDrawState lorque je fais l'appel de la proc&#233;dure?



Merci beaucoup et &#224; bientot



0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
gazier20 Messages postés 9 Date d'inscription dimanche 22 janvier 2006 Statut Membre Dernière intervention 5 février 2006
5 févr. 2006 à 02:53
Je viens de tester ce que vous m'avez dit et c'est exact il n'y a pas besoin de préciser les parametres de l'appel de la procedure donc je supprime le problème numero 2 de ma précédente remarque.

Par contre je maintiens mon problème sur le fait de relancer l'évènement ondrawcell.
Si vous avez une solution??

En tout cas merci beaucoup
0
gazier20 Messages postés 9 Date d'inscription dimanche 22 janvier 2006 Statut Membre Dernière intervention 5 février 2006
5 févr. 2006 à 12:20
Bonjour, je viens de tout essayer mais le problème c'est qu'il faut que je clique sur la cellule de la stringrid pour que le nouvel evenement drawcell2 s'execute. Moi je voudrais qu'il s'execute sans que j'ai besoin de cliquer sur une case en question.

Peut-être que l'évènement drawcell qui génère un évènement ondrawcell pourrait m'aider mais je ne vois comment l'executer.

Voici ma procédure:

procedure TForm1.StringGrid1DrawCell2(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
with StringGrid1.Canvas do
begin
if (Acol=2) and (Arow=2) then
begin
Pen.Color:=clred;
brush.style:=BsClear; //<= evite de remplir ton rectangle
rectangle(Rect.left,Rect.Top,rect.Right,rect.Bottom);
end;
end;
end;

Je voudrais que cela s'execute que je clique sur un bouton et n'ont quand je clique sur la cellule 2,2.

J'espère que mes explications sont claires. Merci beaucoup de m'aider
0
gazier20 Messages postés 9 Date d'inscription dimanche 22 janvier 2006 Statut Membre Dernière intervention 5 février 2006
5 févr. 2006 à 12:45
Je rajoute toute mon implementation pour que vous compreniez bien le problème:

implementation

{$R *.dfm}

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
with StringGrid1.Canvas do
begin
if (Acol=1) and (Arow=1) then
begin

Pen.Color:=cllime;
brush.style:=BsClear;
rectangle(Rect.left,Rect.Top,rect.Right,rect.Bottom);
end;
end;
end;

procedure TForm1.StringGrid1DrawCell2(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
with StringGrid1.Canvas do
begin
if (Acol=2) and (Arow=2) then
begin

Pen.Color:=clred;
brush.style:=BsClear;
rectangle(Rect.left,Rect.Top,rect.Right,rect.Bottom);
end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
StringGrid1.onDrawCell:=StringGrid1DrawCell2;
end;

end.

Le problème c'est que quand je clique sur le bouton cela change la direction de l'evenement mais par la suite il faut que je clique sur la cellule pour qu'elle se dessine et moi je ne voudrais pas à avoir à cliquer sur cette cellule.

J'attends vos réponses avec une grande impatience
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
5 févr. 2006 à 13:27
ps : Mais si c'est juste pour changer la couleur c'est pas la peine de redéfinir un deuxième évènement OnDrawCell
tu peux juste Faire :

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
with StringGrid1.Canvas do
beginif (Acol1) and (Arow1) then
Pen.Color:= cllime
Else
if (Acol =2) and (Arow= 2) then
Pen.Color: =clred;
brush.style:=BsClear;
rectangle(Rect.left,Rect.Top,rect.Right,rect.Bottom);
end;
end;

@+
Cirec
0
gazier20 Messages postés 9 Date d'inscription dimanche 22 janvier 2006 Statut Membre Dernière intervention 5 février 2006
5 févr. 2006 à 17:55
Bien joué pour le StringGrid1.Invalidate

Le problème c'est que cela efface ce que j'ai déja dessiné. Moi je veux que cela se rajoute.
Je ne peux pas utiliser votre 2ème solution dans mon cas

Avez-vous une solution pour éviter d'effacer ce qui a déjà été dessiné ?

Merci
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
5 févr. 2006 à 18:04
le code que tu as posté précedement est-il vraiment complet
parce que théoriquement seul les cellules [1, 1] et [2, 2] devraient se redessiner d'après ce que j'ai vu
Cells[1, 1] en clLime
et
Cells[2, 2] en clRed

@+
Cirec
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
5 févr. 2006 à 18:43
"Le problème c'est que cela efface ce que j'ai déja dessiné. Moi je veux que cela se rajoute."
Je suis de l'avis de Cirec pour dire que tu ne nous dit pas tout...
<hr color="#008000">Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0
gazier20 Messages postés 9 Date d'inscription dimanche 22 janvier 2006 Statut Membre Dernière intervention 5 février 2006
5 févr. 2006 à 20:28
Voila la totalité du code:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls;

type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
Button1: TButton;
procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure StringGrid1DrawCell2(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);

procedure Button1Click(Sender: TObject);

private
{ Déclarations privées }
public
{ Déclarations publiques }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
with StringGrid1.Canvas do
begin
if (Acol=1) and (Arow=1) then
begin

//1er rectangle vide plein
Pen.Color:=cllime;
brush.style:=BsClear; //<= evite de remplir ton rectangle
rectangle(Rect.left,Rect.Top,rect.Right,rect.Bottom);
end;
end;

end;

procedure TForm1.StringGrid1DrawCell2(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
with StringGrid1.Canvas do
begin
if (Acol=2) and (Arow=2) then
begin

//1er rectangle vide plein
Pen.Color:=clred;
brush.style:=BsClear; //<= evite de remplir ton rectangle
rectangle(Rect.left,Rect.Top,rect.Right,rect.Bottom);
end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
StringGrid1.onDrawCell:=StringGrid1DrawCell2;

end;

end.

Je n'ai pas encore cliqué sur reponse acceptée car je trouvais que mon problème n'était pas totalement résolu.
Mais ne vous inquiétez pas je le ferais dès que ma solution sera trouvée. Je suis désolé pour ce désagrément

En tout cas, je vous remercie beaucoup pour tout ce que vous faites.
0
gazier20 Messages postés 9 Date d'inscription dimanche 22 janvier 2006 Statut Membre Dernière intervention 5 février 2006
5 févr. 2006 à 20:30
Excusez j'ai oublié de mettre le StringGrid1.invalidate;

Mais meme avec, cela efface la précedente case couleur cllime.
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
5 févr. 2006 à 21:42
Bon j'ai testé et la rien ne s'éfface
Teste ce bout de code avec un seul évènement OnDrawCell :

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
with StringGrid1.Canvas do
begin
brush.style:= BsClear;
if (Acol =1) and (Arow= 1) then
Pen.Color: =cllime
Else if (Acol2) and (Arow2) then
Pen.Color:= clred
Else exit;
rectangle(Rect.left,Rect.Top,rect.Right,rect.Bottom);
end;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
StringGrid1.Cells[1,1] : = 'Delphifr';
end;

@+
Cirec
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
5 févr. 2006 à 22:34
D'accord avec toi Cirec, j'ai testé aussi et rien ne s'efface.
Aurait-il modifié une des propriétés du TStringGrid dans l'éditeur ? Du style mettre DefaultDrawing à False ?

<hr color="#008000">Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0
gazier20 Messages postés 9 Date d'inscription dimanche 22 janvier 2006 Statut Membre Dernière intervention 5 février 2006
5 févr. 2006 à 23:23
J'ai testé dans une nouvelle form cela s'efface toujours. Ce n'est pas grave.

Je vous remercie de tout ce que vous avez fait, merci
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
5 févr. 2006 à 23:33
@ Delphiprog :
Effectivement en mettant DefaultDrawing à False le texte s'éfface mais par defaut il est à True donc mystère et boule de gomme

@ Gazier20

J’ai beaucoup de mal à comprendre comment c'est possible on est deux à avoir testé le code et nous sommes arrivés aux mêmes conclusions ça fonctionne
Avec le dernier code que j'ai posté qu'est ce qui s'éfface chez toi

@+
Cirec
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
6 févr. 2006 à 00:28
@cirec : non, tout fonctionne correctement avec ton code aussi.

<hr color="#008000">Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
6 févr. 2006 à 00:37
mais oui justement c'est la que je ne comprend plus rien, pourquoi chez Gazier20 ça ne fonctionne pas
j'en perd mon latin euh non mon Delphi
0
Rejoignez-nous