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

Lazarus Pascal Discussion :

StringGrid : colonnes et lignes fixes


Sujet :

Lazarus Pascal

  1. #1
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 5
    Points : 3
    Points
    3
    Par défaut StringGrid : colonnes et lignes fixes
    Bonjour,

    J'ai une application avec un composant StringGrid sur lequel je souhaite avoir la première et dernière colonne fixes et la première et dernière ligne fixes.

    J'ai parcouru le net en long, en large et en travers et je n'ai pas trouvé de solution.

    Alors je fais appel aux âmes charitables qui auraient déjà été confrontés au problème et qui l'auraient résolu...

    Merci d'avance ...

  2. #2
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 729
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 729
    Points : 15 132
    Points
    15 132
    Par défaut
    Yep !

    Jamais été confronté au problème, mais je peux toujours passer l'idée qui m'est venue :
    ce composant StrinGrid est-il redimensionnable, ou avec des dimensions fixes ?

    S'il est de dimensions fixes, ben tu simules

    Tu rajoutes à droite du principal une autre StringGrid avec une seule colonne, et en bas encore une avec juste une ligne et hop !

    Bien sûr va y avoir un peu plus de code que prévu, , surtout si c'est redimensionnable
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    j'ai dû régler ce genre de problème. Je ne souhaite pas diffuser le source final : ce n'est pas que "c'est" précieux, mais c'est tellement "surchargé" qu'il faudrait le nettoyer pour qu'il soit exploitable de manière générale. Pour l'instant, il ne répond qu'à mes besoins et reste "illisible".

    Par contre, voici ma première ébauche fonctionnelle et "exploitable" au moins sous Windows. Comme la version finale, elle repose sur l'utilisation de 3 StringGrids dont on synchronise les scrollbars. Je m'étais inspiré d'un code Delphi. Il faut jouer des pixels pour les superposer, gérer les agrandissements des colonnes,... Rapidement cela devient fatiguant.
    Le code de synchronisation est le suivant :
    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
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    unit Unit1;
     
    {$mode objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Grids,
      StdCtrls, LMessages, LCLType, LCLIntf;
     
    type
     
      TSyncKind = (skBoth, skVScroll, skHScroll);
      TSyncStringGrid = class(TStringGrid)
      private
        FInSync: Boolean;
        FsyncGrid: TSyncStringGrid;
        FSyncKind: TSyncKind;
        { Private declarations }
        procedure LMVScroll(var Msg: TLMessage); message LM_VSCROLL;
        procedure LMHScroll(var Msg: TLMessage); message LM_HSCROLL;
      protected
        { Protected declarations }
      public
        { Public declarations }
        procedure DoSync(Msg, wParam: Integer; lParam: Longint); virtual;
      published
        { Published declarations }
        property SyncGrid: TSyncStringGrid read FSyncGrid write FSyncGrid;
        property SyncKind: TSyncKind read FSyncKind write FSyncKind default skBoth;
      end;
     
      { TForm1 }
     
      TForm1 = class(TForm)
        SG1, SGHorz: TStringGrid;
        SGVert: TStringGrid;
        procedure FormCreate(Sender: TObject);
        procedure SG1MouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure SG1MouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure SG1PrepareCanvas(sender: TObject; aCol, aRow: Integer;
          aState: TGridDrawState);
      private
        { private declarations }
       GridEvent1, GridEvent2, GridEvent3: TWndMethod;
       procedure Grid1WindowProc(var Message: TLMessage);
       procedure Grid2WindowProc(var Message: TLMessage);
       procedure Grid3WindowProc(var Message: TLMessage);
      public
        { public declarations }
      end;
     
    var
      Form1: TForm1;
      bColD, bRowD : integer;
    implementation
     
    {$R *.lfm}
     
    procedure TSyncStringGrid.DoSync(Msg, wParam: Integer; lParam: Longint);
    begin
      FInSync := True;
      Perform(Msg, wParam, lParam);
      FinSync := False;
    end;
     
    procedure TSyncStringGrid.LMVScroll(var Msg: TLMessage);
    begin
      if not FInSync
      and Assigned(FSyncGrid)
      and (FSyncKind in [skBoth, skVScroll]) then
        FSyncGrid.DoSync(LM_VSCROLL, Msg.wParam, Msg.lParam);
      inherited;
    end;
     
    procedure TSyncStringGrid.LMHScroll(var Msg: TLMessage);
    begin
      if not FInSync
      and Assigned(FSyncGrid)
      and (FSyncKind in [skBoth, skHScroll]) then
        FSyncGrid.DoSync(LM_HSCROLL, Msg.wParam, Msg.lParam);
      inherited;
    end;
     
    { TForm1 }
    procedure TForm1.Grid1WindowProc(var Message: TLMessage);
    begin
      GridEvent1(Message);
      if ((Message.Msg = LM_VSCROLL)
      or (Message.Msg = LM_HSCROLL)
      or (Message.Msg  = LM_MOUSEWHEEL)) then
         GridEvent2(Message);
    end;
     
    procedure TForm1.Grid2WindowProc(var Message: TLMessage);
    begin
      GridEvent2(Message);
      if ((Message.Msg = LM_VSCROLL)
      or (Message.Msg  = LM_HSCROLL)
      or (Message.Msg  = LM_MOUSEWHEEL)
      ) then
        GridEvent1(Message);
    end;
     
    procedure TForm1.Grid3WindowProc(var Message: TLMessage);
    begin
      GridEvent3(Message);
      if ((Message.Msg = LM_VSCROLL)
      or (Message.Msg  = LM_HSCROLL)
      or (Message.Msg  = LM_MOUSEWHEEL)) then
        GridEvent1(Message);
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    var i : integer;
    begin
      GridEvent1  := SG1.WindowProc;
      GridEvent2  := SGVert.WindowProc;
      GridEvent3  := SGHorz.WindowProc;
     
      with SG1 do begin
        Rowcount  := 30;
        ColCount  := 20;
        FixedRows := 1;
        FixedCols := 1
      end;
     
      with SGVert do begin
        Rowcount  := SG1.Rowcount;
        ColCount  := 1;
        FixedRows := 1;
        FixedCols := 0; {Sinon pas de gestion du ScroolBar}
      end;
     
      with SGHorz do begin
        Rowcount  := 1;
        ColCount  := SG1.Colcount;
        FixedRows := 0; {Sinon pas de gestion du ScroolBar}
        FixedCols := 1;
      end;
     
      with SG1 do
        for i := 1 to RowCount - 1 do begin
          Cells[0, i] := IntToStr(i);
          SGVert.Cells[0, i]     := 'Tot '+ IntToStr(i);
        end;
     
      with SG1 do
         for i := 1 to ColCount - 1 do begin
          Cells[i, 0 ] := IntToStr(i);
          SGHorz.Cells[i, 0]     := 'Tot ' + IntToStr(i);
        end;
     
      with SGVert do Cells[0, 0] := 'Totaux';
      with SGHorz do Cells[0 ,0] := 'Totaux';
     
      SG1.WindowProc      := @Grid1WindowProc;
      SGVert.WindowProc   := @Grid2WindowProc;
      SGHorz.WindowProc   := @Grid3WindowProc;
    end;
     
    procedure TForm1.SG1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
     {Pour le positionnement des cellules - Voir MouseUp}
     {if SG1.AutoAdvance <> aaNone then SG1.AutoAdvance := aaNone;
      Non fonctionnel ? Mal utilisé sans doute}
     SG1.MouseToCell(X, Y, bColD, bRowD);
    end;
     
    procedure TForm1.SG1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var
      aRowTmp : integer;
    begin
     {Pour le positionnement des cellules}
     {Comportement bizarre si click sur cellule dont faible fraction de
      la hauteur affichée aussi bien en haut qu'en bas}
     if (bRowD = SG1.TopRow) or (bRowD = SG1.RowCount -1) then begin
       if bRowD < SG1.Rowcount -1 then
         aRowTmp := SG1.topRow +1
       else  aRowTmp := SG1.topRow -1;
     
       SGVert.topRow := aRowTmp;
       SGVert.Row := aRowTmp;
       SG1.topRow := aRowTmp;
       SG1.Row:= aRowTmp;
     
       SGVert.topRow := bRowD;
       SGVert.Row := bRowD;
       SG1.topRow := bRowD;
       SG1.Row    := bRowD;
     end;
     SGHorz.Col := bColD;
    end;
     
    procedure TForm1.SG1PrepareCanvas(sender: TObject; aCol, aRow: Integer;
      aState: TGridDrawState);
    begin
      SGVert.TopRow := SG1.TopRow ; {Pour la gestion de SG1.MouseWheel}
    end;
     
    end.
    Par contre il faut absolument implanter "l'ajustement inverse" : vous remarquerez
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    procedure SG1MouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
    procedure SG1MouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
    procedure SG1PrepareCanvas(sender: TObject; aCol, aRow: Integer;
          aState: TGridDrawState);
    J'ai pris le temps de vérifier : j'ai rencontré et cela existe toujours un comportement bizarre sur les lignes du haut très partiellement affichées soit en haut (TopRow) de la StringGrid principale, soit en bas (dernière ligne) d'où le code en 2 temps de MouseDown et MouseUp et une réactualisation de l'affichage un peu curieuse..

    Ici ne sont pas gérés ni le parcours des cellules au clavier (avec les touches Up, Down, Left,...) ni la sélection sur un rectangle qui dépasse la partie visible de la StringGrid et donc nécessite une nouvelle synchronisation des grilles associées.

    Il faut également pallier le problème de la synchronisation des événements autres que le Scrolling (Création de colonnes, suppression) et éviter d'autoriser la modification de la hauteur des lignes . La solution que j'ai retenue utilise des scrollBars externes et donc 3 StringGrids en effet synchronisées, le tout placé dans un TPanel. Dans tous les cas, c'est un peu bricolé... mais faute de mieux...

    Cordialement. Gilles

    PS : Testé en rentrant chez moi sur mon Ubuntu 12.04 : OK -> maintenant compatible même au niveau dessin sans rien repositionner ni redimensionner (cf les 2 copies d'écran).
    Images attachées Images attachées   
    Fichiers attachés Fichiers attachés
    Dernière modification par Invité ; 09/06/2013 à 02h24. Motif: Mise à jour du code et des images pour compatibilité Win/Nux

Discussions similaires

  1. Réponses: 6
    Dernier message: 10/08/2012, 17h55
  2. Une colonne et une ligne fixes ?
    Par cartol dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 02/07/2010, 11h54
  3. Stringgrid: Éditer les lignes et les colones fixes.
    Par poly128 dans le forum Delphi
    Réponses: 4
    Dernier message: 12/04/2007, 03h05
  4. transformer des colonnes en lignes
    Par flonardi dans le forum Oracle
    Réponses: 13
    Dernier message: 28/10/2004, 12h43
  5. sélection colonnes et lignes d'une dbgrid
    Par propa dans le forum Bases de données
    Réponses: 6
    Dernier message: 13/05/2004, 10h32

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