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
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
tu peut expliqué plus??
sa utilité pour vs??
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 :
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) :
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;
- 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) :
La possibilité de dessiner des morceaux de scrollbar "standard" grace à l'API DrawFrameControlSM_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);
C'est infernal, hein ?????![]()
![]()
![]()
![]()
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...
bonjour
@jambonstar
il me semble que Andry est très clair,
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.Ceci dans un souci de presentation de l'IHM de mon petit appli.
à plus
Bonjour,
Dans le help du TstringGrid:
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.
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.
Si le onresize du tstringrid n'existe pas, mettre la grid en Align=Alclient dans un panel et utiliser l'event onresize du panel.
re
donc à mon avis si GridHeight >(=?) ClientHeight le SclollBar doit apparaître, et ainsi tu dois pouvoir gérer ton affichage.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![]()
à plus
Salut
J'ai trouvé ça comme méthode:
Doit pouvoir être amélioré !
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;
@+ Claudius.
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+
Je croyais qu'il voulait intercepter le dessin de la scrollbar pour le remplacer par son propre dessinEnvoyé par jambonstar
![]()
![]()
![]()
![]()
La présence ou non des scrollbars n'est pas trop difficile:
Bref, tes contrôles d'en tête, tu dois les aligner selon les dimensions de
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';
StringGrid1.ClientWidth et non selon StringGrid1.Width (tu vois ce que je veux dire ???)
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;
Ouais, j'ai l'impression de mettre compliqué la tâche avec le code que j'ai proposé !Envoyé par waskol
![]()
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);
Merci pour vos conseil.
En faites, j'ai aussi retrouvé ce code sur le net :
Maintenant, je vais me mettre au boulot.
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!');
Wascol, quelle demonstration, en plus très interresant.
Merci
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager