IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

Fusion de cellules fixes


Sujet :

Delphi

  1. #41
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Bon, j'ai trouvé.

    Explication : si une case n'est pas visible, CellRect renvoie un TRect nul pour cette cellule, ce qui fausse la routine d'affichage

    Solution : calculer les coordonnées pixels des cellules concernées à l'aide d'une boucle. Comme il faut les coordonnées relatives à la zone d'affichage, il faut connaître la cellule située en haut à gauche. Et comme LeftCol et TopRow ne prennent en compte que les cellules non fixes, il faut encore une boucle pour déterminer cette cellule (je n'ai pas trouvé mieux, mais je pense que ça existe).

    Le code : il est certainement très optimisable, mais en l'état il semble fonctionner.

    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
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    // Indices de la case visible en haut à gauche, MÊME FIXE
    // (contrairement à TopRow et LeftCol)
    procedure GetSGTopLeftCoords(const SG:TStringGrid;var C,R:Integer);
     var I,J:Integer;Rc:TRect;
     begin
      C:=0;R:=0;
      with SG do
       begin
        for I := 0 to ColCount - 1 do for J := 0 to RowCount - 1 do
         begin
          Rc := CellRect(I,J);
          if (Rc.Left <> 0)  or (Rc.Top <> 0) or (Rc.Right <> 0) or (Rc.Bottom <> 0)
             then begin
                   C := I;
                   R := J;
                   Exit
                  end
         end
       end
     end;
     
    // Coordonnées pixels absolues de la case (I,J)
    procedure GetSGAbsRect(const SG:TStringGrid;const I,J:Integer;var R:TRect);
     var U,V:Integer;
     begin
      FillChar(R,SizeOf(R),0);
      with SG do
       begin
        for U:=0 to I-1 do R.Left := R.Left + ColWidths[U]  + GridLineWidth;
        for V:=0 to J-1 do R.Top  := R.Top  + RowHeights[V] + GridLineWidth;
        R.Right  := R.Left + ColWidths[I];
        R.Bottom := R.Top  + RowHeights[J];
       end;
     end;
     
    // Coordonnées pixels relatives de la case (I,J)
    procedure GetSGRect(const SG:TStringGrid;const I,J:Integer;var Rect:TRect);
     var RectTL : TRect;T,L:Integer;
     begin
      GetSGTopLeftCoords(SG,T,L);
      GetSGAbsRect(SG,T,L,RectTL); // Coords pix. abs. de la case en haut à gauche
      GetSGAbsRect(SG,I,J,Rect);   // Coords pix. abs. de la case (I,J)
      // Calcul des coordonnées pixels relatives de la case (I,J)
      Rect.Left   := Rect.Left   - RectTL.Left;
      Rect.Top    := Rect.Top    - RectTL.Top;
      Rect.Right  := Rect.Right  - RectTL.Left;
      Rect.Bottom := Rect.Bottom - RectTL.Top;
     end;
     
    function MergedCells(ASG:TStringGrid; ACol,ARow,ACol1,ARow1,ACol2,ARow2:Integer; ACurrentState: TGridDrawState):Boolean;
    var
      x1,y1,x2,y2:Integer;
      Rect,Rect1,Rect2:TRect;
    begin
     with ASG, Canvas do
      begin
       //Initialisations diverses
       Result := False;
       x1 := ACol1;
       y1 := ARow1;
       x2 := ACol2;
       y2 := ARow2;
     
       //On vérifie que la zone fusionnée est valide
       if x1 < 0 then x1 := 0;
       if x2 > ColCount-1 then x2 := ColCount-1;
       if y1 < 0 then y1 := 0;
       if y2 > RowCount-1 then y2 := RowCount-1;
     
       if (x1 > x2) or (y1 > y2) then
        begin
          result := false;
          exit;
        end;
     
       if ((ACol>=ACol1) and (ACol<=ACol2) and (ARow>=ARow1) and (ARow<=ARow2)) then
        begin
         GetSGRect(ASG,ACol1,ARow1,Rect1);
         GetSGRect(ASG,ACol2,ARow2,Rect2);
         Rect.Left := Rect1.Left;
         Rect.Top := Rect1.Top;
         Rect.Right := Rect2.Right;
         Rect.Bottom := Rect2.Bottom;
     
         FillRect(Rect);
         // Le bloc qui suit pour imiter le "look" par défaut
         if GridLineWidth = 1 then
          begin
           Pen.Color := clBlack;Pen.Width := 1;
           Canvas.Rectangle(Rect.Left-1,Rect.Top-1,Rect.Right+1,Rect.Bottom+1);
          end;
         //
         Frame3D(ASG.Canvas, Rect, clBtnHighlight, clBtnShadow, BevelWidth);
         InflateRect(Rect,-2,-2);
         DrawText(ASG.Canvas.Handle, PChar(Cells[ACol1,ARow1]), -1, Rect ,DT_CENTER or DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE );
         Result := True;
        end;
     
      end;
    end;

  2. #42
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 261
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 261
    Points : 19 424
    Points
    19 424
    Billets dans le blog
    63
    Par défaut
    Quand je scroll en une fois je n'ai pas le problème mais si je scroll par petit pas
    J'ai toujours le problème de défilement,

    Désolé

    mon unité:

    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
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Grids,ExtCtrls;
     
    type
      TForm1 = class(TForm)
        StringGrid1: TStringGrid;
        procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
          Rect: TRect; State: TGridDrawState);
        procedure FormCreate(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure GetSGTopLeftCoords(const SG:TStringGrid;var C,R:Integer);
     var I,J:Integer;Rc:TRect;
     begin
      C:=0;R:=0;
      with SG do
       begin
        for I := 0 to ColCount - 1 do for J := 0 to RowCount - 1 do
         begin
          Rc := CellRect(I,J);
          if (Rc.Left <> 0)  or (Rc.Top <> 0) or (Rc.Right <> 0) or (Rc.Bottom <> 0)
             then begin
                   C := I;
                   R := J;
                   Exit
                  end
         end
       end
     end;
     
    // Coordonnées pixels absolues de la case (I,J)
    procedure GetSGAbsRect(const SG:TStringGrid;const I,J:Integer;var R:TRect);
     var U,V:Integer;
     begin
      FillChar(R,SizeOf(R),0);
      with SG do
       begin
        for U:=0 to I-1 do R.Left := R.Left + ColWidths[u]  + GridLineWidth;
        for V:=0 to J-1 do R.Top  := R.Top  + RowHeights[V] + GridLineWidth;
        R.Right  := R.Left + ColWidths[i];
        R.Bottom := R.Top  + RowHeights[J];
       end;
     end;
     
    // Coordonnées pixels relatives de la case (I,J)
    procedure GetSGRect(const SG:TStringGrid;const I,J:Integer;var Rect:TRect);
     var RectTL : TRect;T,L:Integer;
     begin
      GetSGTopLeftCoords(SG,T,L);
      GetSGAbsRect(SG,T,L,RectTL); // Coords pix. abs. de la case en haut à gauche
      GetSGAbsRect(SG,I,J,Rect);   // Coords pix. abs. de la case (I,J)
      // Calcul des coordonnées pixels relatives de la case (I,J)
      Rect.Left   := Rect.Left   - RectTL.Left;
      Rect.Top    := Rect.Top    - RectTL.Top;
      Rect.Right  := Rect.Right  - RectTL.Left;
      Rect.Bottom := Rect.Bottom - RectTL.Top;
     end;
     
    function MergedCells(ASG:TStringGrid; ACol,ARow,ACol1,ARow1,ACol2,ARow2:Integer; ACurrentState: TGridDrawState):Boolean;
    var
      x1,y1,x2,y2:Integer;
      Rect,Rect1,Rect2:TRect;
    begin
     with ASG, Canvas do
      begin
       //Initialisations diverses
       Result := False;
       x1 := ACol1;
       y1 := ARow1;
       x2 := ACol2;
       y2 := ARow2;
     
       //On vérifie que la zone fusionnée est valide
       if x1 < 0 then x1 := 0;
       if x2 > ColCount-1 then x2 := ColCount-1;
       if y1 < 0 then y1 := 0;
       if y2 > RowCount-1 then y2 := RowCount-1;
     
       if (x1 > x2) or (y1 > y2) then
        begin
          result := false;
          exit;
        end;
     
       if ((ACol>=ACol1) and (ACol<=ACol2) and (ARow>=ARow1) and (ARow<=ARow2)) then
        begin
         GetSGRect(ASG,ACol1,ARow1,Rect1);
         GetSGRect(ASG,ACol2,ARow2,Rect2);
         Rect.Left := Rect1.Left;
         Rect.Top := Rect1.Top;
         Rect.Right := Rect2.Right;
         Rect.Bottom := Rect2.Bottom;
     
         FillRect(Rect);
         // Le bloc qui suit pour imiter le "look" par défaut
         if GridLineWidth = 1 then
          begin
           Pen.Color := clBlack;Pen.Width := 1;
           Canvas.Rectangle(Rect.Left-1,Rect.Top-1,Rect.Right+1,Rect.Bottom+1);
          end;
         //
         Frame3D(ASG.Canvas, Rect, clBtnHighlight, clBtnShadow, 1);
         InflateRect(Rect,-2,-2);
         DrawText(ASG.Canvas.Handle, PChar(Cells[ACol1,ARow1]), -1, Rect ,DT_CENTER or DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE );
         Result := True;
        end;
     
      end;
     
    end;
     
     
    procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    begin
    with Sender as TStringGrid do
     if gdFixed in State then // Si cellule fixe :
     if not MergedCells(StringGrid1,ACol,ARow,1,0,3,0,State)
        and not MergedCells(StringGrid1,ACol,ARow,4,0,6,0,State)
        then begin // Si cellule fixe pas fusionnée :
              FillRect(Canvas.Handle,Rect,Canvas.Brush.Handle);
              // Le bloc qui suit pour imiter le "look" par défaut
              if GridLineWidth = 1 then
               begin
                Canvas.Pen.Color := clBlack;Canvas.Pen.Width := 1;
                Canvas.Rectangle(Rect.Left-1,Rect.Top-1,Rect.Right+1,Rect.Bottom+1);
               end;
              //
              Frame3D(Canvas, Rect, clBtnHighlight, clBtnShadow, BevelWidth);
              InflateRect(Rect,-2,-2);
              DrawText(Canvas.Handle, PChar(Cells[ACol,ARow]), -1, Rect ,DT_CENTER or DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE );
             end;
     
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    StringGrid1.Cells[1,0]:='Hello1';
    StringGrid1.Cells[2,0]:='';
    StringGrid1.Cells[3,0]:='';
     
    StringGrid1.Cells[4,0]:='Hello2';
    StringGrid1.Cells[5,0]:='';
    StringGrid1.Cells[6,0]:='';
     
    end;
     
    end.
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  3. #43
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Essaie de rajouter en évènement OnTopLeftChanged le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TForm1.StringGrid1TopLeftChanged(Sender: TObject);
    begin
     StringGrid1.Repaint;
    end;

  4. #44
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 261
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 261
    Points : 19 424
    Points
    19 424
    Billets dans le blog
    63
    Par défaut
    Je ne parvient pas à implémenter la méthode TopLeftChanged:

    Impossible de trouver l'implémentation de la méthode StringGrid1TopLeftChanged

    La je ne pige pas trop...
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  5. #45
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Elle n'existe peut-être pas en Delphi 7 ?

    De toutes façons, il vaut mieux laisser tomber cette piste, j'avais créé cet évènement lors de mes essais, mais quand je le supprime ça marche tout aussi bien.

    Pourrais-tu aussi publier le .dfm en mode texte, ou alors carrément toute l'appli en zip, que je puisse tenter de reproduire le phénomène ?

  6. #46
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 261
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 261
    Points : 19 424
    Points
    19 424
    Billets dans le blog
    63
    Par défaut
    Non, j'ai toujours le problème de défilement même avec le paint...


    voici l'image:

    Pièce jointe 13951

    @+
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  7. #47
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Zut ! J'avais testé avec des FixedCols = 0 !

    Effectivement, il y a toujours un problème !

    Grmbl.

  8. #48
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 261
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 261
    Points : 19 424
    Points
    19 424
    Billets dans le blog
    63
    Par défaut
    Je vais te zipper le petit projet...

    Dans ce post..
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  9. #49
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Bon, je vois maintenant où est l'autre problème.

    Je n'avais pas pensé que les colonnes fixes restent en place lors d'un scroll horizontal, et les lignes fixes lors d'un scroll vertical, ce qui complique un peu la chose...

  10. #50
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 261
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 261
    Points : 19 424
    Points
    19 424
    Billets dans le blog
    63
    Par défaut
    Je te post quand même le projet:

    Pièce jointe 13953

    @+
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  11. #51
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Si je puis me permettre, suite à ce fil de discussion et avant que mon PC ne tombe en rade, je me suis penché sur le code de TStringgrid, en particulier, la partie où est appelé l'évènement OnDrawCell... La méthode Paint en fait.

    Et je pense que L'idéal, le plus simple de plus simple, serait de reprendre in-extenso le code de TStringGrid pour en faire un TStringGridBis un peu plus docile.
    Je m'explique, on est face à deux limitation de TstringGrid que l'on essaye de contourner :
    - Pas mal de functions et procédures gagnerait à être des méthodes publiques (notemment les routines qui permettent de calculer les limitations du rectangle (la fusion de cellules était elle prévue à l'origine ???) du canvas dans lequel se trouve un lot de cellule, les méthodes de dessin par défaut des cellules aussi (ça nous éviterais de réinventer la roue n'est-ce pas ?). Or ces fonctions et procédures sont implémentées en tant que "sous-procédures" de la méthode Paint (si si, regardez, il y en a une palanquée)
    - On pourrait à cette occasion rajouter un évènement OnAfterDrawCell, appelée après que tous les dessins gérés dans le OnPaint soient passé (donc tout à la fin du OnPaint, on aurais une sorte de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      .... 
                if Assigned(FOnAfterDrawCell) then FOnAfterDrawCell({tous les paramètres que l'on veut pour réaliser un dessin personalisé})
    vous voyez ce que je veus dire ?

    Parce que là, ça deviendrait facile de faire de jolies fusions de cellules
    Par contre, si on sort du code de la VCL sur le forum, c'est pas bien

    A moins, qu'exceptionnellement, pour le bien de la communauté Delphi, quelqu'un de chez Borland nous y autorise (Whiler ? es-tu là ? ).

    Si quelqu'un pouvait lui envoyer un gentil mail-perso en lui expliquant, ce serait top, là je ne peux malheureusement pas, étant en pleine réinstall de Windows. Et vu que je fais patch après patch pour arriver à trouver le logiciel/patch ou pilote qui fait que sur certains XP, la machine virtuelle Dos ne fonctionne plus, je ne suis pas au bout de mes peines). Et j'en ai besoin pour mon émulateur fétiche (Euphoric), DosBox ramant sur mon PC...

    A+
    Bidouilleuse Delphi

  12. #52
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Citation Envoyé par CapJack
    Bon, je vois maintenant où est l'autre problème.

    Je n'avais pas pensé que les colonnes fixes restent en place lors d'un scroll horizontal, et les lignes fixes lors d'un scroll vertical, ce qui complique un peu la chose...
    C'est ce dont j'avais tenté de tenir compte dans mon code
    Bidouilleuse Delphi

  13. #53
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    C'est sûr que repartir du code de la VCL serait le top, mais bon...

    En attendant, ça tourne à l'usine à gaz, mais je crois que je tiens le bon bout.

    Edit : Sauf que sauf que... si lors d'un scroll à droite le bloc fusionné est parti pour se cacher derrière le bloc de colonnes fixes, la méthode ne fonctionne plus puisqu'on risque de dessiner par dessus le bloc de colonnes fixes, vu que l'on est dans une zone visible de canevas... Arg.

    Bon, je vais laisser reposer pour ce soir, je suis presque certain de trouver une solution dans ces prochains jours, mais là il faut que j'y médite. Mon dernier code fonctionne si l'on a, soit que des lignes fixes, soit que des colonnes fixes. Ce n'est déjà pas si mal.

  14. #54
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 261
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 261
    Points : 19 424
    Points
    19 424
    Billets dans le blog
    63
    Par défaut
    Merci beaucoup CapJack,

    et bon courage pour la suite...

    Désolé de ne pas intervenir sur le code, mais il vaut mieux se baser sur un seul code...

    Waskol, pour le moment il s'agit d'un besoin ponctuel donc le futur code de CapJack me conviendra...

    Bonne soirée a vous deux !
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  15. #55
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Et hop !

    J'ai entièrement repris le code. Cette fois, ça semble fonctionner. Particularité de cette version : elle peut aussi être utilisée pour des cellules non-fixes !

    En outre, c'est beaucoup plus simple et élégant que les autres versions. Preuve que parfois, il faut savoir sortir la tête de l'eau pour méditer un 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
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    // Renvoie true si (C,R) est valide et dans le rectangle supérieur gauche fixe
    function SGFixedTopLeft(const SG:TStringGrid;const C,R:Integer):Boolean;
    begin Result := (C >= 0) and (C < SG.FixedCols) and (R >= 0) and (R < SG.FixedRows) end;
     
    // Renvoie true si (C,R) est valide et dans le rectangle supérieur fixe verticalement
    function SGFixedTop(const SG:TStringGrid;const C,R:Integer):Boolean;
    begin Result := (C >= SG.FixedCols) and (C < SG.ColCount) and (R >= 0) and (R < SG.FixedRows) end;
     
    // Renvoie true si (C,R) est valide et dans le rectangle gauche fixe horizontalement
    function SGFixedLeft(const SG:TStringGrid;const C,R:Integer):Boolean;
    begin Result := (C >= 0) and (C < SG.FixedCols) and (R >= SG.FixedRows) and (R < SG.RowCount) end;
     
    // Renvoie true si (C,R) est valide et dans le rectangle non fixe
    function SGNotFixed(const SG:TStringGrid;const C,R:Integer):Boolean;
    begin Result := (C >= SG.FixedCols) and (C < SG.ColCount) and (R >= SG.FixedRows) and (R < SG.RowCount) end;
     
    function DrawMergedCells(const ASG:TStringGrid;const ACol,ARow,ACol1,ARow1,ACol2,ARow2:Integer):Boolean;
    var
      C1,R1,C2,R2,C,R:Integer;
      Fixed : Boolean;
      DR    : TRect; // Rectangle à dessiner
    begin
     with ASG, Canvas do
      begin
       //Initialisations diverses
       Result := False;
       C1 := ACol1;R1 := ARow1;C2 := ACol2;R2 := ARow2;
       if C1 < 0 then C1 := 0;
       if C2 >= ColCount then C2 := ColCount-1;
       if R1 < 0 then C1 := 0;
       if R2 >= RowCount then C2 := RowCount-1;
     
       if (C1 <= C2) and (R1 <= R2) and (ACol>=C1) and (ACol<=C2) and (ARow>=R1) and (ARow<=R2)
          then begin
     
                // Deuxième série de validations. La zone fusionnée doit être comprise
                // toute entière dans l'une des quatre zones définies plus haut
                // pour être logiquement valide.
     
                if ( SGFixedTopLeft(ASG,C1,R1) and SGFixedTopLeft(ASG,C2,R2) )
                or ( SGFixedTop(ASG,C1,R1) and SGFixedTop(ASG,C2,R2) )
                or ( SGFixedLeft(ASG,C1,R1) and SGFixedLeft(ASG,C2,R2) )
                   then Fixed := True
                else if ( SGNotFixed(ASG,C1,R1) and SGNotFixed(ASG,C2,R2) )
                   then Fixed := False
                else Exit;
     
                // Si DrawMergedCells est appelée, cela signifie que la cellule
                // concernée par l'affichage est visible, donc CellRect
                // Renvoie les vraies coordonnées écran de la cellule concernée.
                DR := CellRect(ACol,ARow);
                // Maintenant on agrandit le rectangle de la zone de fusion,
                // en partant de la cellule courante, donc sans faire d'appels
                // à CellRect qui risqueraient de renvoyer des rectangles nuls.
                DR.Right := DR.Left + ColWidths[ACol];
                for C := ACol - 1 downto C1 do DR.Left := DR.Left - ColWidths[C] - GridLineWidth;
                for C := ACol + 1 to C2 do DR.Right := DR.Right + ColWidths[C] + GridLineWidth;
                DR.Bottom := DR.Top + RowHeights[ARow];
                for R := ARow - 1 downto R1 do DR.Top := DR.Top - RowHeights[R] - GridLineWidth;
                for R := ARow + 1 to R2 do DR.Bottom := DR.Bottom + RowHeights[R] + GridLineWidth;
     
                if Fixed
     
                 then
                   begin
                    FillRect(DR);
                    // Le bloc qui suit pour imiter le "look" par défaut
                    if GridLineWidth = 1 then
                       begin
                        Pen.Color := clBlack;Pen.Width := 1;
                        Canvas.Rectangle(DR.Left-1,DR.Top-1,DR.Right+1,DR.Bottom+1);
                       end;
                    //
                    Frame3D(ASG.Canvas, DR, clBtnHighlight, clBtnShadow, BevelWidth);
                    InflateRect(DR,-2,-2);
                    DrawText(ASG.Canvas.Handle, PChar(Cells[ACol1,ARow1]), -1, DR ,DT_CENTER or DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE );
                    Result := True;
                   end
     
                 else
                   begin
                    // TODO... cellules non-fixes fusionnées
                   end;
               end;
      end;
    end;
     
     
    procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    begin
    with Sender as TStringGrid do
     if not DrawMergedCells(Sender as TStringGrid,ACol,ARow,1,0,3,0)
     and not DrawMergedCells(Sender as TStringGrid,ACol,ARow,4,0,6,0)
     then DrawMergedCells(Sender as TStringGrid,ACol,ARow,ACol,ARow,ACol,ARow);
    end;

  16. #56
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 261
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 261
    Points : 19 424
    Points
    19 424
    Billets dans le blog
    63
    Par défaut
    Ca a l'air de fonctionner sur le petit projet,

    Je transfert le tout dans mon appli et te confirme d'ici quelques minutes

    @+
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  17. #57
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 261
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 261
    Points : 19 424
    Points
    19 424
    Billets dans le blog
    63
    Par défaut
    BRAVO !!!!

    Alors la chapeau !

    On en a révé tu l'as fait !

    Ca me sauve vraiment, et ya pas mal de monde qui peut être intéressé par ton code vu que les autres grid sont payant !


    Faudrait que tu vois avec Waskol pour mettre tout sa dans la faq et vous pourriez par la suite crée le composant hérité de TStringGrid avec cette fonctionnalité entre autre...

    Bravo encore et 1 grand merci !


    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  18. #58
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Ben merci !

    On va voir pour le composant hérité, dans l'immédiat pas trop le temps, mais ce sera fait !

  19. #59
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Citation Envoyé par CapJack
    Ben merci !

    On va voir pour le composant hérité, dans l'immédiat pas trop le temps, mais ce sera fait !
    Alors là chapeau !
    J'ai hâte d'avoir installé mon Delphi pour essayer ça !
    Bidouilleuse Delphi

Discussions similaires

  1. Fusion de cellules (fixes) dans TStringGrid
    Par pjtuloup dans le forum C++Builder
    Réponses: 0
    Dernier message: 03/06/2010, 14h08
  2. [JTable]Fusion de cellules
    Par vincent63 dans le forum Composants
    Réponses: 6
    Dernier message: 13/02/2006, 14h28
  3. [VB6] Problème MsFlexgrid et Fusion des cellules
    Par dubidon dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 07/02/2006, 09h00
  4. remplir des cellules fixes dans une colone
    Par tahri_1989 dans le forum Bases de données
    Réponses: 1
    Dernier message: 11/01/2006, 16h06
  5. [VBA-E] Fusion de cellule
    Par Nicos77 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 29/07/2004, 13h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo