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

gazier20 9 Messages postés dimanche 22 janvier 2006Date d'inscription 5 février 2006 Dernière intervention - 4 févr. 2006 à 18:55 - Dernière réponse : Cirec 4225 Messages postés vendredi 23 juillet 2004Date d'inscription 24 juin 2018 Dernière intervention
- 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
Afficher la suite 

Votre réponse

19 réponses

Meilleure réponse
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 4 févr. 2006 à 19:52
3
Merci
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.

Merci cs_Delphiprog 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 84 internautes ce mois-ci

Commenter la réponse de cs_Delphiprog
Meilleure réponse
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 5 févr. 2006 à 10:16
3
Merci
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.

Merci cs_Delphiprog 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 84 internautes ce mois-ci

Commenter la réponse de cs_Delphiprog
Meilleure réponse
Cirec 4225 Messages postés vendredi 23 juillet 2004Date d'inscription 24 juin 2018 Dernière intervention - 5 févr. 2006 à 13:19
3
Merci
Salut,
Essaye comme ceci :

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

@+
Cirec

Merci Cirec 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 84 internautes ce mois-ci

Commenter la réponse de Cirec
gazier20 9 Messages postés dimanche 22 janvier 2006Date d'inscription 5 février 2006 Dernière intervention - 5 févr. 2006 à 02:35
0
Merci
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



Commenter la réponse de gazier20
gazier20 9 Messages postés dimanche 22 janvier 2006Date d'inscription 5 février 2006 Dernière intervention - 5 févr. 2006 à 02:53
0
Merci
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
Commenter la réponse de gazier20
gazier20 9 Messages postés dimanche 22 janvier 2006Date d'inscription 5 février 2006 Dernière intervention - 5 févr. 2006 à 12:20
0
Merci
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
Commenter la réponse de gazier20
gazier20 9 Messages postés dimanche 22 janvier 2006Date d'inscription 5 février 2006 Dernière intervention - 5 févr. 2006 à 12:45
0
Merci
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
Commenter la réponse de gazier20
Cirec 4225 Messages postés vendredi 23 juillet 2004Date d'inscription 24 juin 2018 Dernière intervention - 5 févr. 2006 à 13:27
0
Merci
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
Commenter la réponse de Cirec
gazier20 9 Messages postés dimanche 22 janvier 2006Date d'inscription 5 février 2006 Dernière intervention - 5 févr. 2006 à 17:55
0
Merci
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
Commenter la réponse de gazier20
Cirec 4225 Messages postés vendredi 23 juillet 2004Date d'inscription 24 juin 2018 Dernière intervention - 5 févr. 2006 à 18:04
0
Merci
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
Commenter la réponse de Cirec
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 5 févr. 2006 à 18:43
0
Merci
"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.
Commenter la réponse de cs_Delphiprog
gazier20 9 Messages postés dimanche 22 janvier 2006Date d'inscription 5 février 2006 Dernière intervention - 5 févr. 2006 à 20:28
0
Merci
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.
Commenter la réponse de gazier20
gazier20 9 Messages postés dimanche 22 janvier 2006Date d'inscription 5 février 2006 Dernière intervention - 5 févr. 2006 à 20:30
0
Merci
Excusez j'ai oublié de mettre le StringGrid1.invalidate;

Mais meme avec, cela efface la précedente case couleur cllime.
Commenter la réponse de gazier20
Cirec 4225 Messages postés vendredi 23 juillet 2004Date d'inscription 24 juin 2018 Dernière intervention - 5 févr. 2006 à 21:42
0
Merci
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
Commenter la réponse de Cirec
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 5 févr. 2006 à 22:34
0
Merci
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.
Commenter la réponse de cs_Delphiprog
gazier20 9 Messages postés dimanche 22 janvier 2006Date d'inscription 5 février 2006 Dernière intervention - 5 févr. 2006 à 23:23
0
Merci
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
Commenter la réponse de gazier20
Cirec 4225 Messages postés vendredi 23 juillet 2004Date d'inscription 24 juin 2018 Dernière intervention - 5 févr. 2006 à 23:33
0
Merci
@ 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
Commenter la réponse de Cirec
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 6 févr. 2006 à 00:28
0
Merci
@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.
Commenter la réponse de cs_Delphiprog
Cirec 4225 Messages postés vendredi 23 juillet 2004Date d'inscription 24 juin 2018 Dernière intervention - 6 févr. 2006 à 00:37
0
Merci
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
Commenter la réponse de Cirec

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.