BindEvent (Résolu..)

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

BindEvent (Résolu..)

Message par Good07 »

Bonjour à tous,
Bien que programmant depuis longtemps en PureBasic, j'ai profité du confinement pour me payer la formation de chez Udemy "Purebasic pour les nulles". Bien sûr il y a beaucoup de choses que je connaissait, mais un petit vaccin de rappel ne fait jamais de mal. A ce sujet si je peux me permettre une petite remarque au sujet du titre de cette formation, j'aurais écrit "PureBasic pour les nuls" a moins que celle-ci ne s'adresse à la gente féminine. Si c'est le cas on pourrait déceler un peu de misogynie dans celui-ci. :D
Mais comme je vous le disait, même un amateur un peu éclairé trouvera quelques astuces (Je n'en suis qu'a la moitié de la formation) qui lui avait échappé. A ce sujet, j'ai essayé dans l'éditeur la touche F9 et sur mon Mac, j'ai un plantage de l'éditeur. J'attends un retour de ceux qui travaillent sur ce genre de bécane pour savoir si le problème viens de mon côté. :(
Pour en venir au coeur de mon sujet, j'ai fait connaissance avec la fonction "BindEvent" que j'avais bien vu dans la doc, mais comme je le disait précédemment dans un autre post, la doc est souvent confuse et ne révèle pas toujours la substantifique moelle des commandes.
Dans cette formation, j'ai enfin compris à quoi ça pouvait servir, seulement il y a un mais... :( Il y a toujours un mais qui se cache quelque part. :D
En cherchant dans le forum, je me suis aperçu que beaucoup d'entre vous utilisaient cette commande pour simplifier la boucle d'évènement d'un fenêtre. Et c'est là que le bas blesse... :(
Pour une fenêtre pas de problème et c'est tout simple, mais quand est t'il lorsque le programme comporte une dizaine de fenêtres et qu'on veux les fermer les unes après les autres sans pour autant quitter le programme ?
Voici la méthode que j'ai employé ;

Code : Tout sélectionner

Enumeration
  #window1
  #window2
EndEnumeration

Enumeration gadget
  #Bchange
  #CanvasDessin
EndEnumeration

Procedure ClicBouton()
  OpenWindow(#window2,0,0,400,400,"Fenêtre 2",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
EndProcedure
Procedure FermetureF2()
  CloseWindow(#window2)
EndProcedure
Procedure FermetureF1()
  CloseWindow(#window1)
  End
EndProcedure

OpenWindow(#window1,0,0,800,600,"Fenêtre 1",#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(#Bchange,20,500,100,25,"Ouverture")
BindGadgetEvent(#Bchange,@ClicBouton())
BindEvent(#PB_Event_CloseWindow,@FermetureF2(),#window2)
BindEvent(#PB_Event_CloseWindow,@FermetureF1(),#window1)


Repeat
  WaitWindowEvent()
ForEver
Ne cherchez pas l'utilité de celui-ci, c'est juste un exemple pour utiliser deux(ou plus) fenêtres. A ce stade je ne vois pas trop la simplification de la boucle si il faut écrire autant de procédures qu'il y a de fenêtres à gérer. Mais comme d'habitude je dois mal gérer la chose. :(
Je vous remercie d'avance pour vos réponses. :wink:
Dernière modification par Good07 le mer. 22/avr./2020 17:39, modifié 1 fois.
Marc56
Messages : 2196
Inscription : sam. 08/févr./2014 15:19

Re: BindEvent

Message par Marc56 »

On utilise l'une ou l'autre méthode (ou les deux ensemble) selon ce que l'on souhaite faire.
Dans la méthode classique, les évènements sont captés puis traités l'un après l'autre.
Dans la méthode Bind, le système n'attend pas. En quelques sortes, il fonctionne en comme en thread.
:!: Ce n'est pas toujours un avantage car on peut parfois vouloir que des évènements soient dépendants les uns des autres

Lance les deux exemples suivants, et déplace la fenêtre.
- Dans la méthode classique, la pendule s'arrête pendant le déplacement.
- Dans la méthode bind, elle continue à tourner

Programme qui affiche l'heure en méthode classique

Code : Tout sélectionner

OpenWindow(0, 100, 100, 300, 200, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered )

AddWindowTimer(0, 0, 1000)

Repeat
    If WaitWindowEvent() = #PB_Event_Timer
        SetWindowTitle(0, FormatDate("%hh:%ii:%ss", Date()))
    EndIf
Until WaitWindowEvent() = #PB_Event_CloseWindow
Programme qui affiche l'heure en méthode bind

Code : Tout sélectionner

OpenWindow(0, 100, 100, 300, 200, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered )

AddWindowTimer(0, 0, 1000)

Procedure Show_Time()
    SetWindowTitle(0, FormatDate("%hh:%ii:%ss", Date()))    
EndProcedure

BindEvent(#PB_Event_Timer, @Show_Time())

Repeat

Until WaitWindowEvent() = #PB_Event_CloseWindow
Cela veut dire que si une fenêtre contient beaucoup d'évènements gérés en mode Bind, le système check sans arrêt et teste énormément de choses. Par exemple un déplacement de fenêtre en mode Bind va retracer tous les objets (c'est joli, mais va ralentir) alors que le mode classique ne va tracer que le cadre externe pendante le déplacement et dessine le reste quand on relâche la souris.

Les évènements gérés par Bind et liés à une fenêtre sont aussi relâchés dès que la fenêtre est fermée, cela veut dire aussi qu'il faut refaire un Bind si on ré-ouvre la même fenêtre même avec le même ID.

Comme on peut mélanger les deux systèmes, le plus simple est de réserver Bind aux évènements indépendants du "travail" principal de l'application (comme par exemple afficher l'heure) ou aux évènements qui doivent arriver souvent, même pendant un autre traitement.

:wink:
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Re: BindEvent

Message par Good07 »

Bonjour Marc56,
Merci pour ta réponse.
Evidemment dans ce cas là, c'est utile. Mais dans mon cas de gestion des fenêtres, est-ce que c'est vraiment un avantage ? Et ma façon de faire est-elle la bonne ?
Je pense que pour gérer ce genre de chose, la méthode classique reste la meilleure. J'ai tout faux ?
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: BindEvent

Message par Ollivier »

Ça, c'est la bonne, et ça cartonne :

Code : Tout sélectionner

Procedure FermeLaFenetre()
   CloseWindow(EventWindow() )
EndProcedure

BindEvent(#Pb_Event_CloseWindow, FermeLaFenetre() )
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Re: BindEvent

Message par Good07 »

Bonjour Olivier,
Merci aussi pour ta réponse.
Mais ma demande était la gestion de 1,2,3...Etc fenêtres dans le même programme. Faut-il écrire autant de procédure de fermeture que de fenêtres créées ?
Marc56
Messages : 2196
Inscription : sam. 08/févr./2014 15:19

Re: BindEvent

Message par Marc56 »

Faut-il écrire autant de procédure de fermeture que de fenêtres créées ?
On peut réduire

Code : Tout sélectionner

Procedure Fermeture()
    Protected Win = GetActiveWindow()
    Select EventWindow()
        Case #window1 : End
        Case #window2 : CloseWindow(Win) 
    EndSelect   
EndProcedure

...
BindEvent(#PB_Event_CloseWindow, @Fermeture())
Avatar de l’utilisateur
microdevweb
Messages : 1802
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: BindEvent

Message par microdevweb »

On peut faire comme cela aussi

Code : Tout sélectionner

Procedure closeForm()
   CloseWindow(EventWindow)
endProcedure
Cela fermera la fenêtre qui reçoit l'événement
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Re: BindEvent

Message par Good07 »

Merci pour vos réponses.
@microdevweb
Ça ne marche pas.En fait ça me ferme en premier la fenêtre 1 alors que la 2 est affichée à l'écran et ensuite le programme plante. :(
@Marc56
Ça marche nickel :D
Marc56
Messages : 2196
Inscription : sam. 08/févr./2014 15:19

Re: BindEvent

Message par Marc56 »

La solution de microdevweb est excellente et simplifie encore, mais plante simplement parce qu'il a juste oublié les ()
il faut mettre EventWindow()
qui retourne alors l'id de fenêtre.
Sans les (), cela donne juste une variable 'EventWindow' qui ne contient rien, donc = 0, donc l'id de la première fenêtre.

Mais même avec EventWindow() cela plante à la fin car en l'absence de End, WaitWindowEvent() n'a plus rien à lire après la fermeture des deux fenêtres.

Solution: ajouter une condition de sortie si la fenêtre principale n'existe plus

:wink:
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: BindEvent

Message par Ollivier »

Good07 a écrit :Bonjour Olivier,
Merci aussi pour ta réponse.
Mais ma demande était la gestion de 1,2,3...Etc fenêtres dans le même programme. Faut-il écrire autant de procédure de fermeture que de fenêtres créées ?
Là y a 15 fenêtres. Faut toute les fermer !

Code : Tout sélectionner

Global i

For i = 1 To 15
 OpenWindow(#Pb_Any,
  i * 32,
  i * 32,
  400,
  200,
  Str(i),
  #Pb_Window_SystemMenu)
Next
i - 1

Procedure Fermeture()
 CloseWindow(EventWindow() )
 i - 1
 If Not i
  End
 Endif
EndProcedure

BindEvent(#Pb_Event_CloseWindow,
 @Fermeture() )

Repeat
 WaitWindowEvent()
ForEver
@MicroDevWeb(c)

Faudrait que t'écrive << PureBasic pour les nul(le)s >>
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Re: BindEvent

Message par Good07 »

Merci Olivier,
Ça marche...
Tu n'as pas lésiné sur le nombre de fenêtres ouvertes :D
Mais ta solution fonctionne bien.

@Marc56
J'ai pensé insérer :

Code : Tout sélectionner

If GetActiveWindow=-1
 End
EndIf
Mais où que je le mette ça ne marche pas mieux. :(
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: BindEvent

Message par Ollivier »

En programmation,
Il y a "aise"...
"thèse"...
Et "parenthèse".

Code : Tout sélectionner

GetActiveWindow()
L'auteur de ce message pilote un pétrolier lancé depuis CapCa direction la 1ère planète habitable qu'il espère reconquérir, très loin d'ici...

@MicroDevWeb

Ou alors << PureBasic pour les curieu[x; ses] >>, naon ?
Dernière modification par Ollivier le mer. 22/avr./2020 17:31, modifié 1 fois.
Marc56
Messages : 2196
Inscription : sam. 08/févr./2014 15:19

Re: BindEvent

Message par Marc56 »

Changer la boucle principale par quelque chose comme

Code : Tout sélectionner

While iswindow(window_0)
   Waitwindowevent()
Wend 
End
:wink:
Good07
Messages : 308
Inscription : ven. 23/avr./2004 18:08
Localisation : Hérault 34190 Laroque

Re: BindEvent

Message par Good07 »

@Marc56
Ça marche effectivement.. :D
:oops: je suis encore passé à côté. :twisted:
Merci à tous pour votre contribution et je me coucherais moins bête ce soir. 8O
Je marque résolu dans le titre du post.
Répondre