Au sujet des écrans graphiques

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
pat
Messages : 411
Inscription : mar. 24/nov./2009 15:13

Au sujet des écrans graphiques

Message par pat »

Bonjour à tous.
PB permet d'ouvrir des écrans graphiques, que ce soit dans une fenêtre ou plein écran.
Vous remarquerez que quand vous changez la résolution de l'écran, l'écran graphique est fermé et il faut obligatoirement recharger les objets (sprites, images...) mais pas les gadgets, qui, eux, restent parfaitement valides.
Dans le cas où il y a changement de résolution, par exemple lorsque votre programme est ouvert et que l'utilisateur, sans fermer votre programme, charge un autre programme en mode plein écran dans une autre résolution, vous perdez l'écran graphique et il faut recharger les objets.
Pour savoir quand cela s'est fait, on peut utiliser, et merci PB, la commande AvailableMemoryScreen() qui permet de savoir combien d'octets il y a dans la mémoire graphique et donc si cette commande est égale à 0, l'écran est fermé. C'est parfait jusqu'à maintenant.

Ceux dont l'OS est, comme moi, Vista, doivent connaître le logiciel Microsoft Defender, qui de temps en temps invite l'utilisateur à cliquer dessus.
Ce logiciel bloque le programme ouvert mais surtout, hélas, ferme l'écran graphique et nous revoilà à obligatoirement recharger les objets. Alors me direz vous, il faut utiliser la commande AvailableMemoryScreen() pour voir si l'écran graphique est fermé. Hélas, la mémoire n'est pas à 0.
Question donc : comment faire pour savoir quand un écran graphique est fermé ?
Merci à ceux qui savent de me donner quelques indications et surtout les clés du problème.
:)
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Au sujet des écrans graphiques

Message par djes »

Le sujet le plus complet là-dessus, qui concerne le basculement des écrans graphiques avec ALT-TAB, ce qui engendre le même problème : http://purebasic.fr/english/viewtopic.p ... 4&start=15
pat
Messages : 411
Inscription : mar. 24/nov./2009 15:13

Re: Au sujet des écrans graphiques

Message par pat »

Merci djes mais cela ne répond pas à ma question de savoir comment savoir quand un écran graphique est fermé.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Au sujet des écrans graphiques

Message par Backup »

pat a écrit :Merci djes mais cela ne répond pas à ma question de savoir comment savoir quand un écran graphique est fermé.

Code : Tout sélectionner

 If IsScreenActive () = 0 ; le joueur a quitté le jeu (Alt-tab)... ou autre raison .... 
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Au sujet des écrans graphiques

Message par djes »

Dobro a écrit :
pat a écrit :Merci djes mais cela ne répond pas à ma question de savoir comment savoir quand un écran graphique est fermé.

Code : Tout sélectionner

 If IsScreenActive () = 0 ; le joueur a quitté le jeu (Alt-tab)... ou autre raison .... 
Merci !

A noter que le code de Dobro est la meilleure façon de gérer le basculement, grâce à l'ouverture d'une fenêtre pour gérer les évènements qui arrivent à l'appli, quand elle n'a plus le focus.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Au sujet des écrans graphiques

Message par Backup »

pat a écrit :Merci djes mais cela ne répond pas à ma question de savoir comment savoir quand un écran graphique est fermé.
suite a débat sur un bug présent ou pas a ce niveau sur le forum anglais ,
voici donc une solution de nco2k pour savoir si l’écran a été créé ou pas , (s'il est existant ou pas )

entre parenthèses , je ne sais pas comment ce code fonctionne ... mais il fonctionne :lol:
faut dire que je ne me suis jamais intéressé aux Imports :)

Code : Tout sélectionner

Import ""
  PB_Screen_Windowed
EndImport

InitSprite()
OpenWindow(0, 0, 0, 640, 480, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

Debug "ecran actif ? :"+str(PB_Screen_Windowed)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0)
Debug "ecran actif ? :"+str( PB_Screen_Windowed)

Repeat
  Repeat
    Select WindowEvent()
      Case 0
        Break
      Case #PB_Event_CloseWindow
        CloseScreen()
        Debug "ecran actif ? :"+str( PB_Screen_Windowed)
        Break 2
    EndSelect
  ForEver
  ClearScreen(RGB(0, 100, 200))
  FlipBuffers()
ForEver 
merci a vous tous, ça a fait avancer le smilblick :)

djes a écrit : A noter que le code de Dobro est la meilleure façon de gérer le basculement, grâce à l'ouverture d'une fenêtre pour gérer les évènements qui arrivent à l'appli, quand elle n'a plus le focus.

il y a juste ce Goto , qui pourrait faire peur a certain..
j'ai pas trouvé mieux :)
enfin , un goto reste un jump (courant en assembleur)

mais c'est vrais que je ne teste pas si le prg lanceur est toujours présent en Ram avant le goto...
c'est un problème facilement résolvable en ajoutant un test sur le nom de la fenetre (findwindow())
avant de risquer de sauter dans le vide ;)

ce code me fait penser aux Trapezistes ;

dans un cirque , le premier (le prg) envoi le second sur l'autre trapèze ( en attente de relancement dans la barre des taches ) , et le second se jette dans le vide , en espérant que le premier (le prg ) soit toujours là

de la haut voltige je vous dis :lol:

imager les prg donne souvent des solutions :)
pat
Messages : 411
Inscription : mar. 24/nov./2009 15:13

Re: Au sujet des écrans graphiques

Message par pat »

Merci Dobro (et aussi Djes). Je vais voir ça de plus près car je ne suis pas chez moi et je ne possède pas Internet.
pat
Messages : 411
Inscription : mar. 24/nov./2009 15:13

Re: Au sujet des écrans graphiques

Message par pat »

Bonjour,

A Dobro.
J'ai bien regardé ton programme. C'est parfait mais cela ne représente pas la réalité.
PB_Screen_Windowed est une commande interne à PB qui prend la valeur 1 quand on ouvre un écran graphique et 0 quand on le ferme.
Pour bien comprendre ce que je veux dire, exécute ton programme, laisse-le ouvert et ouvre un programme qui utilise une autre résolution d'écran que celui du bureau, tu verras qu'il faudra recharger les objets graphiques parce que l'écran graphique a été fermé, par contre la commande PB_Screen_Windowed te renverra la valeur 1 puisque tu n'as pas fait CloseScreen().
Ce qu'il me faut c'est savoir si REELLEMENT l'écran graphique est ouvert ou pas, PB_Screen_Windowed n'étant qu'une commande interne à PB qui prend la valeur 1 quand on fait Open... et 0 quand on fait CloseScreen().
J'espère que tu as bien compris ce que je voulais dire.
Il doit bien avoir un moyen de se renseigner si un écran graphique est ouvert ou fermé car le changement de résolution ferme systématiquement l'écran graphique, sans que le programmeur ait fait quoi que ce soit, mais c'est également le cas du programme Windows Defender (en tout cas sous Vista) qui bloque le programme et ferme l'écran graphique du programme analysé.
:)
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Au sujet des écrans graphiques

Message par djes »

Tu n'as pas lu ce que j'ai écrit. Si tu l'avais fait, tu aurais été voir ce lien http://purebasic.fr/english/viewtopic.p ... 4&start=15 qui contient beaucoup de codes reposant sur IsScreenActive(). Le principe de celui de Dobro (http://purebasic.fr/english/viewtopic.p ... ea#p323137) est très bon.
pat
Messages : 411
Inscription : mar. 24/nov./2009 15:13

Re: Au sujet des écrans graphiques

Message par pat »

A djes.
J'ai parfaitement regardé ton lien (site en anglais).
Je n'ai pas besoin de savoir ce qu'est IsScreenActive et comment basculer en multitâche ou pas.
Ca je sais très bien le faire.
Il n'y a aucun exemple de programme qui pourrait me servir pour ce que je souhaite.
Je répète que je souhaite savoir quand un écran graphique soit ouvert ou fermé, et cela dans la réalité.
Mais tu n'as pas bien lu ce que j'ai écrit à Dobro.
Fais ceci :
Tu ouvres un programme avec un écran graphique ouvert, par exemple celui de Dobro.
Tu fais dans le programme de Dobro un Debug Pb_Screen_Windowed (la variable de l'Import) pour voir ce que donne cette variable. Si l'écran est ouvert cette variable devrait valoir 1 et donc si c'est fermé 0.
Maintenant tu changes la résolution de ton écran en bien veillant à laisser ton programme ouvert.
Si tu regardes bien ta variable sera à 1 alors que ton écran graphique sera fermé. Normal que cet écran soit fermé puisque tu as changé la résolution de l'écran. Par contre ta variable devrait donner 0 et comme ce n'est pas le cas, cela veut dire que cela ne marche pas.
Tu l'as souvent annoncé, tu as toi-même créé des programmes de jeux et je suis étonné que tu ne puisses me fournir de solution étant donné que je considère que tu es très compétent et largement plus que beaucoup d'autres, comme moi par exemple qui n'a pas ta connaissance.
Il ne te reste, si tu le souhaites, qu'à vérifier tout ça et constater ce qu'il en est réellement.
:)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Au sujet des écrans graphiques

Message par Backup »

je viens de tester :

avec ce code :

Code : Tout sélectionner


; Purebasic 4.41
;By Dobro
; exemple de l'utilisation de IsScreenActive()

; quittez le pseudo jeux avec Alt+TAB
; on retourne dans le jeux d'un clique sur la fenetre en barre des taches

initsprite ()
initmouse ()
initkeyboard ()
Enumeration
         #sprite
EndEnumeration
Structure sprite
        x.i
        y.i
        pas_x.i
        pas_y.i
EndStructure
Dim sprite.sprite(1)
examinedesktops ()
x_screen= desktopwidth (0) ; je recup la rez de l'ecran
y_screen= desktopheight (0)
flag=0
debut: ; le label qui permet le retour dans le jeux !!
openscreen (x_screen, y_screen, 32, "Fullscreen + ALT-TAB démo" )
releasemouse (0)
createsprite ( #sprite , 64, 64)
startdrawing ( spriteoutput ( #sprite ))
         box (0,0,64,64, rgb (255,13,40))
stopdrawing ()


;********* initialisation du sprite **********
If flag=0 ; le joueur n'est jamais sorti du jeu , s'il est sorti on ne fais pas ce bloc de code !!
sprite(1)\x=x_screen/2 ; on place le sprite au centre
sprite(1)\y=y_screen/2 ; on place le sprite au centre
sprite(1)\pas_x=2 ; on donne une vitesse de deplacement a notre sprite
sprite(1)\pas_y=2 ; on donne une vitesse de deplacement a notre sprite
EndIf

Repeat
         examinekeyboard () ; ne sert que pour quitter le prg avec la touche esc
    
         ; ************* gere le deplacement du sprite ***************
        sprite(1)\x=sprite(1)\x+sprite(1)\pas_x
        sprite(1)\y=sprite(1)\y+sprite(1)\pas_y
                 ; ----------------------------------------------------------------------------
         If sprite(1)\x+64>=x_screen:sprite(1)\pas_x=-sprite(1)\pas_x: EndIf
         If sprite(1)\y+64>=y_screen:sprite(1)\pas_y=-sprite(1)\pas_y: EndIf
         ; ----------------------------------------------------------------------------
         If sprite(1)\x<=0:sprite(1)\pas_x=-sprite(1)\pas_x: EndIf
         If sprite(1)\y<=0:sprite(1)\pas_y=-sprite(1)\pas_y: EndIf
         ; *******************************************************
        
        
         ; ********** affichage du sprite *********************
         displaytransparentsprite ( #sprite , sprite(1)\x, sprite(1)\y)
        
         flipbuffers ()
         clearscreen (0)
        
         ; *************** attention toute l'astuce est la !! *******************
         If isscreenactive () = 0 ; le joueur a quitter le jeu (Alt-tab)
                 releasemouse (1) ; je libere la souris ... inutile ici mais bon
                flag=1 ; on note que l'utilisateur est sorti du jeux
                 closescreen () ; on ferme l'ecran
                
                 ; ******* la ruse de guerre !! ****************************
                 openwindow (1,1,1,1,1, "toto le jeu " , #PB_Window_Minimize ) ; j'ouvre une fenetre que je minimise en bar des taches
                 Repeat :Event= waitwindowevent (2): Until Event= #PB_Event_ActivateWindow ; j'attend qu'on clique sur la fenetre
                 closewindow (1) ; je ferme la fenetre
                 Goto debut ; je retourne dans le jeux sans réinitialiser les variables de déplacement (on reprends ou on en etait! !!! )
     EndIf
Until keyboardpushed ( #PB_Key_Escape ) ; là , on veux vraiment quitter le jeux LOL
End

si tu lance le pseudo jeux

que tu fais Alt+tab pour aller au bureau
que tu change la resolution
que tu reclique sur le prg ( ou Alt+tab pour sauter sur le prg de pseudo-jeux )
ben ça marche , il repart comme en 14 :)
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Au sujet des écrans graphiques

Message par djes »

Il y a deux cas distincts, en fenêtré ou en plein écran. Dans les deux cas, tu dois utiliser IsScreenActive(). Si tu changes de résolution, IsScreenActive() renverra 0. En fenêtré, quand tu as quitté ta fenêtre, il faut tester si IsScreenActive() = 1

Voici l'exemple de Dobro remanié

Code : Tout sélectionner

;*****************************************************************************
;
; Purebasic 4.41 
; par Dobro 
; modifié par djes
; Exemple de l'utilisation de IsScreenActive() 
; Quittez le pseudo-jeu avec ALT + TAB 
; On retourne dans le jeu d'un clic sur la fenêtre en barre des tâches 
; #WINDOWED = 0 : test en plein écran
; #WINDOWED = 1 : test en fenêtré
;
;*****************************************************************************

#WINDOWED = 1
#SPRITE = 0

EnableExplicit

InitSprite()
InitMouse()
InitKeyboard()

Define.i ScreenWidth, ScreenHeight 

;*****************************************************************************

Structure Sprite
  x.i
  y.i
  pas_x.i
  pas_y.i
EndStructure 

;*****************************************************************************

Procedure InitialisationGraphique()
  
  Shared ScreenWidth, ScreenHeight
  Define Event.i
  
  ExamineDesktops()
  
  CompilerIf #WINDOWED
  
    ScreenWidth  = DesktopWidth(0) / 2 ; Je récup la rés de l'écran 
    ScreenHeight = DesktopHeight(0) / 2

    OpenWindow(0, 0, 0, ScreenWidth, ScreenHeight, "Test", #PB_Window_ScreenCentered | #PB_Window_BorderLess)
    OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0)
    Repeat 
      Event = WaitWindowEvent() 
    Until IsScreenActive() = 1 ; Attends que l'utilisateur ait cliqué sur la fenêtre
    
  CompilerElse
    
    ScreenWidth  = DesktopWidth(0)
    ScreenHeight = DesktopHeight(0)
    OpenScreen(ScreenWidth, ScreenHeight, 32, "Screen + ALT - TAB démo" )
    
  CompilerEndIf
  
  ReleaseMouse(0)
  
EndProcedure

;*****************************************************************************

Procedure DessinSprite()
  
  CreateSprite( #Sprite, 64, 64)
  StartDrawing( SpriteOutput( #Sprite ))
  Box(0, 0, 64, 64, RGB(255, 13, 40))
  StopDrawing()
  
EndProcedure

;*****************************************************************************

Dim Sprites.Sprite(1)
Define Event.i

InitialisationGraphique()
DessinSprite()

;- ********* Initialisation du Sprite ********** 
Sprites(1)\x = ScreenWidth / 2  ; on place le sprite au centre 
Sprites(1)\y = ScreenHeight / 2
Sprites(1)\pas_x = 2 ; on donne une vitesse de déplacement à notre sprite 
Sprites(1)\pas_y = 2

Repeat 
  
  ExamineKeyboard() ; ne sert qu'à quitter le prg avec la touche esc 
  
  ;- ************* Déplacement du sprite *************** 
  Sprites(1)\x = Sprites(1)\x + Sprites(1)\pas_x
  Sprites(1)\y = Sprites(1)\y + Sprites(1)\pas_y
  ; ------------------------------------------------------------------------------- 
  If Sprites(1)\x + 64 >= ScreenWidth  : Sprites(1)\pas_x = -Sprites(1)\pas_x : EndIf 
  If Sprites(1)\y + 64 >= ScreenHeight : Sprites(1)\pas_y = -Sprites(1)\pas_y : EndIf 
  ; ---------------------------------------------------------------------------- 
  If Sprites(1)\x <= 0 : Sprites(1)\pas_x = -Sprites(1)\pas_x : EndIf 
  If Sprites(1)\y <= 0 : Sprites(1)\pas_y = -Sprites(1)\pas_y : EndIf 
  
  ;- ********** Affichage du Sprite ********************* 
  ClearScreen(0)
  DisplayTransparentSprite( #Sprite, Sprites(1)\x, Sprites(1)\y) 
  FlipBuffers()
  
  ;- *************** Attention toute l'astuce est la !! ******************* 
  If IsScreenActive() = 0 ; le joueur a quitté le jeu (par exemple avec Alt - tab) 
    
    ReleaseMouse(1) ; je libère la souris ... inutile ici mais bon 
    
    CompilerIf #WINDOWED
      CloseWindow(0) 
    CompilerElse
      CloseScreen()
    CompilerEndIf
       
    ;- ******* la ruse de guerre !! **************************** 
    OpenWindow(1, 1, 1, 1, 1, "toto le jeu ", #PB_Window_Minimize ) ; j'ouvre une fenetre que je minimise dans la barre des tâches 
    Repeat : Event = WaitWindowEvent(2) : Until Event = #PB_Event_ActivateWindow ; j'attends qu'on clique sur la fenêtre 
    CloseWindow(1) ; je ferme la fenetre 
    InitialisationGraphique()
    DessinSprite() 
    
  EndIf 
  
Until KeyboardPushed(#PB_Key_Escape) ; là, on veut vraiment quitter le jeu LOL 

End 
pat
Messages : 411
Inscription : mar. 24/nov./2009 15:13

Re: Au sujet des écrans graphiques

Message par pat »

A djes et Dobro.
Merci pour vos efforts pour m'aider.
Il ne s'agit pas pour moi de savoir si on sort du programme ou pas (avec IsScreenActive), que ce soit en mode fenêtré ou plein écran. Je connais parfaitement la manoeuvre.
Il s'agit pour moi de savoir SI UN ECRAN GRAPHIQUE EST OUVERT OU FERME.
Le fait de changer la résolution d'écran fermera automatiquement tous les écrans graphiques.
Et si par exemple, je suis en mode fenêtré et que je sort du programme, effectivement IsScreenActive sera égal à 0 et si je rentre dans mon programme il sera différent de 0 (idem pour le mode plein écran).
Par contre, ce qui m'intéresse c'est l'ECRAN GRAPHIQUE, de savoir s'il est ouvert ou pas.
Pour savoir cela, la commande AvailableScreenMemory est importante : en effet, quand on changera la résolution cette commande renverra 0 puisqu'il n'y a plus d'écran ouvert.
Donc c'est déjà un pas, comme je l'ai déjà expliqué dans mon premier message.
Maintenant il faut savoir que le programme Windows Defender bloquera le programme et ferma l'écran graphique du programme analysé mais la commande AvailableScreenMemory ne sera pas égale à 0.
J'ai déjà vu des jeux où, analysé avec Windows Defender, le programme ne plantait pas. Tout simplement parce que les programmeurs savaient quand l'écran graphique était fermé ou ouvert.
Je souhaite connaître la manoeuvre.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Au sujet des écrans graphiques

Message par Backup »

putain le dialogue de sourd !! :lol:

as tu essayé mon dernier code ?
d'ailleurs as tu essayé le code de Djes ?


je dis ça , car si tu lance mon code , tu peux bien changer de résolution , lancer un autre prg ...

lorsque tu reviendra sur mon code ( par Alt+tab ) par exemple ... enfin , comme tu le sent...

mon code va se réafficcher comme une fleur , et le Sprite, se promenera toujours sur l'ecran !

si tu veux , je peux meme te filler le code pour Forcer la résolution de l'ecran lorsque le prg reprends la main ....


si tu n'arrive pas a mieux expliquer ce qui te dérange , on n'y arrivera pas :lol:

perso j'ai testé , changé de résolution , et c'est niquel !!
je ne vois pas pourquoi ça ne le serai pas chez toi ... :roll:

il faut savoir que le programme Windows Defender bloquera le programme et ferma l'écran graphique du programme analysé
t'as qu'a virer cette daube de la ram , avec un KillProcess(Pid) , il ne fera plus ch*er ... :lol:
ptain , ...c'est qui le chef , toi ? ou ce prg de m**de

tu pourra éventuellement le relancer avec runprg ...
pat
Messages : 411
Inscription : mar. 24/nov./2009 15:13

Re: Au sujet des écrans graphiques

Message par pat »

A Dobro.
Merci pour tes efforts soutenus pour m'aider que j'apprécie particulièrement.
Effectivement dialogue de sourd puisque nous nous comprenons mal.
Si ton programme fonctionne, malgré le changement de résolution d'écran, c'est que tu recharges tes objets à chaque fois que tu rentres dans ton programme, ce qui engendre un clignotement de l'écran.
Ca je peux parfaitement aussi le faire mais je souhaite éviter ce clignotement dû au rechargement des objets et à la réouverture de l'écran graphique. Clignotement donc normal.
Mais il faut se dire, à chaque fois qu'on va dans un autre programme et qu'on on retourne dans notre programme, ce clignotement apparaîtra systématiquement, ce que je veux éviter.
Pour éviter ça, savoir quand l'écran graphique est fermé ou ouvert est important puisque quand SEULEMENT l'écran graphique sera fermé je rouvrirai l'écran graphique et je rechargerai les objets.
Je suis perfectionniste et je veux que mes programmes de jeux soit corrects.
Maintenant je vais bien définir ce que je veux dire par écran graphique ouvert et écran graphique fermé puisque la compréhension semble difficile.
Avec OpenScreen... j'ouvre un écran graphique pour des dessins, des images, etc.
Par CloseScreen() je ferme cet écran graphique.
Si j'ouvre un écran graphique avec OpenScreen... l'écran est ouvert mais si je change la résolution, le système fermera systématiquement et automatiquement cet écran graphique sans que je fasse CloseScreen().
Donc je souhaite savoir quand l'écran graphique que j'ai ouvert avec OpenScreen sera fermé pour pouvoir après rouvrir un écran graphique et recharger mes objets, ce qui m'évitera des clignotements de l'écran du à la fermeture (par le système) et la réouverture (par le programmeur) et le chargement des objets.
Comme j'ai vu des jeux parfaitement fluides, je me suis dis qu'il serait bien de faire pareil.
Si effectivement Windows Defender ne fait pas la loi, l'utilisateur d'un jeu peut parfaitement vouloir contrôler mon programme pour voir s'il est valide ou pas. Les pros savent faire ça, je pensais aussi qu'on pouvait faire ça également mais je me rends compte que cela est difficile.
Dommage car j'attendais beaucoup de résoudre mon problème pour finaliser mes jeux.
En tout cas je ne peux que te remercier pour ton aide, toujours aussi précieuse et avisée.
Répondre