Comment détecter si un jeu externe est lancé ?

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Comment détecter si un jeu externe est lancé ?

Message par Fig »

Ar-S a écrit :En effet ça fonctionne par contre dans la boucle (de moa radio) ça génère un lag de fou. Surement du au GetPixel_ en boucle.
Dites, les hommes, peut être que je dis une bêtise, mais de mon expérience récente, si on utilise GetPixel_, il faut utiliser ReleaseDC après, sinon, vous allez droit au plantage dans un temps proportionnel à la quantité de mémoire disponible.(si la nature vous a bien doté, ça peut durer une bonne 30ène de minutes)
La fonction getpixel_ prend quand même 20ms chez moi, je ne sais pas pourquoi c'est si lent... (c'est une constante quand on utilise les fonctions de l'Api ?)

Pour info, si ça fonctionne, ReleaseDC retourne la valeur de 1.
Dernière modification par Fig le ven. 06/déc./2013 18:02, modifié 1 fois.
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Comment détecter si un jeu externe est lancé ?

Message par Backup »

Exacte !!

je viens de modifier mon code ci dessus , dans ce sens , merci :)


Ajout de la detection lorsqu'on quitte le plein ecran ... :)
beep grave 440 on entre en plein ecran

Beep aigue on a quitté le plein ecran !
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Comment détecter si un jeu externe est lancé ?

Message par Ar-S »

Pour la detection je capture 2 pixels précise de mon interface, ça marche nikel.
La désactivation de l'OWScreen se fait des que les 2 couleurs de pixel ne correspondent plus et elle se redessine bien si la fenêtre de la radio réapparait. En revanche, l'anim se fige des que la fenêtre n'a plus le focus, même si visible et se réanime des qu'elle reprend le focus. Vraiment etrange.

Voilà la proce dans mon timer (toutes les secondes)

Code : Tout sélectionner

Procedure CheckRecouvre()

	PosX	=	WindowX(#LDVM)
	PosY	=	WindowY(#LDVM)

	If Pxlcolor(PosX + 347, posY + 4) <> RGB(240,240,240) And Pxlcolor(PosX + 11, posY + 78) <> RGB(0,219,0)
		If creation = 0
			DestroySPRITE()
			Creation = 1 ; Pour ne pas refermer la fenêtre vu qu'elle est déjà fermée
		EndIf
		Debug "PLUS DEVANT"
	Else
		If Creation = 1
			CreaSPRITES(Creation)
			Creation = 0 ; Pour ne pas recréer la fenêtre et les sprites vu qu'ils sont crées
			SetActiveWindow(#ldvm)
		EndIf
		Debug "DEVANT"	
	EndIf
	
	ProcedureReturn Creation
	
EndProcedure	
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Comment détecter si un jeu externe est lancé ?

Message par Backup »

Ar-S a écrit :En revanche, l'anim se fige des que la fenêtre n'a plus le focus, même si visible et se réanime des qu'elle reprend le focus. Vraiment etrange.

Voilà la proce dans mon timer (toutes les secondes)

je parie que tu as utilisé la fonction Timer de Purebasic !! ;)

le probleme c'est que cette fonction comme son nom l'indique (AddWindowTimer(#Fenetre, Minuteur, Temps)) est lié aux Event de la fenetre du prg !! via (EventTimer() )


utilise cette procedure (Version API ) independante des Events :
ici pour 3 timers.... mais suprime en 2 ;)

Code : Tout sélectionner

Declare TimerProc(hwnd.l, uMsg.l, idEvent.l, dwTime.l)

Enumeration
	#timer_1
	#timer_2
	#timer_3
EndEnumeration

If OpenWindow(0, 100, 100, 100, 100,"", #PB_Window_SystemMenu|#PB_Window_SizeGadget)
	Handle = WindowID(0)
	
	SetTimer_(Handle, #timer_1, 1000, @TimerProc()) ; envoie un evenement toutes les 1000 millisecondes ; en fait on prepare un timer qui enverra cette evenement
	SetTimer_(Handle, #timer_2, 200, @TimerProc())  ; envoie un evenement toutes les 200 millisecondes ; en fait on prepare un timer qui enverra cette evenement
	SetTimer_(Handle, #timer_3, 3000, @TimerProc())  ; envoie un evenement toutes les 3000 millisecondes ; en fait on prepare un timer qui enverra cette evenement
	
	Repeat
	Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf 



; cette procedure contient les actions a effectuer des  3 timers
Procedure TimerProc(hwnd.l, uMsg.l, idEvent.l, dwTime.l)
	Select uMsg
		Case #WM_TIMER
		Select idEvent
			Case  #timer_1
			Debug "--------------------1 seconde"
			; Ici, le code à executer toutes les secondes
			beep_(440,100)
			Case  #timer_2
			Debug "0.2 secondes"
			; Ici, le code à executer toutes les 200 millisecondes
			Case #timer_3
			Debug "-------------------------------------------3 secondes"
			
			; Ici, le code à executer toutes les 3 secondes
		EndSelect
	EndSelect
EndProcedure




; EPB

sinon , j'y pense tu aurai pas merdouillé le WaitWindowEvent() ?? t'a mis un minuteur "WaitWindowEvent(20)" ??

parceque perso , j'ai enormement de prg qui tourne en Arriere plan fait en purebasic , et qui fonctionnent

(PureAniv, Horloge , Pure_Alerte , SpyPseudo ,etc .... )
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Comment détecter si un jeu externe est lancé ?

Message par Ar-S »

Yop,

J'ai pas testé ton code API car j'ai réussi avec le timer PB :)
De la grosse balle.

Voilà un exemple concret.
Tout roule ! :mrgreen:

je l'ai adapté à l'oscillo de la radio, ça marche nikel.
Je vais la mettre à jour (0.6.4) d'ici peu

Code : Tout sélectionner

; Activer / desactiver fenêtre OpenWindowScreen() selon que la fenêtre soit visible ou pas.
; Ar-S - PB 5.21 LTS x86


Enumeration
	#LDVM
	#SP
	#T
EndEnumeration

InitSprite()

Declare CheckRecouvre()
Declare Pxlcolor(X,Y) 
Declare CreaOWS()
Declare DestroyOWS()
Declare CreaSPRITE()

Global X
Global.b Creation


Procedure Pxlcolor(X,Y) 
	; by Dobro
	handle=GetDC_(GetDesktopWindow_()) 
	couleur=GetPixel_(handle,X,Y) 
	ReleaseDC_(GetDesktopWindow_(),handle ) 
	ProcedureReturn couleur 
EndProcedure  

Procedure CheckRecouvre()

		PosX   =   WindowX(#LDVM)
		PosY   =   WindowY(#LDVM)
		
		; Capture d'un pixel du GUI
		If Pxlcolor(PosX + 5, posY + 40) <> RGB(240,240,240)

				If creation = 0
						DestroyOWS()
						Creation = 1 ; Pour ne pas refermer la fenêtre vu qu'elle est déjà fermée
				EndIf
				Debug "CACHE"
		Else
				If Creation = 1
						CreaOWS()
						CreaSPRITE()
						Creation = 0 ; Pour ne pas recréer la fenêtre et les sprites vu qu'ils sont crées
						SetActiveWindow(#ldvm)
				EndIf
				
				Debug "VISIBLE"   
		EndIf
		
		ProcedureReturn Creation
		
EndProcedure   


Procedure CreaSPRITE()

CreateSprite(#SP, 5, 5)
StartDrawing( SpriteOutput(#SP) )
	Box(0,0,5,5,#Green)
StopDrawing()


EndProcedure


Procedure DestroyOWS()
	CloseScreen()
EndProcedure


Procedure CreaOWS()
	OpenWindowedScreen(WindowID(#LDVM),5,5,40,40)
EndProcedure


Procedure MoveSPRITE()
If Creation = 0

	DisplaySprite(#Sp, X, 10)
	X + 1
	If X > 55
		X = -5
	EndIf
	
	FlipBuffers()
	ClearScreen(RGB(0,0,0))

EndIf

EndProcedure



If OpenWindow(#LDVM, 5,5, 50, 50, "test", #PB_Window_SystemMenu| #PB_Window_ScreenCentered)
StickyWindow(#LDVm,1)

	
	CreaOWS()
	CreaSPRITE()
	Creation = 0
	
	AddWindowTimer(#LDVM, #T, 1000)


EndIf


Repeat



Event = WindowEvent()
EvT = EventTimer()

MoveSPRITE()

 Select Event
      Case #PB_Event_CloseWindow
        Quit = 1
        
    EndSelect    
        
        
	Select EvT
		Case #T
			CheckRecouvre()
		
	EndSelect

Until Quit = 1
End
		
Pour ma radio j'ai mis un WaiWindowEvent(10) pour laisser souffler le CPU (contrairement à l'exemple), en regardant le gestionnaire de tâche c'est tout de même bénéfique.

Ton idée de choper X pixel de la GUI est juste excellente :P
J'en ai pris 2 opposées et c'est parfait.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Comment détecter si un jeu externe est lancé ?

Message par Backup »

Merci :)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Comment détecter si un jeu externe est lancé ?

Message par Backup »

j'ai modifié ta procedure " CheckRecouvre()"
de sorte qu'on ne soit pas obligé de lui indiqué la couleur du pixel de reference (240,240,240)
elle la lit tout seul comme une grande :)
ce qui rend la procedure compatible , si tu change la couleur de ton interface :)

Code : Tout sélectionner

Procedure CheckRecouvre(xxx,yyy,num_fenetre)
	; Version Dobro
	; xxx , yyyy = coordonées du pixel a Tester
	; num_fenetre de votre application
	; Renverra #True si votre fenetre est recouverte , et #False sinon ;)
	Static flag ; ajout Dobro
	Static couleur_ref  ; ajout Dobro
	
	PosX   =   WindowX(num_fenetre)
	PosY   =   WindowY(num_fenetre)
	; Capture d'un pixel du GUI
	
	; ********************* Ajout Dobro *******************
	if flag=0  
		SetActiveWindow(num_fenetre)
		couleur_ref=Pxlcolor(PosX + xxx, posY + yyy)  ; on lit le pixel la premiere fois , pour connaitre sa valeur , et en faire le Pixel de Reference ;)
		flag=1
	Endif
	; ***************************************************
	If Pxlcolor(PosX + xxx, posY + yyy) <> couleur_ref
		ProcedureReturn #true ; Recouvert
		Else
		ProcedureReturn #False  ; Pas Recouvert
	EndIf
EndProcedure   
Dernière modification par Backup le sam. 07/déc./2013 15:29, modifié 2 fois.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Comment détecter si un jeu externe est lancé ?

Message par Backup »

Bon au final , j'ai simplifié la procedure a ce qu'elle devrai etre

c'est a dire une procedure qui ne fait que renvoyer un resultat si la fenetre (dont le numero est passé en parametre )
est recouvert (#true ) ou pas (#false )


ce qui donne au final ce code :)

Code : Tout sélectionner

; Activer / desactiver fenêtre OpenWindowScreen() selon que la fenêtre soit visible ou pas.
; Ar-S - PB 5.21 LTS x86
; Retouché par Dobro
Enumeration
	#LDVM
	#SP
	#T
EndEnumeration
InitSprite()

;-Declarations
Declare  Pxlcolor(X,Y)
Declare  CheckRecouvre(xxx,yyy,num_fenetre)
Declare  CreaSPRITE()
Declare  DestroyOWS()
Declare  CreaOWS()
Declare  MoveSPRITE()

Global X
Global.b Creation

; ouverture Fenetre
If OpenWindow(#LDVM, 5,5, 50, 50, "test", #PB_Window_SystemMenu| #PB_Window_ScreenCentered)
	StickyWindow(#LDVm,1)
	CreaOWS()
	CreaSPRITE()
	Creation = 0
	AddWindowTimer(#LDVM, #T, 1000)
EndIf


Repeat
	Event = WindowEvent()
	EvT = EventTimer()
	MoveSPRITE()
	Select Event
		Case #PB_Event_CloseWindow
		Quit = 1
	EndSelect   
	Select EvT
		Case #T
		if CheckRecouvre(5,40,#LDVM) =#true ; (recouvert); du coup on applique le traitement en fonction  de ce que renvoi la procedure ;) 
			If creation = 0
				DestroyOWS()
				Creation = 1 ; Pour ne pas refermer la fenêtre vu qu'elle est déjà fermée
			EndIf
			Debug "CACHE"
			Else  ; #false (pas recouvert)
			If Creation = 1
				CreaOWS()
				CreaSPRITE()
				Creation = 0 ; Pour ne pas recréer la fenêtre et les sprites vu qu'ils sont crées
				SetActiveWindow(#ldvm)
			EndIf
			Debug "VISIBLE"   
		Endif
	EndSelect
	
Until Quit = 1
End
;- **** Zone Procedures ****
Procedure Pxlcolor(X,Y)
	; Lecture de la valeur couleur du pixel 
	; a l'emplacement X,y
	handle=GetDC_(GetDesktopWindow_())
	couleur=GetPixel_(handle,X,Y)
	ReleaseDC_(GetDesktopWindow_(),handle )
	ProcedureReturn couleur
EndProcedure 

Procedure CheckRecouvre(xxx,yyy,num_fenetre)
	; Version Dobro
	; xxx , yyyy = coordonées du pixel a Tester
	; num_fenetre de votre application
	; Renverra #True si votre fenetre est recouverte , et #False sinon ;)
	Static flag ; ajout Dobro
	Static couleur_ref  ; ajout Dobro
	
	PosX   =   WindowX(num_fenetre)
	PosY   =   WindowY(num_fenetre)
	; Capture d'un pixel du GUI
	
	; ********************* Ajout Dobro *******************
	if flag=0  
		SetActiveWindow(num_fenetre)
		couleur_ref=Pxlcolor(PosX + xxx, posY + yyy)  ; on lit le pixel la premiere fois , pour connaitre sa valeur , et en faire le Pixel de Reference ;)
		flag=1
	Endif
	; ***************************************************
	If Pxlcolor(PosX + xxx, posY + yyy) <> couleur_ref
		ProcedureReturn #true ; Recouvert
		Else
		ProcedureReturn #False  ; Pas Recouvert
	EndIf
EndProcedure   

Procedure CreaSPRITE()
	CreateSprite(#SP, 5, 5)
	StartDrawing( SpriteOutput(#SP) )
		Box(0,0,5,5,#Green)
	StopDrawing()
EndProcedure

Procedure DestroyOWS()
	CloseScreen()
EndProcedure

Procedure CreaOWS()
	OpenWindowedScreen(WindowID(#LDVM),5,5,40,40)
EndProcedure

Procedure MoveSPRITE()
	If Creation = 0
		DisplaySprite(#Sp, X, 10)
		X + 1
		If X > 55
			X = -5
		EndIf
		FlipBuffers()
		ClearScreen(RGB(0,0,0))
	EndIf
EndProcedure





; 

; EPB
Répondre