Page 1 sur 1
problème relachement de la souris
Publié : sam. 13/mai/2006 23:02
par barnierchristophe
J'ai un soucis pour la détection du relachement du bouton de la souris. Je ne veux pas passer par examinemouse() parce que je ne travaille pas avec un écran. Je detecte l'appuie du bouton, ensuite je rentre dans une boucle et je veux sortir dès que le bouton est relaché. Je teste Event=#WM_LBUTTONUP. Le problème c'est que cela ne marche pas tous le temps. C'est un peu chaotique. J'ai essayé de multiplier les tests Event=#WM_LBUTTONUP dans la boucle mais cela n'a rien donné. Il y a t'il un moyen de tester l'état des boutons sans passer par examinemouse???
Publié : dim. 14/mai/2006 6:48
par Sehka
Salut Christophe,
Il y a un super Tutoriel sur la souris...
http://purebasic.hmt-forum.com/viewtopic.php?t=1310 
Publié : lun. 15/mai/2006 16:17
par barnierchristophe
Je l'ai lu mais il ne réponds pas à ma question. Peut-on connaitre la position des boutons de la souris de manière absolu, c'est à dire sans passer par les évenements appuyé relaché. Et sans passer par examinmouse().
Publié : lun. 15/mai/2006 17:06
par Gillou
Si je comprends bien, tu travailles avec une fenêtre, mais ce que je veux savoir c'est lorsque tu relaches le bouton gauche de la souris, ou est elle?
(sur ta fenêtre, en dehors, sur un gadget, sur un menu, sur la barre de titre...)
Publié : lun. 15/mai/2006 17:26
par Flype
ceci peut peut-etre t'aider :
Code : Tout sélectionner
If OpenWindow(0, 0, 0, 640, 480, "Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
If CreateGadgetList(WindowID(0))
ButtonGadget(0, 5, 5, 50, 50, "0")
ButtonGadget(1, 5, 60, 50, 50, "1")
ButtonGadget(2, 60, 5, 50, 50, "2")
ButtonGadget(3, 60, 60, 50, 50, "3")
TextGadget( 4, 5, 120,200, 20, "4", #PB_Text_Border)
EndIf
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #WM_MOUSEMOVE
hWnd = ChildWindowFromPoint_(WindowID(0), WindowMouseX(0), WindowMouseY(0))
If hWnd
SetGadgetText(4, "GadgetID(" + Str(GetDlgCtrlID_(hWnd)) + ")=" + Hex(hwnd))
EndIf
EndSelect
ForEver
EndIf
ou çà :
Code : Tout sélectionner
Define.RECT r, old
Define.l hWnd, brush
If OpenWindow(0, 0, 0, 640, 480, "Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
SetWindowColor(0, #White)
hWnd = WindowID(0)
brush = GetStockObject_(#WHITE_BRUSH)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #WM_LBUTTONDOWN
SetCapture_(hWnd)
r\left = WindowMouseX(0)
r\top = WindowMouseY(0)
Case #WM_LBUTTONUP
InvalidateRect_(hWnd, #Null, #True)
ReleaseCapture_()
Case #WM_MOUSEMOVE
If EventwParam() & #MK_LBUTTON
hDC = GetDC_(hWnd)
If hDC
r\right = WindowMouseX(0)
r\bottom = WindowMouseY(0)
FrameRect_(hDC, old, brush)
DrawFocusRect_(hDC, r)
SetRect_(old, r\left, r\top, r\right, r\bottom)
ReleaseDC_(hWnd, hDC)
EndIf
EndIf
EndSelect
ForEver
DeleteObject_(brush)
EndIf
Publié : lun. 15/mai/2006 23:16
par barnierchristophe
Le premier des deux exemples m'a été très utile; Il me permet de détecter précisement quand la souris sort d'un gadget..Merci Beaucoup
Par contre, la capture de la souris par la fenêtre ne change rien. Certains lachés de bouton m'échappent encore avec waitwindowevent...
Publié : lun. 15/mai/2006 23:59
par Le Soldat Inconnu
oui, si on relache le bouton hors de la fnêtre, on ne verra pas l'évènement.
ce qui est normal car l'évènement de la souris est renvoyé vers l'application se trouvant dessous.
Après, quand on appuie sur le bouton de la souris, on peut définir une zone dans laquelle la souris doit rester, cela oblige a l'utilisateur de relacher le bouton de la souris quand celle ci est sur la fenêtre
regarde ceci
Code : Tout sélectionner
; récupère les coordonnées de la zone du curseur
GetClipCursor_(rc_Org.RECT)
; définitions de la nouvelle zone de déplacement du curseur
rc.RECT\left = 300
rc\top = 100
rc\right = 300 + 200
rc\bottom = 100 + 200
ClipCursor_(rc)
; restaure la zone d'origine
ClipCursor_(rc_Org)
Publié : mar. 16/mai/2006 11:02
par barnierchristophe
Impeccable. C'est très utile, utilisé avec
qui donne la position absolu d'un gadget, ça permet de contraindre la souris dans le gadget.
Par contre, pour mon problème de laché de bouton, comme je fais l'examen en fin d'une boucle où il se passe pas mal de chose, j'ai été obligé d'utiliser une fonction qui vide régulierement la pile en examinant le laché, et ceci plusieurs fois dans la boucle. Quasiment, après chaque gros calcul.. Ca marche un peu près..
Voilà la procedure, elle vide la pile des evenements accumulés (pendant un calcul par exemple) et renvoie 1 si l'evenement (#WM_LBUTTONUP pour moi) est dans la pile
Code : Tout sélectionner
Procedure VidePileEvenement(Evt1.l)
Protected resultat.l,evenement.l
resultat.l=0
Debug "debut vide pile"
Repeat
evenement=WindowEvent()
Debug evenement
If evenement=Evt1
resultat=1
Debug "détection dans le vide pile"
EndIf
Until evenement=0
Debug "fin vide pile"
ProcedureReturn resultat
EndProcedure
Cette procedure est appelé plusieurs fois dans la boucle par
on examine sortie en fin de boucle...
Ca marche, mais il y a surement plus simple...
Merci une fois de plus au soldat inconnu. Tes trouvailles mon déjà été très utiles..