Page 2 sur 4

Re: #WM_centreBUTTONDOWN ?

Publié : dim. 23/août/2015 8:50
par Ollivier
Tout se résume aux entrées\sorties.

Il y a 4 états d'affichage de souris:
- un état néant (pas de prise en charge possible)
- une souris au-dessus d'un élément classique du bureau et des fenêtres de l'OS.
- une souris prise au-dessus d'un rectangle
- une souris absente (ex lors de certains glisser déposer, etc...)

Mais, il vaut mieux gérer Alt+Tab avant sur les 6 supports possibles (vous avez opengl, moi j'ai "opengl_"...) moi je n'ai que 5 supports "communicables", SPH en a 7.

Re: #WM_centreBUTTONDOWN ?

Publié : dim. 23/août/2015 21:56
par Ollivier
J'ai dit InitScreen() le plus rapide possible, c'est faux si imprécis.

Concrètement, c'est d'avoir des exécutions qui restent véloces.

Un détail modifié dans le source, [F5], et rebelote.

En 10 minutes on "tourne" vite fait autour de la tâche qu'on fait.

Re: #WM_centreBUTTONDOWN ?

Publié : mer. 26/août/2015 13:07
par SPH

Code : Tout sélectionner

Procedure CrisotMouseButton() ; Très, très sale (PB ne gère pas les Event ButtonUp ou ButtonDown)
   Repeat
      Event = WindowEvent()
      Select Event
         Case #WM_LBUTTONDOWN   ; Sale
            LMB=#True
         Case #PB_Event_LeftClick
            LMB=#False
         Case #WM_RBUTTONDOWN   ; Sale
            RMB=#True
         Case #PB_Event_RightClick
           RMB=#False
      EndSelect
   Until Event=0
EndProcedure
Je butte sur un truc. Si j'ai compris qu'il fallait mettre un "M" a WM_MBUTTONDOWN, je ne trouve pas le bon #PB_Event_???Click :

Code : Tout sélectionner

         Case #WM_MBUTTONDOWN   ; Sale
            RMB=#True
         Case #PB_Event_???Click
           RMB=#False
Avez vous une idee ? 8) :?

Re: #WM_centreBUTTONDOWN ?

Publié : mer. 26/août/2015 14:03
par Ollivier
Tu peux faire une hystérésis:

Code : Tout sélectionner

Case #WM_MButtonDown
Static SourisBoutonMilieu ; je comprends désormais la remarque de Falsam (procédure)
If SourisBoutonMilieu = 0
 SourisBoutonMilieu = 1 
 Endif

 Case #WM_MButtonUp
If SourisBoutonMilieu = 1
 SourisBoutonMilieu = 0
ClicMilieu = 1
Endif
Intégration:

Code : Tout sélectionner

If ClicMilieu
ClicMilieu = 0
; ton code
EndIf

Re: #WM_centreBUTTONDOWN ?

Publié : mer. 26/août/2015 22:03
par case
salut pour windows uniquement utilise les api systeme , je sais pas si je l'ai deja posté

Code : Tout sélectionner



; +--------------------------------------+
; |   code par case @ purebasic forums   |
; |   case[at]moonshade.org              |
; +--------------------------------------+
; |                                      |
; |     procedures  d'interrogation      |
; |              clavier                 |
; |                                      |
; +--------------------------------------+
; |                                      |
; |    PROCEDURES ET DOCUMENTATION       |
; |                                      |
; +--------------------------------------+
; |   RefreshKeyboard()                  |
; |   *****************                  |
; |   Récupere l'etat du clavier         |
; |   equivalent d'examinekeyboard()      |
; |                                      |
; |   returnchar(key)                    |
; |   ***************                    |
; |   renvoi le caractere ascii de la    |
; |   touche 'key'                       |
; |                                      |
; |   Keydown(key)                       |
; |   ************                       |
; |   renvoi 1 si la touche est enfoncee |
; |                                      |
; |   Keyup(key)                         |
; |   **********                         |
; |   renvoi 1 si la touche est relachée |
; |                                      |
; |   keypushed(key)                     |
; |   **************                     |
; |   renvoi 1 si la touche est appuyée  |
; |   mais ne l'etait pas avant          |
; |                                      |
; |   keyon(key)                         |
; |   **********                         |
; |   renvoi 1 si al touche est allumée  |
; |   numlock par exemple                |
; |                                      |
; +--------------------------------------+


InitSprite()
ExamineDesktops()
main=OpenWindow(#PB_Any,0,0,DesktopWidth(0),DesktopHeight(0),"",#PB_Window_BorderLess)
OpenWindowedScreen(WindowID(main),0,0,DesktopWidth(0),DesktopHeight(0),0,0,0)
;
;
;
;
; les deux lignes suivantes sont inutiles mais permettent de bloquer les touches menu de windows.
;
;
;
;
;
InitKeyboard()
KeyboardMode(#PB_Keyboard_International)
;+--------------------------------------+
;|           BUFFERS CLAVIER            |
;+--------------------------------------+
Global *buffer=AllocateMemory(256)
Global *state=AllocateMemory(256)
;+--------------------------------------+
;|  CONSTANTES DEFINITION DES TOUCHES   |
;+--------------------------------------+
#AltKey_windows         =91
#AltKey_Shift           =16
#AltKey_LeftShift       =160
#AltKey_RightShift      =161
#AltKey_Alt             =17
#AltKey_Left_Alt        =164
#AltKey_AltGr           =165
#AltKey_Esc             =27
#AltKey_tilde           =222
#AltKey_F1              =112
#AltKey_F2              =113
#AltKey_F3              =114
#AltKey_F4              =115
#AltKey_F5              =116
#AltKey_F6              =117
#AltKey_F7              =118
#AltKey_F8              =119
#AltKey_F9              =120
#AltKey_F10             =121
#AltKey_F11             =122
#AltKey_F12             =123
#AltKey_0               =48
#AltKey_1               =49
#AltKey_2               =50
#AltKey_3               =51
#AltKey_4               =52
#AltKey_5               =53
#AltKey_6               =54
#AltKey_7               =55
#AltKey_8               =56
#AltKey_9               =57 
#AltKey_parenthese      =219 
#AltKey_egal            =187
#AltKey_backspace       =8
#AltKey_windows         =91
#AltKey_Tab             =9
#AltKey_A               =65
#AltKey_B               =66
#AltKey_C               =67
#AltKey_D               =68
#AltKey_E               =69
#AltKey_F               =70
#AltKey_G               =71
#AltKey_H               =72
#AltKey_I               =73
#AltKey_J               =74
#AltKey_K               =75
#AltKey_L               =76
#AltKey_M               =77
#AltKey_N               =78
#AltKey_O               =79
#AltKey_P               =80
#AltKey_Q               =81
#AltKey_R               =82
#AltKey_S               =83
#AltKey_T               =84
#AltKey_U               =85
#AltKey_V               =86
#AltKey_W               =87
#AltKey_X               =88
#AltKey_Y               =89
#AltKey_Z               =90
#AltKey_circ            =221
#AltKey_dollar          =186
#AltKey_return          =13
#AltKey_caps            =20
#AltKey_percent         =192
#AltKey_multiply        =220
#AltKey_compare         =226
#AltKey_space          =32
#altKey_left           =37
#altKey_up             =38
#altKey_right          =39
#altKey_down           =40
#AltKey_del             =46
#AltKey_pageup          =33
#altKey_pagedown        =34
#altKey_fin             =35
#altKey_debut           =36
#AltKey_inser           =45
#AltKey_prtscr          =44
#AltKey_pause           =19
#AltKey_mute            =173
#AltKey_voldwn          =174
#AltKey_volup           =175
#AltKey_numlock         =144
#AltKey_0num            =96
#AltKey_1num            =97
#AltKey_2num            =98
#AltKey_3num            =99
#AltKey_4num            =100
#AltKey_5num            =101
#AltKey_6num            =102
#AltKey_7num            =103
#AltKey_8num            =104
#AltKey_9num            =105
#Altkey_minnum          =109
#Altkey_addnum          =107
#altKey_leftmouse       =1
#altKey_rightmouse      =2
#altKey_middlemouse     =4 ; pas sur que la valeur soit la meme suivant les souris a tester




Procedure RefreshKeyboard()          ;rafraichis l'etat du clavier
  CopyMemory(*buffer,*state,256)      ; sauvegarde l'etat precedent pour comparaison (keyup)
  GetKeyboardState_(*buffer)         
EndProcedure
Procedure.s returnchar(key)          ; renvoi le caractere saisi
  r.s=Space(4)
  ToAscii_(key,0,*buffer,@r,0) 
  ProcedureReturn r
EndProcedure
Procedure Keydown(key)               ; teste si une touche est enfoncée (continue)
  If PeekB(*buffer+key)<0
    ProcedureReturn 1
  EndIf
EndProcedure
Procedure keyup(key)                 ; teste si une touche est lachée
  If PeekB(*buffer+key)>=0 And PeekB(*state+key)<0
    RefreshKeyboard()                 ;rafraichis le clavier pour eviter un clic fantome
    ProcedureReturn 1
  EndIf
EndProcedure
Procedure keypushed(key)             ; teste si une touche est poussée (instant)
  If PeekB(*buffer+key)<0 And PeekB(*state+key)>=0
    RefreshKeyboard()                    ;rafraichis le clavier pour eviter un clic fantome
    ProcedureReturn 1
  EndIf
EndProcedure
Procedure keyon(key)                 ; teste si une touche  est 'on' ver maj, num lock etc...
  ProcedureReturn PeekB(*buffer+key) &%00000001;1 
EndProcedure
;
;
;
;
;
;
; exemple d'utilisation
;
;
;
;
;
;
;
Repeat
  ClearScreen(0)
  RefreshKeyboard()
  StartDrawing(ScreenOutput())
  b=0
  For y=0 To 15
    For x=0 To 15
      If Keydown(b)
        col=$0000ff
      Else
        col=$ff00ff
      EndIf
      DrawText(x*100+40,y*20,Chr(MapVirtualKeyEx_(b,2,0)),$00ff00)   
      DrawText(x*100+56,y*20,returnchar(b),$00ffff)               
      DrawText(x*100,y*20,"["+RSet(Str(b),3,"0")+"]",col)
      b+1
    Next
  Next
  If keydown(#AltKey_circ)   
    Debug returnchar(#AltKey_circ)
  EndIf
  If keyup(#AltKey_return)
    Debug "released"
  EndIf
  If keyon(#AltKey_numlock)
    Debug "numlock"
  EndIf
  If keypushed(#AltKey_return)
    Debug "touche #AltKey_return pushed "
  EndIf
  If Keydown(#AltKey_del)
    Debug "touche del down "
  EndIf
  
  
  
  StopDrawing()
  FlipBuffers()
  WaitWindowEvent(0)
Until keydown(#AltKey_Esc)

Re: #WM_centreBUTTONDOWN ?

Publié : ven. 28/août/2015 14:08
par crisot
Pour répondre (simplement) aux besoins de SPH.

Code : Tout sélectionner

Global LMB, RMB, MMB

; Attention, flush tous les WindowEvent()

Procedure CrisotMouseButton()
	Repeat
		Event = WindowEvent()
		Select Event
			Case #WM_LBUTTONDOWN			; API Windows
				LMB=#True
			Case #PB_Event_LeftClick	; bricolage - #WM_LBUTTONUP plante
				LMB=#False
			Case #WM_RBUTTONDOWN			; API Windows
				RMB=#True
			Case #PB_Event_RightClick	; bricolage - #WM_RBUTTONUP plante
				RMB=#False
			Case #WM_MBUTTONDOWN			; API Windows
				MMB=#True
			Case #WM_MBUTTONUP			; API Windows
				MMB=#False
		EndSelect
	Until Event=0
EndProcedure

; Serait plus propre avec une seule procédure et un argument

Procedure CrisotLeftMouseButton()	
	CrisotMouseButton()
	ProcedureReturn LMB
EndProcedure

Procedure CrisotRightMouseButton()
	CrisotMouseButton()
	ProcedureReturn RMB
EndProcedure

Procedure CrisotMiddleMouseButton()
	CrisotMouseButton()
	ProcedureReturn MMB
EndProcedure

Re: #WM_centreBUTTONDOWN ?

Publié : ven. 28/août/2015 17:02
par SPH
Merci Crisot, ca maaaarche 8)

J'ai meme pu enlever le InitMouse :P

Re: #WM_centreBUTTONDOWN ?

Publié : ven. 28/août/2015 21:03
par crisot
Spock a écrit :
crisot a écrit :Pour répondre (simplement) aux besoins de SPH. ......................................#WM_LBUTTONUP plante
ha bah si ton code plante, c'est sur que c'est plus simple :mrgreen:
Ahah non c'est plutôt que techniquement pour être propre j'aurais du utiliser deux messages (#WM_LBUTTONUP et #WM_RBUTTONUP) qui par le plus grand des mystères ne fonctionnent pas voir plantent le soft. :mrgreen:

Du coup... workaround, workaround... :)

Re: #WM_centreBUTTONDOWN ?

Publié : mar. 01/sept./2015 20:29
par Flype
Avec WindowEvent() dans une boucle, il est préférable de mettre un Delay(1 ou plus) sinon c'est comme rouler à 100km/h en 3ème, c'est pas très Green :mrgreen: et ton CPU il est pas content.

Re: #WM_centreBUTTONDOWN ?

Publié : mar. 01/sept./2015 21:48
par Patrick88
d'ou le canvasgadget bien pratique ou openglgadget qui ont leur propre event souris et clavier... manque plus qu'un ogregadget ou un screengadget :roll:

Re: #WM_centreBUTTONDOWN ?

Publié : mer. 02/sept./2015 0:07
par Ollivier
Patrick88 a écrit :d'ou le canvasgadget bien pratique ou openglgadget qui ont leur propre event souris et clavier... manque plus qu'un ogregadget ou un screengadget :roll:
L'idée portant intérêt, j'ai créé le sujet dans la section 'Suggestion'.

Re: #WM_centreBUTTONDOWN ?

Publié : jeu. 03/sept./2015 0:37
par crisot
Flype a écrit :Avec WindowEvent() dans une boucle, il est préférable de mettre un Delay(1 ou plus) sinon c'est comme rouler à 100km/h en 3ème, c'est pas très Green :mrgreen: et ton CPU il est pas content.
Hein? Quel rapport? (me répond pas "3ème" :mrgreen: )

Depuis quand on ralenti du code, n'importe quel code doit être executée le plus vite possible, mettre un delay() dans une boucle qui flush les WindowsEvent() n'a pas plus de sens que mettre un delay() dans une boucle for/next - while/wend - repeat/until comme une autre...

Et on flush TOUJOURS les WindowsEvent() dans une boucle, il peut arriver plusieurs event dans une même frame.

Re: #WM_centreBUTTONDOWN ?

Publié : jeu. 03/sept./2015 16:14
par Ollivier
Bonjour Crisot,

En fait l'alchimie interne, c'est à peu près :
WaitWindowEvent == Delay ++ WindowEvent

Le multi-tâche engendre des contraintes, notamment partager la main. C'est plutôt bon signe de pouvoir choisir à quel moment dans le code on rend la main. C'est synonyme de fiabilité. Et si tu ne rend pas la main à temps (qque secondes), l'OS te la prend d'office et là tu ne contrôle plus rien, dans le sens où tu ne sais pas à quel endroit l'OS a interrompu ton processus pour s'occuper des autres tâches. Dans ce même cas, tu ne sais pas non plus quand il va te la rendre.

Alors que si tu lui donnes un peu de temps très régulièrement, l'OS peut analyser à 100% les différents rythmes de tâche et rendre équitablement la main à chacune d'entre elles, dont la tienne.

Re: #WM_centreBUTTONDOWN ?

Publié : jeu. 03/sept./2015 17:15
par SPH
Crisot n'est pas la pour 10 jours. :idea:

Bon, vous etes en train de me dire qu'un delay() est obligatoire, c'est ca ? (c'est pour mon jeu) :?:

Re: #WM_centreBUTTONDOWN ?

Publié : ven. 04/sept./2015 1:00
par crisot
Les gars... Vous avez bien conscience que cette boucle qui gère les événements n'est pas exécutée indéfiniment le plus vite possible dans une boucle infinie sans rien à côté. Auquel cas, effectivement, ça chargerait le CPU à 100%, comme n'importe quelle boucle critique dans laquelle on cherche à tout sauf à mettre un wait.

Le flush des WindowsEvent() se fait intégralement (d'où la boucle), le plus rapidement possible (comme n'importe quel bout de code), mais un nombre de fois limité.

Dans le code que j'ai donné ci dessus pour le jeu de SPH, cette boucle est exécutée sur appel d'une procédure qui n'est appelée que ponctuellement pour tester le clic souris (bidouillage, ok).

Dans le cadre d'un code monothreadé, on peut aussi l'appeler à chaque frame graphique, donc généralement 60x par secondes, "à peu prêt exactement" 0% de charge CPU.

Pour utiliser WaitWindowsEvent(), il faudra threader la chose afin de ne pas bloquer en l'absence d'événement. Sans doute le plus "pro", mais largement dispensable pour une appli simple. Perso, j'utilise beaucoup plus couramment la solution précédente.

Je réponds donc maintenant à vos remarques sur cette base:
lance ton code, et regarde le temp machine pris (control+alt+Del ) par ton prg ....
En fait mon code n'est pas vraiment lançable puisqu'il n'y a pas de boucle principale.
En pratique sur HexaScrabble pour lequel j'ai bidouillé cette procédure j'ai 19% de charge CPU, parce qu'il faut bien qu'HexaScrabble tourne.
La version originale de HexaScrabble qui utilises les fonctions natives de PB consomme les mêmes 19% de CPU (mais les souris Razer déconnent, bug PB).
Ma procédure n'engendre donc pas de charge supplémentaire.

Bref: 0% :)
Spock a écrit : ensuite met un delay(2) ou WaitWindowsEvent(2) et regarde la difference ;)
->avec delay(2), plus ma procédure est appelée souvent, plus la charge CPU baisse.... plus le temps disponible pour mon programme est faible, plus celui-ci devient lent.
Bref, j'obtiens un code peu performant avec une charge CPU proche de 0%. :mrgreen:

->avec un WaitWindowsEvent(), le code arrête purement et simplement de s'exécuter tant que je ne touche pas ma souris. Pratique.
Spock a écrit : pis parle français , j'ai pas compris ton "Et on flush"
"Vidange". Pourtant très courant dans le jargon de codeur...
Ollivier a écrit : Le multi-tâche engendre des contraintes, notamment partager la main.
Les opérations GPU, un accès ram, disque, la synchro verticale (etc...) sont des moments où la main se rend naturellement. Au sein même du CPU certaines instructions chargeront plus ou moins le CPU. Au pire si notre application est extrêmement "CPU intensive" on baissera à peine la priorité de notre thread et on laissera l'Os faire. Bref, le multitasking, c'est son problème. :wink: