Boucle d'evenement de fenetre dans un thread

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
bombseb
Messages : 445
Inscription : jeu. 25/août/2005 22:59
Localisation : 974
Contact :

Boucle d'evenement de fenetre dans un thread

Message par bombseb »

Salut,

J'essaye d'ouvrir plusieurs fenêtres, je crois donc qu'il faut une boucle d'evenement et un thread pour chacune ?
Seulement voici mon code, lorsque j'ouvre la deuxieme fenêtre (Menu Projet -> Nouvelle fenetre), j'ai des fois un "Invalid memory access" au niveau du WaitWindowEvent
De plus, quand j'arrive à ouvrir cette nouvelle fenêtre, lorsque je veux la fermer, c'est la toolbar qui se ferme et l'appli plante....

Est-ce que je procède de la bonne manière ?

(Je suis sur PB 4.51RC1 sur Mac)


Edit : si je compile avec l'option "Activer la gestion des thread" c'est encore pire...

Code : Tout sélectionner

Enumeration
  #ToolBar
  #Fenetre
EndEnumeration

Enumeration
  #Menu
  #MenuAffichageBoiteAOutils
  #MenuProjet
  #MenuProjetNouvelleFenetre
EndEnumeration
  
Enumeration
  #Bouton
  #BoutonImage
EndEnumeration  


Procedure Fenetre (Param)
  
  CloseFenetre.b
  
  If OpenWindow (#Fenetre, 200, 100, 500, 500, "Nouvelle fenetre", #PB_Window_SystemMenu)
    Repeat
      EventFenetre = WaitWindowEvent ()  
    
      Select Event
        Case #PB_Event_CloseWindow
          CloseFenetre = 1
      EndSelect
    Until CloseFenetre = 1
    
    CloseWindow (#Fenetre)
    
  EndIf
  
  
EndProcedure




If OpenWindow (#ToolBar, 20, 100, 200, 300, "ToolBar", #PB_Window_Tool | #PB_Window_SystemMenu)

    If CreateMenu (#Menu, WindowID(#ToolBar))
      MenuTitle ("Affichage")
        MenuItem (#MenuAffichageBoiteAOutils, "Boite à outils")
          SetMenuItemState (#Menu, #MenuAffichageBoiteAOutils, 1)
        MenuTitle ("Projet")
          MenuItem (#MenuProjetNouvelleFenetre, "Nouvelle fenêtre")
    EndIf
    
    ButtonGadget(#Bouton, 10, 10, 150, 20, "Standard Button")
    
    Resultat = LoadImage(1, "Images/Bouton.bmp")
    If Resultat = 0 
      MessageRequester ("Erreur !", "Erreur !")
      End
    EndIf
      
    ButtonImageGadget(#BoutonImage, 10, 50, 36, 36, ImageID(1))
  
  
  Repeat
    Event = WaitWindowEvent ()
    Select Event
      Case #PB_Event_Menu
      
        Select EventMenu ()  ; To see which menu has been selected
          Case #MenuAffichageBoiteAOutils ; Boite à outils
          
            If GetMenuItemState (#Menu, #MenuAffichageBoiteAOutils) = 1
              SetMenuItemState (#Menu, #MenuAffichageBoiteAOutils, 0)
            Else
              SetMenuItemState (#Menu, #MenuAffichageBoiteAOutils, 1)
            EndIf
            
          Case #MenuProjetNouvelleFenetre
            CreateThread (@Fenetre(), 1)
            
          Default
            
        EndSelect
      Case #PB_Event_CloseWindow
        Quit = 1
    EndSelect
  Until Quit = 1
  
  MessageRequester("Fin", "Fin")
 
EndIf
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Boucle d'evenement de fenetre dans un thread

Message par Backup »

t'es pas obligé d'utliser les threads pour ça...

si tu utilise les threads , il faut les killer lorsque tu t'en sert plus ...
d'ou ton probleme de memory :)
bombseb
Messages : 445
Inscription : jeu. 25/août/2005 22:59
Localisation : 974
Contact :

Re: Boucle d'evenement de fenetre dans un thread

Message par bombseb »

Merci pour ta réponse,

mais alors comment faire pour différentier les evenements de la 1ere fenêtre avec ceux de la 2eme si je fait ca dans le même thread ?
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Boucle d'evenement de fenetre dans un thread

Message par Backup »

ici tu as un tuto sur l'utilisation de plusieurs fenetre sans utilisation des threads
(les threads ne sont pas fait pour gerer les evenements !! juste pour effectuer un algo en tache de fond...)

http://www.purebasic.fr/french/viewtopic.php?t=182

ps: descend un peu dans le tuto car il y a d'autres exemples concernant d'autres sujet au debut de ce tuto ;)

ce code en fait :)

Code : Tout sélectionner


;Mis en V4.00 Dobro
;======================================
;- declaration des constantes
; il faut donner au maximum un nom a la constantes qui représente son utilité
; on déclare chaque type de constantes dans une rubrique
; Windows
#fenetre_principale = 0
#fenetre_secondaire = 1
; Gadgets de la fenêtre principale
#gadget_bouton_ouvrir = 0
#gadget_bouton_quitter = 1
#gadget_bouton_ouvrir_masquer = 2
; Gadget de la fenêtre secondaire, attention, ne pas mettre les mêmes valeurs !!
#gadget_bouton_quitter2 = 3
; ======================================
;- declaration des variables globales, des strutures, des listes ou tableau, ...
; ======================================
;- declaration des procedures

Procedure Ouvre_Fenetre_principale()
     If OpenWindow ( #fenetre_principale , 0, 0, 300, 200, "fenêtre principale" , #PB_Window_SystemMenu | #PB_Window_WindowCentered )
         ; on créer la liste des éléments (gadget) de la fenètre
         If CreateGadgetList ( WindowID ( #fenetre_principale ))
             ; on crée 3 boutons
             ButtonGadget ( #gadget_bouton_ouvrir , 10, 10, 280, 20, "Ouvrir une seconde fenêtre" )
             ButtonGadget ( #gadget_bouton_ouvrir_masquer , 10, 40, 280, 20, "Ouvrir une seconde fenêtre en masquant la première" )
             ButtonGadget ( #gadget_bouton_quitter , 10, 70, 280, 20, "Quitter" )
         EndIf
     EndIf
EndProcedure

Procedure Ouvre_Fenetre_secondaire()
     If OpenWindow ( #fenetre_secondaire , 0, 0, 200, 100, "fenêtre secondaire" , #PB_Window_SystemMenu | #PB_Window_WindowCentered )
         ; on créer la liste des éléments (gadget) de la fenètre
         If CreateGadgetList ( WindowID ( #fenetre_secondaire ))
             ; on crée 1 boutons
             ButtonGadget ( #gadget_bouton_quitter2 , 10, 10, 180, 20, "Quitter la fenêtre secondaire" )
         EndIf
     EndIf
EndProcedure

Procedure Fenetre_secondaire()
     ; on affiche la fenêtre secondaire
    Ouvre_Fenetre_secondaire()
     Repeat
        Event = WaitWindowEvent ()
         If Event = #PB_Event_Gadget
             Select EventGadget () ; boutons, zone de texte, ...
                 Case #gadget_bouton_quitter2
                    Event = #PB_Event_CloseWindow ; on stocke dans event l'évènement quitter, ainsi l'appui sur le bouton quitter rvient à l'appui sur la croix
             EndSelect
         EndIf
     Until Event = #PB_Event_CloseWindow
     ; on ferme la fenêtre secondaire
     CloseWindow ( #fenetre_secondaire )
EndProcedure


; =====================================
;- Debut du programme
; On initialise tous d'abord les valeurs
; On affiche la fenêtre les boutons
Ouvre_Fenetre_principale()
; On lance la boucle de gestion des évènements de la fenêtre ouverte
Repeat
    Event = WaitWindowEvent ()
     ; Mettre ici la gestion des évènements
     If Event = #PB_Event_Gadget
         Select EventGadget () ; boutons, zone de texte, ...
             Case #gadget_bouton_ouvrir
                 ; on ouvre la deuxième fenêtre, les gestion des évènement sera gérer dans une procedure
                 ; cette procedure doit respecter la même architecture que la boucle gérant les évènements de la fenêtre principale
                Fenetre_secondaire()
                 SetActiveWindow ( #fenetre_principale ) ; pour pouvoir utiliser la fenêtre principale car la fenête par défaut est la dernière crées donc la fenêtre #fenetre_secondaire
                
             Case #gadget_bouton_ouvrir_masquer
                 HideWindow ( #fenetre_principale , 1) ; on masque la première fenêtre
                Fenetre_secondaire()
                 HideWindow ( #fenetre_principale , 0) ; on affiche la fenêtre
                 SetActiveWindow ( #fenetre_principale )
             Case #gadget_bouton_quitter
                Event = #PB_Event_CloseWindow ; on stocke dans event l'évènement quitter, ainsi l'appui sur le bouton quitter rvient à l'appui sur la croix
         EndSelect
     EndIf
Until Event = #PB_Event_CloseWindow ; si on appui sur la croix, on ferme le programme
End ; Fin du programme

bombseb
Messages : 445
Inscription : jeu. 25/août/2005 22:59
Localisation : 974
Contact :

Re: Boucle d'evenement de fenetre dans un thread

Message par bombseb »

Cool, c'est interressant mais malheureusement j'aimerais pouvoir utliser ces deux fenêtres en même temps
Dans ton exemple on ne peut utiliser les boutons que d'une seule fenêtre...

bon je regarderais en détail ce week end, je pense avoir une idée...(faire une seule boucle d'évènements pour les deux fenêtres peut être ?)
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Boucle d'evenement de fenetre dans un thread

Message par Ar-S »

2 fenêtres qui marchent en même temps.

Code : Tout sélectionner

x=400 : y=400
global O
O=0

Procedure fenetre1()
  OpenWindow(0,x,y,400,400,"",#PB_Window_SystemMenu)
    ButtonGadget(10,5,5,100,20,"test moi")
EndProcedure

Procedure fenetre2()
OpenWindow(1,x+400,y+400,400,400,"",#PB_Window_SystemMenu)
    ButtonGadget(11,5,5,100,20,"test moi aussi")
O=1
EndProcedure  

fenetre1()
 
repeat
  fenetre=WaitWindowEvent()
  
  select fenetre
    Case #PB_Event_Gadget
      
      select EventGadget()

       case 10
        MessageRequester("Fenetre 1","Je fonctionne") ;
        if O=0
        fenetre2()
        endif
      
        case 11
          MessageRequester("Fenetre 2","Je marche aussi") ;
      EndSelect
  EndSelect
  
Until fenetre=#PB_Event_CloseWindow  
~~~~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
bombseb
Messages : 445
Inscription : jeu. 25/août/2005 22:59
Localisation : 974
Contact :

Re: Boucle d'evenement de fenetre dans un thread

Message par bombseb »

Merci pour ton code Ar-s, sauf que tu à le même problème que moi : Lorsque tu ferme la 2eme fenêtre, la 1ere se ferme aussi :!:
Warkering
Messages : 808
Inscription : ven. 08/janv./2010 1:14
Localisation : Québec, Canada

Re: Boucle d'evenement de fenetre dans un thread

Message par Warkering »

Je le ressort, à toi de voir ce qu'il faut en retenir! Porte particulièrement attention à EventWindow(). Informe toi dans la documentation! :wink:

Code : Tout sélectionner

Enumeration
  #Fenetre
  #Fenetre2
  #Texte
  #Bouton
  #BoutonFermer
  #BoutonFenetre
EndEnumeration

OpenWindow(#Fenetre, 32, 32, 640, 480, "Fenetre 1", #PB_Window_SystemMenu)
  TextGadget(#Texte, 2, 2, 160, 20, "Texto illimité avec PB! Hourrah!")
  ButtonGadget(#Bouton, 2, 24, 80, 20, "Bouton")
  ButtonGadget(#BoutonFermer, 84, 24, 80, 20, "Bouton Fermer")
  ButtonGadget(#BoutonFenetre, 166, 24, 80, 20, "Bouton Fenêtre")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow:
      If EventWindow() = #Fenetre2
        CloseWindow(#Fenetre2)
      Else
        Break
      EndIf
    Case #PB_Event_Gadget:
      Select EventGadget()
        Case #Bouton:
          MessageRequester("Bouton", "Bouton cliqué", #PB_MessageRequester_Ok)
        Case #BoutonFermer:
          Break
        Case #BoutonFenetre:
          OpenWindow(#Fenetre2, 64, 64, 320, 240, "Fenetre 2", #PB_Window_SystemMenu)
      EndSelect
  EndSelect
ForEver
En gros, il faut que tu regarde sur quelle fenêtre l'événement a eu lieu, ensuite tu fait les actions nécessaires.
Avatar de l’utilisateur
MLD
Messages : 1124
Inscription : jeu. 05/févr./2009 17:58
Localisation : Bretagne

Re: Boucle d'evenement de fenetre dans un thread

Message par MLD »

Salut bombseb

Regarde si ceci te convient

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)
      
     
            ButtonGadget(#FEN1_BOUTON, 5,  5, 100, 22, "Ouvrir Fenêtre 2")
            ButtonGadget(#FEN1_FERMER, 5, 45, 100, 22, "Quitter")
      
      
      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) 
                                                  StickyWindow(#FENETRE2 , 1)   
                                                            ButtonGadget(#FEN2_FERMER, 5, 5, 100, 22, "Fermer")
                                                     
                                                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

Code pomper quelque part et légèrement modifier.
bombseb
Messages : 445
Inscription : jeu. 25/août/2005 22:59
Localisation : 974
Contact :

Re: Boucle d'evenement de fenetre dans un thread

Message par bombseb »

super !

C'est la fonction EventWindow () qui me manquait....!

Merci pour votre aide :wink:
Répondre