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 :wink:

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

Code : Tout sélectionner

GetWindowRect_(GadgetID(2),Rect2.rect) 
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

Code : Tout sélectionner

                    If VidePileEvenement(#WM_LBUTTONUP):sortie=1:EndIf
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..