Bonjour,
Je cherche a utiliser le défilement vertical d'un scrollbox avec la molette de la souris, mais je n'ai rien trouvé.
Quelqu'un aurait une solution svp ?
Merci.
Version imprimable
Bonjour,
Je cherche a utiliser le défilement vertical d'un scrollbox avec la molette de la souris, mais je n'ai rien trouvé.
Quelqu'un aurait une solution svp ?
Merci.
Le contrôle qui reçoit le MouseWeel est celui qui a le focus. Quel est le composant qui a le focus lorsque tu testes ?
je ne sais pas le scrollbox je suppose,
je souhaite faire défiler le srollbox verticalement a l'aide du scroll de la souris, mais je ne sais pas comment m'y prendre.
Non, pas d'idée ???
Il me faudrait juste obtenir les infos de la souris le "position" ou "delta wheel".
Si qqu'un connait ça ....
Merci.
Salut !
En fait, il y a peut-être une solution qui consisterait à intercepter les messages dédiés au scrolling d'une fenêtre.
Il s'agit probablement de WM_HSCROLL et WM_VSCROLL.
Dans ce cas, ça pourrait se faire en modifiant la gestion des messages au niveau du gestionnaire ad-hoc de TForm.
Code:
1
2
3
4
5
6
7
8
9 protected: void __fastcall WMHScroll(TMessage &Message); void __fastcall WMVScroll(TMessage &Message); BEGIN_MESSAGE_MAP MESSAGE_HANDLER(WM_HSCROLL, TMessage, WMHScroll) MESSAGE_HANDLER(WM_VSCROLL, TMessage, WMVScroll) END_MESSAGE_MAP(TForm)
TODO ... ici je ne sais pas quelle serait la meilleure option !Code:
1
2
3
4
5
6
7
8
9 void __fastcall TForm1::WMHScroll(TMessage &Message) { // TODO... } void __fastcall TForm1::WMVScroll(TMessage &Message) { // TODO... }
A plus !
Merci pour ce code ,mais j'ai beau le tourner dans tous les sens je n'arrive a rien avec...
est ce bien du c++ ???
Ce ne serais pas du delphi plutot ?
Je ne suis pas un expert en prog alors si quelqu'un aurais une solution en C++ merci.
Je ne comprend pas pourquoi je n'arrive pas a trouver d'exemple, personne n'a fait ça auparavant ?
Pourtant ça devrais être quelque chose de logique et de facile de pouvoir bouger le scrollbox avec la roulette de la souris, c'est prévu pour, non ?
J'en déduit donc que personne n'a utilisé le défilement des ScroolBar d'un ScroolBox avec la roulette de la souris.
Ou même juste la roulette de la souris.
Dommage .... :? :cry::cry:
Hello,
Tu peux rajouter un composant TApplicationEvents sur ta fiche, et mettre sur le OnMessage:Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 void __fastcall TForm26::vAppEv1Message(tagMSG &Msg, bool &Handled) { if (Msg.hwnd == scrlbx1->Handle) // scrlbx1: Un TScrollBox par exemple { switch (Msg.message) { case WM_VSCROLL: // TODO... Caption = IntToHex((int)Msg.message, 8); break; case WM_HSCROLL: // TODO... Caption = IntToHex((int)Msg.message, 8); break; } } }
OK merci je vais essayer d'exploiter cette piste, merci.
Je vous tiens au courant.
@+
Salut, j'ai beau tourner le code dans tous les sens je n'y arrive toujours pas ...
Il me faudrais dans un premier temps obtenir le WheelDelta je pense mais je n'arrive pas a le récupérer.
Alors si quelqu'un a une solution, je suis preneur.
Merci
Hello,
Sous Builder 6 et 2007 au moins, le TScrollBox te gère la molette sans à avoir à rien faire d'autre, dans la mesure où les contrôles ajoutés dans le TScrollBox n'interceptent pas eux-mêmes les événements souris...
Par exemple, si le TScrollBox contient un TStringGrid, tu récupères les événements de la molette lorsque la souris est sur le fond du TScrollBox, mais pas lorsqu'elle est au dessus du TStringGrid...
Est-ce que c'est ça ton problème ? Qu'est ce que tu utilises comme contrôles ?
Salut totoche76 et merci de te pencher sur mon cas parce que je galère depuis un bon bout de temps, alors je t'explique:
J'ai une fenetre de taille fixe dans laquelle j'ai divers éléments (groupbox, images, etc) tout ça dans un ScrollBox afin de faire défiler le contenu lorsque ça ne tiens plus dans une parti de la fenetre.
donc je souhaiterais récuperer les infos de la roulette de la souris afin de faire défiler mon scrollBox (j'avais mis un ScrollBox pensant que ca ce gérait tout seul, a tord malheureusement).
J'ai essayé différentes choses que l'on m'a proposé au dessus mais je n'y arrive pas.
Donc j'attend impatiemment tes lumières stp.
Merci d'avance.
Info: je suis sous Code GearC++ Builder 2007
Hello,
2 méthodes:
- Sous classement de fenêtre
Exemple, sur un TForm, avec.cpp:Code:
1
2
3 TScrollBox *vScrlbx1; TStringGrid *vGrd1; TButton *vBtn1;
A toi de rajouter autant de SetWindowLong(...) que tu as de contrôles qui intercèptent la moletteCode:
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 #ifdef STRICT #define MYWNDPROC WNDPROC #else #define MYWNDPROC FARPROC #endif MYWNDPROC wpOrigWndProc = NULL; LRESULT APIENTRY WndProcScroll(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_VSCROLL || uMsg == WM_HSCROLL) { PostMessage(Form32->vScrlbx1->Handle, uMsg, wParam, lParam); return 0; } return CallWindowProc(wpOrigWndProc, hwnd, uMsg, wParam, lParam); } __fastcall TForm32::TForm32(TComponent* Owner) : TForm(Owner) { vBtn1Click(NULL); } __fastcall TForm32::~TForm32(void) { if (wpOrigWndProc != NULL) SetWindowLong(vGrd1->Handle, GWL_WNDPROC, (LONG)wpOrigWndProc); } void __fastcall TForm32::vBtn1Click(TObject *Sender) { if (wpOrigWndProc == NULL) { wpOrigWndProc = (MYWNDPROC)SetWindowLong(vGrd1->Handle, GWL_WNDPROC, (LONG)WndProcScroll); vBtn1->Caption = "ON"; } else { SetWindowLong(vGrd1->Handle, GWL_WNDPROC, (LONG)wpOrigWndProc); wpOrigWndProc = NULL; vBtn1->Caption = "OFF"; } }
- un Hook (SetWindowsHookEx), soit sur WH_GETMESSAGE en interceptant WM_VSCROLL et WM_HSCROLL, soit sur WH_MOUSE
Exemple:Code:
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 HHOOK hookGetMsg = NULL; LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode == HC_ACTION) { MSG* pCWP = (MSG*)lParam; if (pCWP->message == WM_VSCROLL || pCWP->message == WM_HSCROLL) if (pCWP->hwnd == Form32->vGrd1->Handle) PostMessage(Form32->vScrlbx1->Handle, pCWP->message, pCWP->wParam, pCWP->lParam); } return CallNextHookEx(hookGetMsg, nCode, wParam, lParam); } // Fin de MouseProc void __fastcall TForm32::vBtn2Click(TObject *Sender) { if (hookGetMsg == NULL) { hookGetMsg = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, 0, GetCurrentThreadId()); vBtn2->Caption = "ON"; } else { UnhookWindowsHookEx(hookGetMsg); hookGetMsg = NULL; vBtn2->Caption = "OFF"; } }
Bon OK ,je vais essayer d'adapter ça a mon code et je te dis je qu'il en ait parceque là comme ça, :? ça ne me parle pas trop, je suis plutôt novice en prog.
Je te remercie et je te tiens au courant .
@+
J'ai essayé d'adapter la solution 2 (le HOOK) qui me semblait plus simple comme suit :
j'ai tout mis dans le .ccpCode:
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 HHOOK hookGetMsg = NULL; // LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode == HC_ACTION) { MSG* pCWP = (MSG*)lParam; if (pCWP->message == WM_VSCROLL || pCWP->message == WM_HSCROLL) if (pCWP->hwnd == Form1->ScrollBox1->Handle) PostMessage(Form1->ScrollBox1->Handle, pCWP->message, pCWP->wParam, pCWP->lParam); } return CallNextHookEx(hookGetMsg, nCode, wParam, lParam); } // Fin de MouseProc void __fastcall TForm1::vBtn2Click(TObject *Sender) { if (hookGetMsg == NULL) { hookGetMsg = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, 0, GetCurrentThreadId()); this->Button1->Caption="ON"; // vBtn2->Caption = "ON"; } else { UnhookWindowsHookEx(hookGetMsg); hookGetMsg = NULL; this->Button1->Caption="OFF";// vBtn2->Caption = "OFF"; } }
je n'ai pas de défaut à la compilation mais il semble que le code n'est pas "opérationel" car j'ai mis des point d'arrêt et rien ne se passe lorsque je bouge la roulette de la souris ...
Un idée ?
il ne me manque pas un .h ou autre ?
Merci
L'idée du machin: si le message arrive sur un des contrôles contenus dans le scrollbox, le rediriger vers le scrollbox. Donc il faut tester les handles des contrôles qui sont à l'intérieur du scrollbox.Code:
1
2 if (pCWP->hwnd == Form1->ScrollBox1->Handle) PostMessage(Form1->ScrollBox1->Handle, pCWP->message, pCWP->wParam, pCWP->lParam);
Là tu ne rediriges rien...
Ah, pas sur d'avoir bien compris mais si je suis sur le scrollbox ça devrais fonctionner, non?
j'ai essayé çapour voir si ça fonctionnait sur la Form directement, mais non, pas mieux.Code:
1
2 if (pCWP->hwnd == Form1->ScrollBox1->Handle||Form1->Handle||Form1->ListBox1->Handle) PostMessage(Form1->ScrollBox1->Handle, pCWP->message, pCWP->wParam, pCWP->lParam);
Le problème que je vais avoir c'est que le contenu du scrollbox est généré aprés la construction et est variable( ce sont des Classes dérivés de TImage dans des Classes dérivées de TGroupbox)
Mais bon ce que je ne comprends pas c'est que ça ne fonctionne pas lorsque ma souris est directement placée sur le Scrollbox.
Une idée ?
:?Code:
1
2
3 if ((pCWP->hwnd == Form1->ScrollBox1->Handle) || (pCWP->hwnd == Form1->Handle) || (pCWP->hwnd == Form1->ListBox1->Handle))
Je pensait que c'était la même chose.
Enfin le résultat lui est le même car j'ai beau bouger la roulette de la souris sur tout les coins de ma Form du Scrollbox ou autre le programme ne s'arrête jamais sur le point d'arrêt sur le ifaurais-tu une idée.Code:
1
2
3 if ((pCWP->hwnd == Form1->ScrollBox1->Handle ) || (pCWP->hwnd == Form1->Handle) || (pCWP->hwnd == Form1->ListBox1->Handle))
Merci pour ton exemple totoche76 mais il utilise un TstringGrid qui gère tout seul le scroll de la souris.
En dehors du TStringGrid le ScrollMouse ne fonctionne pas.
Ou alors je ne sais pas l'utiliser.:roll:
Alors si tu as autre chose...:cry:
Me voila de retour après tout ce temps.
Mon programme est aujourd'hui quasi terminé a l’exception de se fichu scrollbox que je n'arrive toujours pas a gérer.
Je l'avait donc mis de côté mais maintenant que tout le reste est finit j'aimerais bien le faire fonctionner.
Alors si quelqu'un sait le faire fonctionner serait il possible de me donner un exemple afin que je l'étudie et l’adapte a mon prog. SVP
Je rechercher juste un une form contenant un scrollbox avec une image ou autre qui soit plus grand verticalement afin d'utiliser la molette de la souris pour faire défiler l'image( ou l'autre chose que l'on a mis dans le scrollbox).
Si quelqu'un sait gérer ça j’attends avec grande impatience se petit projet.
Un grand MERCI d'avance a cette âme charitable.
J-M.
Je ne suis pas sûr d'avoir compris, mais en utilisant les événement OnMouseWheelDown et OnMouseWheelUp ca ne marche pas? Il faut que le composant ScrollBox ai le Focus (ScrollBox1->SetFocus() ; ):
Code:
1
2
3
4
5
6 void __fastcall TForm1::ScrollBox1MouseWheelDown(TObject *Sender, TShiftState Shift, TPoint &MousePos, bool &Handled) { ScrollBox1->VertScrollBar->Position += 25; }
Code:
1
2
3
4
5 void __fastcall TFRequest::ScrollBox1MouseWheelUp(TObject *Sender, TShiftState Shift, TPoint &MousePos, bool &Handled) { ScrollBox1->VertScrollBar->Position -= 25; }
Dans un ScrollBox, je générais une série d'Edit généré à la volée, idem pas de molette, j'avais fini par utiliser un TDBCtrlGrid avec la gestion manuelle de la roulette
Pour TScrollBox, on dirait que WM_MOUSEWHEEL n'ai jamais provoqué par Windows pour ce control ! Etrange !
En C++Builder 2007, j'ai aussi des ScrollBox contenant des Panels, il n'y a rien à faire, même en cliquant dans la zone client (hors d'un controle) ou sur la Barre, la molette ne fonctionne JAMAIS, aucun OnMouseWheel, OnMouseWheelDown ou OnMouseWheelUp ne se produit !
D'ailleurs, cela ne fonctionne pas non plus pour une Form ayant des barres ou une Zone Client MDI !
@sat83 ! :ccool:
Il est dommage que le clic dans un ScrollBox n'affecte pas le Focus !
Mais ta remarque est pertinente, enfin le WM_MOUSEWHEEL survient et donc OnMouseWheel !
Par contre, le OnClick ou OnMouseEnter ne se produit pas si l'on survole la ScrollBar, on ne peut donc pas s'auto attribuer le Focus !
C'est en tout cas, une solution simple, juste SetFocus dans le OnClick du TScrollBox qui s'attribue lui-même le Focus pour gérer la souris !
C'est tout de même un peu con !
Je n'ai jamais eu de soucis avec le molette souris sur un ScrollBox...
Pour forcer le Focus lorsque l'on survole le ScrollBox, éventuellement forcer le Focus dans le OnMouseMove:
Je viens de tester chez moi (BCB5) ça fonctionne.Code:
1
2
3
4
5
6 void __fastcall TForm1::ScrollBox1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { ScrollBox1->SetFocus() ; }
Oui, c'est ce que j'ai fait OnMouseMove par contre ne se déclenche pas si l'on survole la ScrollBar de la ScrollBox !
Tu as du toujours du mettre des TEdit ou autre control sans Scroll mais pouvant prendre le Focus !Citation:
Je n'ai jamais eu de soucis avec le molette souris sur un ScrollBox...
Car si l'on met un TEdit dans un Panel lui même dans un ScrollBox
Si l'on clique sur le Panel, pas de OnMouseWheel
Si l'on clique sur le TEdit, le OnMouseWheel devient dispo !
hors la c'est l'un des rares cas, où ce la ne fonctionne pas le TImage qui ne prend pas le Focus et donc le ScrollBox non plus !
Moi, j'avais eu le problème car je n'avais que des Labels et Image et TEdit, cela fonctionne, car par reflexe on clique dans l'edit, mais en cliquant sur le TImage (cela provoquait un Dialog), pas de Scroll
jeanmichmuch66, tu as donc une solution, dans le OnClick de l'Image, tu fais un ScrollBox->SetFocus et cela activera la molette !
Je suis désolé, j'ai beau essayer je n'y arrive pas.
j'ai donc fait un "projet" avec dans une form, un Scrollbox dans lequel on trouve un TImage (plus grand que le Scrollbox) j'y ai donc rajouté le code que vous m'avez donné, mais rien n'y fait.
Je n'arrive pas a faire bouger le scrollbox.
Je vous joint donc ce projet afin que vous puissez me dire ou je faute, svp.
Je doit oublier un détail qui me bloque.
Si vous trouvez la raison ou si vous débuggez mon "projet" merci de me dire ou je faute .
Un grand merci d'avance.
Tu as oublié la DFM, c'est con non !
Sinon, tu n'as pas compris que le SetFocus c'était pour que l'on puisse obtenir des OnMouseWheel, OnMouseWheelDown ou OnMouseWheelUp pour qu'ensuite on puisse gérer la molette et modifier la position dans la ScrollBox !
C'est à toi de gérer le défilement !Code:
1
2
3
4
5
6
7 //--------------------------------------------------------------------------- void __fastcall TForm1::ScrollBox1MouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta, TPoint &MousePos, bool &Handled) { ScrollBox1->VertScrollBar->Position -= (WheelDelta / 60); }
En même temps, si tu ne lit pas nos réponses, on perd du temps !
WheelDelta vaut souvent 120 ou -120, il me semble que cela correspond à 12° (le cran par défaut de la plupart des souris)
A toi, de trouver la vitesse de défilement qui te convient
Salut jeanmichmuch66
La methode ScrollBox1MouseWheel ne fonctionne pas seul il faut donner le focus a la ScrollBox, le moyen est de passer par le MouseMove du TImage
Code:
1
2
3
4
5
6
7
8
9
10
11
12 void __fastcall TForm1::ScrollBox1MouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta, TPoint &MousePos, bool &Handled) { ScrollBox1->VertScrollBar->Position -= (WheelDelta); } //--------------------------------------------------------------------------- void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { ScrollBox1->SetFocus(); }
Toutes mes plates excuses il est vrai que j'avais survolé la réponse que j'avais en fait déjà utilisé auparavant mais n'ayant pas le Focus du Scrollbox ne fonctionnait pas.
J'avais fini par pensait que ça marchait tout seul quand on me disait il n'y a rien a faire ça marche tout seul ... tu donnes juste le focus ... :(
Je vous remercie grandement pour votre aide. :lol:
Il est vrai qu'avec la réponse maintenant ça semble évident.
Enfin bref , j'ai donc intégrer la fonction dans mon programme au bon endroit.
Car je crée des images de façon dynamiques (quantité variable) j'ajoute le mousemove avec le focus sur le scrollbox a la création des images et le tour est joué !!!! :ccool:
Encore un grand MERCI a tous ceux qui mon aidé avec patience;)