Gérer 2 fenetres

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
micam
Messages : 46
Inscription : ven. 27/avr./2012 15:29

Gérer 2 fenetres

Message par micam »

Bonjour,
Un petit code pour gérer 2 fenêtres. Je sais il y a déjà des exemples. (dont je me suis inspiré)
Ça pourra peut être servir à quelqu'un.
Je pose la question aux spécialistes : ce code est correct ?
Les réponses sont les bienvenues pour me faire évoluer.
Merci.

Code : Tout sélectionner

Enumeration
  ;Les fenetres
  #Fenetre1
  #Fenetre2
EndEnumeration

Enumeration
  ;Les gadgets
  #Button_OuvrirFenetre2
  #Button_FermerFenetre1
  #Button_OuvrirFenetre1
  #Button_QuitterFenetre2
  #Button_Quitter
EndEnumeration

Define.l EventFenetre1, EventFenetre2, EventGadget, EventType, EventMenu

Procedure OpenWindow_Fenetre1()
  If OpenWindow(#Fenetre1, 889, 206, 412, 412, "Fenetre 1", #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
    ButtonGadget(#Button_OuvrirFenetre2, 125, 60, 135, 25, "Ouvrir fenetre 2")
    ButtonGadget(#Button_Quitter, 125, 100, 135, 25, "Quitter")
  EndIf
EndProcedure
  
Procedure OpenWindow_Fenetre2()
  If OpenWindow(#Fenetre2, 479, 344, 354, 225, "Fenetre 2", #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
    ButtonGadget(#Button_FermerFenetre1, 60, 40, 250, 25, "Fermer fenetre1")
    ButtonGadget(#Button_OuvrirFenetre1, 60, 80, 250, 25, "Ouvrir fenetre 1")
    ButtonGadget(#Button_QuitterFenetre2, 60, 120, 250, 25, "Fermer cette fenetre")
  EndIf
  
  Repeat
  EventFenetre2 = WaitWindowEvent()
  Select EventFenetre2
      
    Case #PB_Event_Gadget
      EventGadget = EventGadget()
      EventType = EventType()
      
      If EventGadget = #Button_OuvrirFenetre2   ;ouvre la deuxième fenetre
        OpenWindow_Fenetre2()
        
      ElseIf EventGadget = #Button_FermerFenetre1   ;ferme la première fenetre
        MessageRequester("","Fermeture de la Fenetre 1")
        CloseWindow(#Fenetre1)
        
      ElseIf EventGadget = #Button_OuvrirFenetre1   ;ouvre la première fenetre
        MessageRequester("","Ouverture de la Fenetre 1")
        OpenWindow_Fenetre1()
        CloseWindow(#Fenetre2)
        
      ElseIf EventGadget = #Button_QuitterFenetre2   ;ferme la deuxième fenetre
        CloseWindow(#Fenetre2)
      ElseIf EventGadget = #Button_Quitter
      End
      EndIf

    Case #PB_Event_CloseWindow
      EventFenetre2 = EventWindow()
      If EventFenetre2 = #Fenetre1   ;ferme tout
        End
      ElseIf EventFenetre2 = #Fenetre2   ;ferme la deuxième fenetre
      CloseWindow(#Fenetre2)
    EndIf
    
EndSelect
ForEver

EndProcedure

OpenWindow_Fenetre1()

Repeat
  EventFenetre1 = WaitWindowEvent()
  Select EventFenetre1
      
    Case #PB_Event_Gadget
      EventGadget = EventGadget()
      EventType = EventType()
      
      If EventGadget = #Button_OuvrirFenetre2   ;ouvre la deuxième fenetre
        OpenWindow_Fenetre2()
        
      ElseIf EventGadget = #Button_Quitter   ;ouvre la première fenetre
        CloseWindow(#Fenetre1)
        Break
      EndIf
      
    Case #PB_Event_CloseWindow
      EventFenetre2 = EventWindow()
      If EventFenetre2 = #Fenetre1   ;ouvre la première fenetre
        CloseWindow(#Fenetre1)
        Break
      EndIf
      
  EndSelect
  
ForEver
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Gérer 2 fenetres

Message par Backup »

micam a écrit :Je pose la question aux spécialistes : ce code est correct ?
Les réponses sont les bienvenues pour me faire évoluer.
je ne suis pas un spécialiste , mais pour moi ce code n'est pas correcte !
meme s'il fonctionne a peut pres ...

pourquoi ? :

on ne devrai jamais mettre une boucle d'event dans une procedure !
ta procedure "OpenWindow_Fenetre2()"

est a bannir !

de plus tant que tu es dans cette procedure , tu ne récupère pas les event de la fenetre 1
ton code c'est ou l'une ou l'autre ....

parce que tu es enfermé dans une procedure


de plus niveau Pile()
tu risque de saturer la pile , avec les event qui arrive dedans
( tout ce qui est dans une procedure est empilé )
enfin pas vraiment , mais si tu as un plantage dans la procedure , là tu aura un probleme de pile
et bonjour le cirque
enfin , tout un tas de mauvaise excuse , simplement parceque j'aime pas l'idée :lol:


ce code est preferable :

Code : Tout sélectionner

Enumeration 0 ; Id. Fenêtres
      #FENETRE1
      #FENETRE2
EndEnumeration
Enumeration 0 ; Id. Gadgets
      #FEN1_BOUTON
      #FEN1_FERMER
      #FEN2_FERMER
EndEnumeration

If OpenWindow(#FENETRE1, 0, 0, 640, 480, "Fenêtre 1", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
      
      If CreateGadgetList(WindowID(#FENETRE1))
            ButtonGadget(#FEN1_BOUTON, 5,  5, 100, 22, "Ouvrir Fenêtre 2")
            ButtonGadget(#FEN1_FERMER, 5, 45, 100, 22, "Quitter")
      EndIf
      
      Repeat
            
            Evenement.l = WaitWindowEvent()
            
            Select EventWindow()
                        
                        ;=====================================================
                        ;== EVENEMENTS DE LA FENETRE PRINCIPALE
                        ;=====================================================
                        
                  Case #FENETRE1
                        
                        Select Evenement
                                    
                              Case #PB_Event_Gadget
                                    
                                    Select EventGadget()
                                                
                                          Case #FEN1_BOUTON
                                                If OpenWindow(#FENETRE2, 0, 0, 320, 240, "Fenêtre 2", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
                                                      If CreateGadgetList(WindowID(#FENETRE2))
                                                            ButtonGadget(#FEN2_FERMER, 5, 5, 100, 22, "Fermer")
                                                      EndIf
                                                EndIf
                                                
                                          Case #FEN1_FERMER
                                                Break
                                                
                                    EndSelect
                                    
                              Case #PB_Event_CloseWindow
                                    Break
                                    
                        EndSelect
                        
                        ;=====================================================
                        ;== EVENEMENTS DE LA FENETRE SECONDAIRE
                        ;=====================================================
                        
                  Case #FENETRE2
                        
                        Select Evenement
                                    
                              Case #PB_Event_Gadget
                                    
                                    If EventGadget() = #FEN2_FERMER
                                          CloseWindow(#FENETRE2)
                                    EndIf
                                    
                              Case #PB_Event_CloseWindow
                                    
                                    CloseWindow(#FENETRE2)
                                    
                        EndSelect
                        
            EndSelect
            
      ForEver
      
EndIf

tu peux t'amuser a faire dessiner une fenetre par une procedure
mais n'inclue pas la boucle d'evenement dedans ! .. mais fais comme tu veux apres tout , je m'en tape ...
je me demande d'ailleurs pourquoi je reponds ,en fait ...
au lieu de me faire un petit café au lait ,accompagné de biscuit a la noix .. de coco


le shemas c'est :


Creation fenetre 1


; boucle principale

; *** Boucle d'event des 2 fenetres ***
si bouton lance fenetre 2
creation fenetre 2
; *****************************


; fin boucle principale




... mais bon je ne suis pas spécialiste :)
Avatar de l’utilisateur
falsam
Messages : 7317
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Gérer 2 fenetres

Message par falsam »

Moi non plus je ne suis pas spécialiste et je viens de terminer de boire un bon café.
Comme le suggère Dobro, Gère l'ensemble des évènements dans une seule boucle évènementielle. Même si le code ci-dessous est incomplet (Il aurait fallu tester l’existence de la fenêtre avant de la fermer ou de l'ouvrir), je pense que la méthode ci-dessous est bonne.

[EDIT] j'ai corrigé le code suite à une connerie de ma part. La prochaine fois je changerais le nom des variable !!!

Code : Tout sélectionner

EnableExplicit

Enumeration
  ;Les fenetres
  #Fenetre1
  #Fenetre2

  ;Les gadgets
  #Button_OuvrirFenetre2
  #Button_FermerFenetre1
  #Button_OuvrirFenetre1
  #Button_QuitterFenetre2
  #Button_Quitter
EndEnumeration

Define.l Event, Event_Window, Event_Gadget

Procedure OpenWindow_Fenetre1()
  If OpenWindow(#Fenetre1, 889, 206, 412, 412, "Fenetre 1", #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
    ButtonGadget(#Button_OuvrirFenetre2, 125, 60, 135, 25, "Ouvrir fenetre 2")
    ButtonGadget(#Button_Quitter, 125, 100, 135, 25, "Quitter")
  EndIf
EndProcedure
  
Procedure OpenWindow_Fenetre2()
  If OpenWindow(#Fenetre2, 479, 344, 354, 225, "Fenetre 2", #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
    ButtonGadget(#Button_FermerFenetre1, 60, 40, 250, 25, "Fermer fenetre1")
    ButtonGadget(#Button_OuvrirFenetre1, 60, 80, 250, 25, "Ouvrir fenetre 1")
    ButtonGadget(#Button_QuitterFenetre2, 60, 120, 250, 25, "Fermer cette fenetre")
  EndIf  
EndProcedure

OpenWindow_Fenetre1()

Repeat
  Event = WaitWindowEvent() ;Un evenement c'et produit
  Event_Window = EventWindow() ;Fenetre ayant reçu l'evemenent
  Event_Gadget = EventGadget() ;gadget ayant reçu l'evenement
  
  Select Event 
    Case #PB_Event_Gadget
      
      Select Event_Gadget  
        Case #Button_OuvrirFenetre1
          OpenWindow_Fenetre1() ;ouvre la fenetre 1
          
        Case #Button_OuvrirFenetre2   ;ouvre la deuxième fenetre
          OpenWindow_Fenetre2()
        
        Case #Button_Quitter   ;ferme la fenetre 1
          CloseWindow(#Fenetre1)
          End ;et ferme l'application
          
        Case #Button_FermerFenetre1 ;Ferme la fenetre 1
          CloseWindow(#fenetre1)
          
        Case #Button_QuitterFenetre2 ; ferme fenetre 2
          CloseWindow(#Fenetre2)
          
      EndSelect
      
    Case #PB_Event_CloseWindow
      Select Event_Window
        Case #fenetre1
          CloseWindow(#Fenetre1)
          End
                    
        Case #Fenetre2
          CloseWindow(#fenetre2)
      EndSelect   
  EndSelect
  
ForEver
PS : Dobro aurait dit qu'il n'est pas bon d'avoir des noms de variables identiques aux noms réservés de Pure Basic et il a raison :p . Exemple EventGadget et EventGadget()
Dernière modification par falsam le jeu. 24/mai/2012 8:40, modifié 1 fois.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
micam
Messages : 46
Inscription : ven. 27/avr./2012 15:29

Re: Gérer 2 fenetres

Message par micam »

Bonjour
Dobro et Falsam, merci de votre aide.
J'ai tenu compte de vos remarques (constructives) et repris le code dans ce sens, notamment en testant l’existence des fenêtres avant leur fermeture.
Ce soir je boirai l'apéritif (jus de fruit) à votre santé.
Merci encore.

Code : Tout sélectionner

EnableExplicit

Enumeration
  ;Les fenetres
  #Fenetre1
  #Fenetre2
  
  ;Les gadgets
  #Button_OuvrirFenetre2
  #Button_FermerFenetre1
  #Button_OuvrirFenetre1
  #Button_QuitterFenetre2
  #Button_Quitter
EndEnumeration

Define.l EventWindow, EventGadget

Procedure OpenWindow_Fenetre1()
  If OpenWindow(#Fenetre1, 889, 206, 412, 412, "Fenetre 1", #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
    ButtonGadget(#Button_OuvrirFenetre2, 125, 60, 135, 25, "Ouvrir fenetre 2")
    ButtonGadget(#Button_Quitter, 125, 100, 135, 25, "Quitter le programme")
  EndIf
EndProcedure

Procedure OpenWindow_Fenetre2()
  If OpenWindow(#Fenetre2, 479, 344, 354, 225, "Fenetre 2", #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
    ButtonGadget(#Button_FermerFenetre1, 60, 40, 250, 25, "Fermer fenetre1")
    ButtonGadget(#Button_OuvrirFenetre1, 60, 80, 250, 25, "Ouvrir fenetre 1")
    ButtonGadget(#Button_QuitterFenetre2, 60, 120, 250, 25, "Fermer cette fenetre")
  EndIf  
EndProcedure

OpenWindow_Fenetre1()

Repeat
  EventWindow = WaitWindowEvent()
  EventGadget = EventGadget()
  
  Select EventWindow   
    Case #PB_Event_Gadget
      
      Select EventGadget  
        Case #Button_OuvrirFenetre1
          OpenWindow_Fenetre1() ;ouvre la fenetre 1
          CloseWindow(#Fenetre2)
          
        Case #Button_OuvrirFenetre2   ;ouvre la deuxième fenetre
          OpenWindow_Fenetre2()
          CloseWindow(#Fenetre1)
          
        Case #Button_Quitter   ;ferme la fenetre 1
          CloseWindow(#Fenetre1)
          End ;et ferme l'application
          
        Case #Button_FermerFenetre1 ;Ferme la fenetre 1
          If #Fenetre1 = GetActiveWindow()
            CloseWindow(#fenetre1)
          EndIf
          
        Case #Button_QuitterFenetre2 ; ferme fenetre 2
          OpenWindow_Fenetre1()
          CloseWindow(#Fenetre2)
          
      EndSelect
      
    Case #PB_Event_CloseWindow
      If #Fenetre1 = GetActiveWindow()
        CloseWindow(#Fenetre1)
        End
      EndIf
      
      If #Fenetre2 = GetActiveWindow()
        OpenWindow_Fenetre1()
        CloseWindow(#Fenetre2)
      EndIf
      
  EndSelect
  
ForEver
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Gérer 2 fenetres

Message par djes »

Euh ! Tu peux parfaitement utiliser une procédure pour traiter les évènements (c'est même la façon standard dans Windows), mais ça demande un peu d'expérience (bientôt!). Voir SetWindowCallback()
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Gérer 2 fenetres

Message par Backup »

djes a écrit :Euh ! Tu peux parfaitement utiliser une procédure pour traiter les évènements (c'est même la façon standard dans Windows), mais ça demande un peu d'expérience (bientôt!). Voir SetWindowCallback()

traiter les evenements dans une procedure ( comme l'exemple du callback ) est une chose

mais insérer l'attente de l'evenement (WaitWindowEvent() ; WindowEvent() ) dans une procedure en est une autre ...

d'ailleurs l'exemple du callback , n'inclu pas la reception des event dans la procedure ;)


c'est ce que je dis lorsque j'ecris :
on ne devrai jamais mettre une boucle d'event dans une procedure !
pour moi la boucle d'event n'est pas le traitement post reception , mais bien le fameux

Code : Tout sélectionner

While:WaitWindowEvent():wend
Avatar de l’utilisateur
falsam
Messages : 7317
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Gérer 2 fenetres

Message par falsam »

@Micam : Ton dernier code n'a pas la même logique que ton code précédent. Quand une ouvres une fenêtre, la précédente est fermée. Le bouton #Button_FermerFenetre1 n'a plus aucune utilité.

pour tester si une fenêtre est ouverte ou pas tu dois utiliser IsWindow(#IdentifiantFenetre)

ne pas confondre non plus, comme je l'ai fait dans mon précédent code !!!,EventWindow() et WindowEvent(). Je te laisse regarder l'aide.

regarge le comportement de iswindow quand tu fermes la fenetre1. J'ai inseré un debug dans le code.

Code : Tout sélectionner

EnableExplicit

Enumeration
  ;Les fenetres
  #Fenetre1
  #Fenetre2
  
  ;Les gadgets
  #Button_OuvrirFenetre2
  #Button_FermerFenetre1
  #Button_OuvrirFenetre1
  #Button_QuitterFenetre2
  #Button_Quitter
EndEnumeration

Define.l Event, Event_Window, Event_Gadget

Procedure OpenWindow_Fenetre1()
  If OpenWindow(#Fenetre1, 889, 206, 412, 412, "Fenetre 1", #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
    ButtonGadget(#Button_OuvrirFenetre2, 125, 60, 135, 25, "Ouvrir fenetre 2")
    ButtonGadget(#Button_Quitter, 125, 100, 135, 25, "Quitter le programme")
  EndIf
EndProcedure

Procedure OpenWindow_Fenetre2()
  If OpenWindow(#Fenetre2, 479, 344, 354, 225, "Fenetre 2", #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
    ButtonGadget(#Button_FermerFenetre1, 60, 40, 250, 25, "Fermer fenetre1")
    ButtonGadget(#Button_OuvrirFenetre1, 60, 80, 250, 25, "Ouvrir fenetre 1")
    ButtonGadget(#Button_QuitterFenetre2, 60, 120, 250, 25, "Fermer cette fenetre")
  EndIf  
EndProcedure

OpenWindow_Fenetre1()

Repeat
  Event = WaitWindowEvent()
  Event_Window = EventWindow()
  Event_Gadget = EventGadget()
  
  Debug "IsWindow(#Fenetre1) = "+ Str(IsWindow(#fenetre1))
  
  Select Event
    Case #PB_Event_Gadget
      
      Select Event_Gadget  
        Case #Button_OuvrirFenetre1
          OpenWindow_Fenetre1() ;ouvre la fenetre 1
          CloseWindow(#Fenetre2)
          
        Case #Button_OuvrirFenetre2   ;ouvre la deuxième fenetre
          OpenWindow_Fenetre2()
          CloseWindow(#Fenetre1)
          
        Case #Button_Quitter   ;ferme la fenetre 1
          CloseWindow(#Fenetre1)
          End ;et ferme l'application
          
        Case #Button_FermerFenetre1 ;Ferme la fenetre 1
          If IsWindow(#fenetre1)
            CloseWindow(#fenetre1)
          EndIf
          
        Case #Button_QuitterFenetre2 ; ferme fenetre 2
          OpenWindow_Fenetre1()
          CloseWindow(#Fenetre2)
          
      EndSelect
      
    Case #PB_Event_CloseWindow
      Select Event_Window
        Case #fenetre1
          CloseWindow(#Fenetre1)
          End
        
        Case #fenetre2
          OpenWindow_Fenetre1()
          CloseWindow(#Fenetre2)
      EndSelect
      
  EndSelect
  
ForEver
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
dayvid
Messages : 1242
Inscription : mer. 11/nov./2009 18:17
Localisation : Poitiers (Vienne)

Re: Gérer 2 fenetres

Message par dayvid »

Merci du partage :)
La vie, C'est comme, Une boitte, De startis, On en voie, De toutes, Les couleurs !

Mon forum http://purebasic.forumphp3.com/index.php
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Gérer 2 fenetres

Message par blendman »

si on a dans une application disons une dizaine de fenêtres qu'on peut ouvrir (c'est le cas dans mon éditeur de map, j'ai 6 ou 7 fenêtres pour des options, préférences, fenêtre pour gérer les sprites, les events de la map, les propriétés de la map, etc..), je dois créer tous les cas possible pour toutes les fenêtres et gadgets et gérer ça dans la boucle principale ?
Avatar de l’utilisateur
falsam
Messages : 7317
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Gérer 2 fenetres

Message par falsam »

J'ai lu dans l'aide que chaque événement ne peut être traité qu'une seule fois et n'est plus disponible pour un deuxième traitement. je traite donc l'ensemble des évènements dans une seule boucle évènementielle.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Gérer 2 fenetres

Message par Backup »

la boucle principale d'un prg , peut etre vue comme le Corps d'une Pieuvre

les tentacules ( ta tante ) , sont les Procedures

chaque procedure (ou sous/programme ) , doit rester péripherique a la boucle principale du prg

c'est pourquoi les events devraient rester dans le Corps , comme le Coeur de la pieuvre ..

je trouve l'image tres parlante :)


de cette façon , pas de mélange

j'aurai pu aussi parler d'arbre , puisque contrairement a la pieuvre, une procedure peut aussi faire appel a une autre procedure , donc, ça ressemble plus
a de la ramification ...

mais , d'en <--- (a force de lire certain , ....j'en perd le français de base) donc dans l'ensemble, l'image reste cohérente :)

je vais de ce pas m'ouvrir une boite d'encornets


j'image souvent mes prg , de façon a ne pas me perdre ;
par exemple pour moi les procedures sont comme des circuit integrés
une ou plusieur entrées ( les parametres ) --> traitement interne ---> résultat ( patte de sortie )

dans ce cas la boucle principale serai le processeur central , et la boucle des Events , un timer dans le processeur central :)
Répondre