#WM_centreBUTTONDOWN ?

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: #WM_centreBUTTONDOWN ?

Message 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.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: #WM_centreBUTTONDOWN ?

Message 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.
Avatar de l’utilisateur
SPH
Messages : 4947
Inscription : mer. 09/nov./2005 9:53

Re: #WM_centreBUTTONDOWN ?

Message 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) :?

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: #WM_centreBUTTONDOWN ?

Message 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
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

Re: #WM_centreBUTTONDOWN ?

Message 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)
ImageImage
crisot
Messages : 98
Inscription : lun. 30/août/2004 21:03

Re: #WM_centreBUTTONDOWN ?

Message 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
Avatar de l’utilisateur
SPH
Messages : 4947
Inscription : mer. 09/nov./2005 9:53

Re: #WM_centreBUTTONDOWN ?

Message par SPH »

Merci Crisot, ca maaaarche 8)

J'ai meme pu enlever le InitMouse :P

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
crisot
Messages : 98
Inscription : lun. 30/août/2004 21:03

Re: #WM_centreBUTTONDOWN ?

Message 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... :)
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Re: #WM_centreBUTTONDOWN ?

Message 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.
Image
Patrick88
Messages : 1564
Inscription : mer. 21/janv./2004 18:24

Re: #WM_centreBUTTONDOWN ?

Message 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:
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: #WM_centreBUTTONDOWN ?

Message 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'.
crisot
Messages : 98
Inscription : lun. 30/août/2004 21:03

Re: #WM_centreBUTTONDOWN ?

Message 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.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: #WM_centreBUTTONDOWN ?

Message 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.
Avatar de l’utilisateur
SPH
Messages : 4947
Inscription : mer. 09/nov./2005 9:53

Re: #WM_centreBUTTONDOWN ?

Message 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) :?:

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
crisot
Messages : 98
Inscription : lun. 30/août/2004 21:03

Re: #WM_centreBUTTONDOWN ?

Message 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:
Répondre