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 :

[ScrollBar] Détecter apparition sur une grille


Sujet :

Delphi

  1. #1
    Membre éprouvé
    Avatar de Andry
    Profil pro
    Informaticien
    Inscrit en
    Juillet 2002
    Messages
    1 164
    Détails du profil
    Informations personnelles :
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : Juillet 2002
    Messages : 1 164
    Points : 1 181
    Points
    1 181
    Par défaut [ScrollBar] Détecter apparition sur une grille
    Salut à tous.

    Comment puis je intercepter le moment ou le stringgrid affiche le scrollbar vertical par exemple.
    Ceci dans un souci de presentation de l'IHM de mon petit appli.

    Cordialement

  2. #2
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 770
    Points
    2 770
    Par défaut
    tu peut expliqué plus??
    sa utilité pour vs??

  3. #3
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 54
    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
    On distingue deux types de scrollbar dans windows

    - Les "Contrôles ScollBar" : ce sont des scrollbars gérées par l'application
    • Ce sont des controles fenétrés (on va dire...), (donc placées dans la zone cliente d'un TWinControl par exemple).
      Exemple de Création (dans la méthode CreateParams d'un contrôle dérivé):
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      CreateSubClass(Params, 'SCROLLBAR');
    • On ne peut agir que sur l'arrière plan de la scrollbar via le message WM_CTLCOLORSCROLLBAR, le message est géré par le TWinControl parent de la scroll bar, exemple avec une ScrollBar dans une Fiche :
      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
       
      //Dans la partie interface
      TForm1 = class(TForm)
           ScrollBar1: TScrollBar;
          Button1: TButton;
          procedure FormCreate(Sender: TObject);
          procedure FormDestroy(Sender: TObject);
        private
          { Déclarations privées }
        public
          { Déclarations publiques }
          ScrollBrush:TBrush;
          procedure ScrollPaint(var msg:TWMCtlColorScrollbar); message WM_CTLCOLORSCROLLBAR;
        end;
       
      //Dans la partie implementation
      procedure TForm1.FormCreate(Sender: TObject);
      begin
         ScrollBrush:=TBrush.Create;
         ScrollBrush.Color:=clYellow;
      end;
       
      procedure TForm1.FormDestroy(Sender: TObject);
      begin
        ScrollBrush.Free;
      end;
       
      procedure TForm1.ScrollPaint(var msg: TWMCtlColorScrollbar);
      begin
        msg.Result:=Form1.ScrollBrush.Handle;
      end;
    • On peut même arriver à redessiner par dessus puisqu'elles sont placés dans la zone cliente d'une fenêtre


    - Les ScrollBars standard : Ce sont des scrollbars gérées par le système
    • On peut changer leur couleur grace à SetSyscolor :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      procedure TForm1.Button1Click(Sender: TObject);
      var A,B:array[0..0] of integer;
      begin
        A[0]:=COLOR_SCROLLBAR;
        B[0]:=colorToRGB(clGreen);
        SetSysColors(1,A,B);
      end;
      Mais attention, celà est censé changer la couleur par défaut de toutes les ScrollBars standard du sytème, sauf que non en fait (et là je n'ai aucune explication, j'ai pas creusé suffisemment) :
      - Ne fonctionne pas quand le theme XP est actif (il faut être en Win9x ou en Theme "classique" sous XP)
      - Ne fonctione pas sur certaines scrollbars standard (celles des contrôles de la VCL qui sont des encapsulation de contrôles Windows )
      - Par contre, les scrollbars des navigateurs changent bien de couleur (parce que ce ne sont pas des contrôles Windows standard)
      - On peut les créer avec l'API CreateWindowEx


    - Les ScrollBar Système :
    • Ce sont des ScrollBars standard crées par Windows pour les contrôles standard Windows (TMemo, etc...) ou bien crées avec les API SetScrollRange, ShowScrollBar, etc... (ex: TStringGrid)
    • On ne peut pas arriver à redessiner par dessus puisqu'elles sont placés dans une zone non-cliente de la fenêtre du contrôle et gérée par le système (enfin, je n'ai jamais réussi, celà dit je n'ai pas essayer en interceptant le message WM_PAINT du contrôle fenétré et en dessinant après la gestion standard du message ) :
      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
       
      TMonControl=Class(TStringGrid);
      private
       ...
        procedure MsgPaint(var Msg:TMsg); //WM_Paint
      end;
      ...
      procedure TMonControl.MsgPaint(var Msg:TMsg);
      ...
        DefaultPaintHandler(Msg);
        Dessine_par_dessus_de_la scrollBar;
        //La scrollbar verticale se trouve entre les coordonnées horizontales
        //self.ClientRect.Right et self.Width
       
        //La scrollbar horizontale se trouve entre les coordonnées verticales
        //self.ClientRectBottom et self.Height
      end;


    Il ne reste plus qu'à tout créer son propre contrôle et tout dessiner à la mimine, pour ce faire, on dispose des armes suivantes :

    Les dimensions des scrollBars standard (pour en dessiner sois même avec des dimensions acceptables) :
    SM_CXHSCROLL Width of arrow bitmap on horizontal scroll bar
    SM_CXHTHUMB Width of scroll box on horizontal scroll bar. In version 4.0 or later, this value retrieves the width a scroll bar that has a page size of zero.
    SM_CXVSCROLL Width of arrow bitmap on vertical scroll bar
    SM_CYHSCROLL Height of arrow bitmap on horizontal scroll bar
    SM_CYVSCROLL Height of arrow bitmap on vertical scroll bar
    SM_CYVTHUMB Height of scroll box on vertical scroll bar.
    In version 4.0 or later, this value retrieves the height
    of a scroll bar that has a page size of zero.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var CXHSCROLL,CXHTHUMB,CXVSCROLL,CYHSCROLL,CYVSCROLL,CYVTHUMB:integer;
    begin
      CXHSCROLL:=GetSystemMetrics(SM_CXHSCROLL);
      CXHTHUMB :=GetSystemMetrics(SM_CXHTHUMB);
      CXVSCROLL:=GetSystemMetrics(SM_CXVSCROLL);
      CYHSCROLL:=GetSystemMetrics(SM_CYHSCROLL);
      CYVSCROLL:=GetSystemMetrics(SM_CYVSCROLL);
      CYVTHUMB:=GetSystemMetrics(SM_CYVTHUMB);
    La possibilité de dessiner des morceaux de scrollbar "standard" grace à l'API DrawFrameControl


    C'est infernal, hein ?????

  4. #4
    Membre habitué Avatar de jambonstar
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    175
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 175
    Points : 161
    Points
    161
    Par défaut
    Waskol, tu t'es emporté là.

    En tout cas très belle explication.

    Par contre elle me semble Hors Sujet... . Je crois qu'il veux juste intercepter le message qui fait apparaitre la scrollbar. Pour en faire quoi, on ne le saura jamais...

  5. #5
    Membre averti
    Inscrit en
    Octobre 2005
    Messages
    338
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 338
    Points : 383
    Points
    383
    Par défaut
    bonjour

    @jambonstar
    il me semble que Andry est très clair,
    Ceci dans un souci de presentation de l'IHM de mon petit appli.
    il est vrai que moi étant plus "binaire", à la conception je prévoi la place d'un scrollbar éventuel à mon StringGrid pour éviter le masquage partiel du dernier champ. Andry est plus puriste et souhaite adapter son StringGrid en conséquence.

    à plus

  6. #6
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour,

    Dans le help du TstringGrid:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    If all the cells in the grid fit in the ClientWidth, 
    no horizontal scrollbar appears, even if ScrollBars is ssHorizontal or ssBoth. 
    If all the cells fit in the ClientHeight, no vertical scrollbar appears, 
    even if ScrollBars is ssVertical or ssBoth.
    Je pense qu'on peut détecter la présence des scrollbar via les propriétés Controls (et ControlCount) ou Components(et componentCount) lors des modifications de la grid ou onresize de la Tstringrid.

    Si le onresize du tstringrid n'existe pas, mettre la grid en Align=Alclient dans un panel et utiliser l'event onresize du panel.

  7. #7
    Membre averti
    Inscrit en
    Octobre 2005
    Messages
    338
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 338
    Points : 383
    Points
    383
    Par défaut
    re

    Si GridHeight est inférieure à la valeur de ClientHeight, toutes les lignes de la grille apparaissent dans le contrôle ainsi qu'une zone vide en dessous de la grille
    donc à mon avis si GridHeight >(=?) ClientHeight le SclollBar doit apparaître, et ainsi tu dois pouvoir gérer ton affichage.

    à plus

  8. #8
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut

    J'ai trouvé ça comme méthode:
    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
     
    type
      TForm1 = class(TForm)
        StringGrid1: TStringGrid;
        procedure FormCreate(Sender: TObject);
      private
        { Déclarations privées }
        FSBVertVisible,
        FSBHorizVisible: Boolean;
        FOldWndProc: TWndMethod;
        procedure GridWndProc(var Message: TMessage);
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    function ScrollBarVisible(SG: TStringGrid; Code: Word): Boolean;
    var
      Min, Max: Integer;
    begin
      Result := False;
      if (SG.ScrollBars = ssBoth) or
         ((Code = SB_HORZ) and (SG.ScrollBars = ssHorizontal)) or
         ((Code = SB_VERT) and (SG.ScrollBars = ssVertical)) then
      begin
        GetScrollRange(SG.Handle, Code, Min, Max);
        Result := Min <> Max;
      end;
    end;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      FOldWndProc := StringGrid1.WindowProc;
      StringGrid1.WindowProc := GridWndProc;
    end;
     
    procedure TForm1.GridWndProc(var Message: TMessage);
    var
      Visible: Boolean;
    begin
      FOldWndProc(Message);  // Traiter le message
     
      if Message.Msg = WM_PAINT then
      begin
        Visible := ScrollBarVisible(StringGrid1, SB_VERT);
        if Visible <> FSBVertVisible then
        begin
          FSBVertVisible := Visible;
          // Actions supplémentaires...
        end;
     
        Visible := ScrollBarVisible(StringGrid1, SB_HORZ);
        if Visible <> FSBHorizVisible then
        begin
          FSBHorizVisible := Visible;
          // Actions supplémentaires...
        end;
     
      end;
    end;
    Doit pouvoir être amélioré !

    @+ Claudius.

  9. #9
    Membre éprouvé
    Avatar de Andry
    Profil pro
    Informaticien
    Inscrit en
    Juillet 2002
    Messages
    1 164
    Détails du profil
    Informations personnelles :
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : Juillet 2002
    Messages : 1 164
    Points : 1 181
    Points
    1 181
    Par défaut
    Vraiment infernale.
    En faites voila le truc



    Le scrollbar s'affiche des qu'on dépasse x lignes.
    Du coup, il y a un decalage entre la ligne de saisie et les colonnes de la grille.
    En faites, j'ai decouvert comment detecter le truc en testant le nombre de ligne de la grille, et reajuster l'emplacement des controles.

    Merci d'être penché sur mon problème

    A+

  10. #10
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 54
    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 jambonstar
    Waskol, tu t'es emporté là.

    En tout cas très belle explication.

    Par contre elle me semble Hors Sujet... . Je crois qu'il veux juste intercepter le message qui fait apparaitre la scrollbar. Pour en faire quoi, on ne le saura jamais...
    Je croyais qu'il voulait intercepter le dessin de la scrollbar pour le remplacer par son propre dessin

    La présence ou non des scrollbars n'est pas trop difficile :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if StringGrid1.ClientHeight+10<StringGrid1.Height
    then Label1.Caption:='ScrollBar Horizontale : Oui' 
    else Label1.Caption:='ScrollBar Horizontale : Non';
     
     
    if StringGrid1.ClientWidth+10<StringGrid1.Width
    then Label2.Caption:='ScrollBar Verticale : Oui' 
    else Label2.Caption:='ScrollBar Verticale : Non';
    Bref, tes contrôles d'en tête, tu dois les aligner selon les dimensions de
    StringGrid1.ClientWidth et non selon StringGrid1.Width (tu vois ce que je veux dire ??? )

  11. #11
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 54
    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
    ou alors...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    with StringGrid1 do
    begin 
      if VisibleRowCount+FixedRows<RowCount
      then Label2.Caption:='ScrollBar Verticale : Oui' 
      else Label2.Caption:='ScrollBar Verticale : Non';
    end;

  12. #12
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Citation Envoyé par waskol
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    with StringGrid1 do
    begin 
      if VisibleRowCount+FixedRows<RowCount  ...
    end;
    Ouais, j'ai l'impression de mettre compliqué la tâche avec le code que j'ai proposé !

  13. #13
    Membre émérite Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Points : 2 770
    Points
    2 770
    Par défaut
    autre méthode, pourqoi pas forcer dés le début l'affichage de scrollbar??
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
         ShowScrollBar(SGrid.Handle,SB_VERT,true);

  14. #14
    Membre éprouvé
    Avatar de Andry
    Profil pro
    Informaticien
    Inscrit en
    Juillet 2002
    Messages
    1 164
    Détails du profil
    Informations personnelles :
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : Juillet 2002
    Messages : 1 164
    Points : 1 181
    Points
    1 181
    Par défaut
    Merci pour vos conseil.
    En faites, j'ai aussi retrouvé ce code sur le net :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (GetWindowlong(Stringgrid1.Handle, GWL_STYLE) and WS_VSCROLL) <> 0 then 
      ShowMessage('Vertical scrollbar is visible!'); 
    if (GetWindowlong(Stringgrid1.Handle, GWL_STYLE) and WS_HSCROLL) <> 0 then 
      ShowMessage('Horizontal scrollbar is visible!');
    Maintenant, je vais me mettre au boulot.
    Wascol, quelle demonstration, en plus très interresant.

    Merci

Discussions similaires

  1. Réponses: 2
    Dernier message: 14/02/2008, 23h40
  2. Réponses: 13
    Dernier message: 28/01/2008, 09h27
  3. appliquer une texture sur une grille
    Par franc82 dans le forum OpenGL
    Réponses: 6
    Dernier message: 02/03/2007, 16h17
  4. Réponses: 16
    Dernier message: 10/11/2005, 22h51
  5. Afficher des images sur une grille
    Par Coussati dans le forum Composants VCL
    Réponses: 3
    Dernier message: 27/10/2005, 09h27

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