[StringGrid] Problemes de bordures [Résolu]

Messages postés
8
Date d'inscription
vendredi 10 juin 2005
Dernière intervention
18 août 2007
- 25 juin 2007 à 15:01 - Dernière réponse :
Messages postés
446
Date d'inscription
vendredi 7 novembre 2003
Dernière intervention
8 octobre 2008
- 27 juin 2007 à 14:09
Bonjour


j'ai créé une Stringgrid, et j'utilise l'évènement onDrawCell pour changer les bordures sur certaines cellules.

mais le problème c'est que quand je clique sur une cellule, les bordures reviennent aux bordures par défaut


j'ai essayé en mettant GoDrawFocusSelected a true ou false ça ne change rien

merci
Afficher la suite 

Votre réponse

13 réponses

Meilleure réponse
Messages postés
8
Date d'inscription
vendredi 10 juin 2005
Dernière intervention
18 août 2007
- 27 juin 2007 à 09:57
3
Merci
resolu, finalement je redessine a chaque fois les lignes blanche quand il faut les dessiner
c'est quand meme le bordel...

Merci jmulans 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de jmulans
Messages postés
446
Date d'inscription
vendredi 7 novembre 2003
Dernière intervention
8 octobre 2008
- 25 juin 2007 à 15:10
0
Merci
Bonjour,
Pourrais-tu nous donner l'événement OnDrawCell ?
Cela pourrais-être dû au fait qu'il faut que tu redessine la cellule pour tout les états du "State" (Sélectionné ou non)
Dom
Commenter la réponse de dominique.stock
Messages postés
900
Date d'inscription
vendredi 3 novembre 2000
Dernière intervention
30 juillet 2009
- 25 juin 2007 à 15:11
0
Merci
salut,

si tu nous copiais ton code (OnDrawCell), on pourrait mieux comprendre d'où peut venir le problem.

Sinon, as-tu bien testé les flags et traité (selected, ...) ? Ajouter un "outputdebugstrin('Drawing')" dans ton event peut t'aider a comprednre quand il est appelé.

A+

Loda
Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
Commenter la réponse de cs_Loda
Messages postés
900
Date d'inscription
vendredi 3 novembre 2000
Dernière intervention
30 juillet 2009
- 25 juin 2007 à 15:13
0
Merci
on s'est croisé!

Le trucs rassurant, c'est qu'on demande la même choses :-D

Loda
Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
Commenter la réponse de cs_Loda
Messages postés
446
Date d'inscription
vendredi 7 novembre 2003
Dernière intervention
8 octobre 2008
- 25 juin 2007 à 15:15
0
Merci
;-)
Par contre qu'est-ce que c'est que ça ?
outputdebugstrin('Drawing')

Dom
Commenter la réponse de dominique.stock
Messages postés
8
Date d'inscription
vendredi 10 juin 2005
Dernière intervention
18 août 2007
- 25 juin 2007 à 15:43
0
Merci
voila onDrawCell
j'ai enlevé tout ce qui n'avais aucun rapport, pour ne pas vous embrouiller
en fait c'est un planning, j'ai les personnes dans les cellules de gauche, et les jour en haut
je vous met un sreen avec :)

procedure TFenetrePrincipale.StringGrid_planningDrawCell(Sender: TObject;
  ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
var
  i,j: Integer;
  Row1,Row2;
  fusion: boolean;
begin

    // fusion des cellules
    // on recherche les cellules identiques a fusionner, puis on fusionne
    Row1 := 1; Row2 := 1;
    fusion := false;
    if ACol = 0 then
    for i:=1 to StringGrid_Planning.RowCount - 1 do
    begin
         if StringGrid_Planning.Cells[0,i] = StringGrid_Planning.Cells[0,i+1] then
         begin
              inc(Row2);
              fusion := true;
         end
         else
         begin
              inc(Row1); inc(Row2);
              fusion := false;
         end;

         if fusion = false then
         begin
              if (Row1 <> Row2) and (Row1 <> (Row2+1)) then
              begin
                   MergedCells(StringGrid_Planning,ACol,ARow,0,Row1-1,0,Row2-1,State);
                   Row1 := Row2;
              end else
              begin
                   //StringGrid_Planning.Canvas.Pen.Color := clBlack;
                   //StringGrid_Planning.Canvas.Polyline([ point(rect.left, rect.bottom) , rect.BottomRight ]);
              end;
         end;

    end;

end;

{*------------------------------------------------------------------------------
Fusionner des cellules
------------------------------------------------------------------------------*}
procedure MergedCells(AStringGrid:TStringGrid;CurrentCol,CurrentRow,Col1,Row1,Col2,Row2:Integer;CurrentState: TGridDrawState);
var x1,y1,x2,y2:Integer;
    X,Y,i: Integer;
    ARect:TRect;
begin
  //Initialisations diverses
  ARect:=Bounds(0,0,0,0);
  x1:=Col1;
  y1:=Row1;
  x2:=Col2;
  y2:=Row2;

  //On vérifie que la zone fusionnée est valide
  if x1<0 then x1:=0;
  if x2>AStringGrid.ColCount-1 then x2:=AStringGrid.ColCount-1;
  if y1<0 then y1:=0;
  if y2>AStringGrid.RowCount-1 then x2:=AStringGrid.RowCount-1;
  if (x1>x2) or (y1>y2) then
  begin
    Exit;
  end;

  for i:= Row1 to Row2-1 do
  begin
  ARect.Left:=AStringGrid.CellRect(1,i).Left;
  ARect.Top:=AStringGrid.CellRect(1,i).Top;
  ARect.Right:=AStringGrid.CellRect(AStringGrid.ColCount,i).Right;
  ARect.bottom:=AStringGrid.CellRect(AStringGrid.ColCount,i).Bottom;

  // bordures
  AStringGrid.Canvas.Pen.Color := clWhite;
  AStringGrid.Canvas.Polyline([ point(Arect.left, Arect.bottom) , point(Arect.Right, Arect.bottom) ]);
  end;
 
  //Si la cellule courante est la dernière de la zone de fusion, on dessine dans la fusion le texte de la cellule en haut à gauche
  if ((CurrentCol=Col2) and (CurrentRow=Row2)) then
  begin

        ARect.Left:=AStringGrid.CellRect(Col1,Row1).Left;
        ARect.Top:=AStringGrid.CellRect(Col1,Row1).Top;
        ARect.Right:=AStringGrid.CellRect(Col2,Row2).Right;
        ARect.bottom:=AStringGrid.CellRect(Col2,Row2).Bottom;

        //alignement horizontal
        X:=ARect.Left + (ARect.Right-ARect.Left-AStringGrid.Canvas.TextWidth(AStringGrid.Cells[CurrentCol,CurrentRow])) div 2;
        // alignement vetical
        Y:=ARect.Top + (ARect.Bottom-ARect.Top-AStringGrid.Canvas.TextHeight(AStringGrid.Cells[CurrentCol,CurrentRow])) div 2;
        AStringGrid.Canvas.TextRect(ARect, X, Y, AStringGrid.Cells[Col1,Row1]);
  end;

end;
Commenter la réponse de jmulans
Messages postés
446
Date d'inscription
vendredi 7 novembre 2003
Dernière intervention
8 octobre 2008
- 25 juin 2007 à 15:58
0
Merci
Ben, il faut que tu dessines pour tous les State ...

Dom
Commenter la réponse de dominique.stock
Messages postés
8
Date d'inscription
vendredi 10 juin 2005
Dernière intervention
18 août 2007
- 25 juin 2007 à 16:01
0
Merci
je met ça au tout debut ça ne change rien

Canvas.brush.color := clWhite;
Canvas.Font.Color := clBlack;
StringGrid_Planning.Canvas.Brush.Style := bsSolid;
StringGrid_Planning.Canvas.fillrect(Rect);

et meme sur les seules cellules qui sont dessinées, la bordure se remet quand meme
Commenter la réponse de jmulans
Messages postés
103
Date d'inscription
mardi 11 avril 2006
Dernière intervention
4 mars 2009
- 25 juin 2007 à 22:21
0
Merci
As-tu positionné l'attribut DefaultDrawing à false ?

Par contre dans ce cas, il ne faut pas oublier de dessiner les cellules non fusionnées.

sylvunix
Commenter la réponse de sylvunix
Messages postés
8
Date d'inscription
vendredi 10 juin 2005
Dernière intervention
18 août 2007
- 26 juin 2007 à 10:18
0
Merci
oui j'ai essayé de mettre true ou false ça me donne la meme chose

en fait je ne fusionne que les cellules de gauche, ou il y a les personnes, le autres ne doivent pas l'etre, il ne doit juste pas y avoir de bordure entre elles
je dessine donc les bordures en blanc. mais quand je clique sur ces cellules ça me remet les birdures grises par defaut :-/
Commenter la réponse de jmulans
Messages postés
900
Date d'inscription
vendredi 3 novembre 2000
Dernière intervention
30 juillet 2009
- 27 juin 2007 à 12:04
0
Merci
re,

@dominique.stock:
OutPutDebugString est un API de win pour le debug en release. Essai! Tu verra le message dans la fenetre "Event log". Indispensable pour debuger les events rapide ou qui ne peuvent pas être interomput (break point).

DefaultDrawing := false; +1
(sinon le focus vas te changer tes bordures. non?)

@jmulan:
hum.
d'abord, saches que l'event Draw est appelé un nombre très élevé de fois. Dons c'est important de bien l'optimiser et d'éviter tout "calculs". cad de calculer les états perso (tel que quelle cellules est fusionée avec quelles autres) en dehors de l'event.

J'ai fait un test. il ne marche pas bien, mais il peut peut-être t'aider.
unit TestGrid_frm;

interface

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

type TodaCellPos = record
// abs. pos. (relative est aussi possible)
  X, Y : integer;
end;

const
  NO_CELL_POS : TodaCellPos = (X:-1;Y:-1);
  MAX_CELL_X = 3;
  MAX_CELL_Y = 3;

type
  TfrmTestgrid = class(TForm)
    StringGrid1: TStringGrid;
    procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
      var CanSelect: Boolean);
    procedure FormCreate(Sender: TObject);
    procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
  private
    Fusionnee : array [0..MAX_CELL_X,0..MAX_CELL_Y] of TodaCellPos;
    // max two cell per fusion

    procedure Init_Fusionnee;

    procedure DrawCell_Normal(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);

    procedure DrawCell_Fusionnee(Sender: TObject; ACol1, ARow1,ACol2, ARow2: Integer;
      State: TGridDrawState);
  end;

var
  frmTestgrid: TfrmTestgrid;

implementation

uses
  math;

{$R *.dfm}

{ TfrmTestgrid }

procedure TfrmTestgrid.DrawCell_Fusionnee(Sender: TObject; ACol1, ARow1, ACol2,
  ARow2: Integer; State: TGridDrawState);
var
  SG : TStringGrid;
  C : TCanvas;
  R1,R2,R : TRect;
  X,Y : integer; //indice

  SR: TGridRect;
begin
 SG := sender as TStringGrid;
 C  := SG.Canvas;
 //add test sur validite des index (cell doivent se toucher)

 // Corrige le State. (cas le state vient d'UNE des deux cellules)
 SR := sg.Selection;
 if
   (InRange(ACol1,SR.Left,sr.Right) and InRange(ARow1,SR.Top,SR.Bottom) ) or
   (InRange(ACol2,SR.Left,sr.Right) and InRange(ARow2,SR.Top,SR.Bottom) ) then
   State := State + [gdSelected];

 // choisit les couleurs
 if gdSelected in State then begin
   C.Brush.Color := clBlue;
   C.Pen.Color := clRed;
   C.Pen.Width := 4;
   C.Font.Color := clYellow;
 end else begin
 // add cas pour autre state
   C.Brush.Color := clWhite;
   C.Pen.Color := clRed;
   C.Font.Color := clBlack;
 end;

 R1 := SG.CellRect(ACol1,ARow1);
 R2 := SG.CellRect(ACol2,ARow2);

 // add les zones
 R.Top    := Min(R1.Top,R2.Top);
 R.Left   := Min(R1.Left,R2.Left);
 R.Bottom := Max(R1.Bottom,R2.Bottom);
 R.Right  := Max(R1.Right,R2.Right);

 C.Rectangle(R);

 // text of TopLeft cell:
 C.TextRect(R,R.Left,R.Bottom, SG.Cells[Min(ACol1,ACol2),Min(ARow1,ARow2)]);

end;

procedure TfrmTestgrid.DrawCell_Normal(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  SG : TStringGrid;
  C : TCanvas;
begin
 SG := sender as TStringGrid;
 C  := SG.Canvas;

 if gdSelected in State then begin
   C.Brush.Color := clSkyBlue;
   C.Pen.Width := 4;
   C.Pen.Color := clYellow;
 end else begin
 // add cas pour autre state
   C.Brush.Color := clYellow;
   C.Pen.Color := clGray;
 end;

 C.Rectangle(Rect);

 C.TextRect(Rect,Rect.Left,Rect.Bottom,SG.Cells[ACol,ARow]);

end;

procedure TfrmTestgrid.Init_Fusionnee;
var i,k : integer;
begin
  for i := 0 to MAX_CELL_X do
    for k := 0 to MAX_CELL_Y do
      Fusionnee[i,k] := NO_CELL_POS;

// ajoute ici un chargement depuis un fichier ou autres.

  // une "fusion" entre 2,2 et 2,3
  Fusionnee[2,2].X := 3;
  Fusionnee[2,2].Y := 2;
  // ce system (simpliste) necessite une double reference.
  Fusionnee[3,2].X := 2;
  Fusionnee[3,2].Y := 2;

end;

procedure TfrmTestgrid.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  P : TodaCellPos;
begin

  //test sur indice
  if not InRange(ACol,0,MAX_CELL_X) then exit;
  if not InRange(ARow,0,MAX_CELL_Y) then exit;

  OutPutDebugString(pchar(format('Draw : %d %d',[ACol,ARow])));

  P := Fusionnee[ACol,ARow];
  if (P.X -1) or (P.Y -1) then begin
  // default drawing
    DrawCell_Normal(Sender,ACol,ARow,Rect,State);
  end else begin
    OutPutDebugString('Draw : FUSION');
    //Fusion
    DrawCell_Fusionnee(Sender,ACol,ARow,P.X,P.Y, State);
  end;

end;

procedure TfrmTestgrid.FormCreate(Sender: TObject);
begin
  Init_Fusionnee;
end;

procedure TfrmTestgrid.StringGrid1SelectCell(Sender: TObject; ACol,
  ARow: Integer; var CanSelect: Boolean);
var
   P : TodaCellPos;
  SG : TStringGrid;
  myRect: TGridRect;
begin
  SG := sender as TStringGrid;

  //test sur indice
  if not InRange(ACol,0,MAX_CELL_X) then exit;
  if not InRange(ARow,0,MAX_CELL_Y) then exit;

  OutPutDebugString(pchar(format('Sel : %d %d',[ACol,ARow])));

  P := Fusionnee[ACol,ARow];
  if (P.X -1) or (P.Y -1) then begin
    //no fusion
    exit;
  end else begin
    //membre de fusion
    // -> Select All the fusion
    OutPutDebugString('Sel : FUSION');
   
    MyRect.Left := Min(P.X,ACol);
    MyRect.Top  := Min(P.Y,ARow);
    MyRect.Bottom := Max(P.Y,ARow);
    MyRect.Right := Max(P.X,ACol);

    SG.Selection := MyRect;

  end;

end;

end.
Bug du test:
- n'efface pas la second cellule du groupe lorsque le group pert le focus.
- la bordure doit être dessiner à la main à l'intérieur de la zone de la cellule.

Loda, de retour de son combat de trois jours avec l'administration (et tout ça pour payer mes impôts... grrr)

Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
Commenter la réponse de cs_Loda
Messages postés
8
Date d'inscription
vendredi 10 juin 2005
Dernière intervention
18 août 2007
- 27 juin 2007 à 13:07
0
Merci
"d'abord, saches que l'event Draw est appelé un nombre très élevé de fois."
oui c'est ce que j'ai pu voir


j'ai limité les boucles a l'interieur de la procedure car ça faisait buguer pas mal de truc


merci pour ton aide ;)
Commenter la réponse de jmulans
Messages postés
446
Date d'inscription
vendredi 7 novembre 2003
Dernière intervention
8 octobre 2008
- 27 juin 2007 à 14:09
0
Merci
Merci !
Dom
Commenter la réponse de dominique.stock

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.