[RESOLU] Evènement Click

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
omega
Messages : 633
Inscription : sam. 26/nov./2011 13:04
Localisation : Alger

[RESOLU] Evènement Click

Message par omega »

Bonjour,

Je n'ai pas trouvé le bon titre à mettre mais je vais expliquer mon problème.

Code : Tout sélectionner

Enumeration
#Mainform
#localExplorer
#NetworkExplorer
#ComboExplorer
#Dest

;images 
#Transmettre
EndEnumeration

UseJPEGImageDecoder()

trans=CatchImage(0, ?trans)

DataSection
trans:
IncludeBinary "images\trans.jpg"
EndDataSection

Global WindowStyle.i=#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered|#PB_Window_SizeGadget
Global wDest$

If OpenWindow(#Mainform,0,0, 900, 550, "ExplorerListGadget", WindowStyle)
  If CreateGadgetList(WindowID(#Mainform))
     ExplorerComboGadget(#ComboExplorer, 10, 80, 400, 100,"C:\", #PB_Explorer_Editable)
     ExplorerListGadget(#LocalExplorer, 10, 100, 400, 400, "*.*", #PB_Explorer_MultiSelect)
     ButtonImageGadget(#Transmettre, 420, 150, 35, 30, ImageID(0))
     TextGadget(#Dest, 470, 80, 400, 20, "c:\test\", #PB_Text_Border)
     ListViewGadget(#NetworkExplorer, 470, 100, 400, 400)
  EndIf 
EndIf

SetGadgetColor(#Dest,#PB_Gadget_BackColor,RGB(255, 255, 255))

Repeat : 
EventID = WaitWindowEvent()
If EventID = #PB_Event_Gadget
   Select EventGadget()

   Case #ComboExplorer
        n=GetGadgetState(#ComboExplorer)
        If n>=0
           wChemin$=GetGadgetText(#ComboExplorer)
           SetGadgetText(#LocalExplorer,wChemin$)
           ResizeGadget(#LocalExplorer, #PB_Ignore, #PB_Ignore,#PB_Ignore, #PB_Ignore)
        EndIf   
   
   Case #Transmettre
         Debug "clic"
         wdest$=GetGadgetText(#Dest)
         If ExamineDirectory(0, wdest$, "*.*")  
            While NextDirectoryEntry(0)
               Debug DirectoryEntryName(0)
            Wend
            FinishDirectory(0)
         Else
            MessageRequester("Erreur...","Chemin de destination inexistant !")
         EndIf

         ;----------------------------------------------------------------------------------------------------
         ;For item=0 To CountGadgetItems(#LocalExplorer)
         ;    If GetGadgetItemState(#LocalExplorer, item) & #PB_Explorer_Selected
         ;       wFile$=GetGadgetItemText(#LocalExplorer, item)   
         ;      AddGadgetItem(#NetworkExplorer,-1,wFile$)
         ;   EndIf    
         ;Next item                 
        
         ;If #PB_Explorer_Directory
         ;   Debug GetGadgetItemText(#Explorer, GetGadgetState(#Explorer)) + " est une unité ou un dossier"
         ;EndIf
         ;If #PB_Explorer_File
         ;   Debug GetGadgetItemText(#Explorer, GetGadgetState(#Explorer)) + " est un fichier"
         ;EndIf
         ;----------------------------------------------------------------------------------------------------
          
   EndSelect
EndIf    
Until WaitWindowEvent() = #PB_Event_CloseWindow
End 
Bon. Pour tester ce code, n'oubliez pas d'ajouter une image quelconque (flèche dirigée vers la droite en ce qui concerne mon code).

Quand je clique sur l'image, l'évènement (click) ne s'exécute pas à chaque fois (parfois je clique 2 à trois fois pour que 1 SEUL EVENEMENT s'exécute) !

Je croyais que c'étais la souris qui déconnait mais je l'ai remplacée et toujours le même
problème.

Ma question est simple:
Pourquoi je dois cliquer plus d'une fois (parfois) pour que l'évènement (click) soit exécuté?

Merci
Dernière modification par omega le lun. 11/mars/2013 11:16, modifié 1 fois.
Win7 (x64) 64 bits Pb 5.72
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Evènement Click

Message par Backup »

c'est normal !!

ton code :

Code : Tout sélectionner

Case #Transmettre
i=i+1
         Debug "clic"+str(i)
         wdest$=GetGadgetText(#Dest)
         If ExamineDirectory(0, wdest$, "*.*") 
            While NextDirectoryEntry(0)    ; <<<<<<<<<< ici , si ton repetoire contient beaucoup de fichier , ça prends du temps , le temps qu'il le parcour en entier
               Debug DirectoryEntryName(0)
            Wend
            FinishDirectory(0)
         ;Else    ; ici ça prends du temps , et ça ouvre un requester , donc perte du Focus , il faudra deja reclicker une fois avant la prise en compte du click suivant
           ; MessageRequester("Erreur...","Chemin de destination inexistant !")

         EndIf

test ce code tel qu'il est , tu verra deja une net amélioration de la réaction ...


tu clickais plus d'une fois car l'ordi est en train de scanner ton repertoire, donc, il est bloqué dans la boucle While-Wend

c'est seulement lorsqu'il en ressort qu'il prends en compte tes cliques .... :)

l'ideal serai de mettre en Thread le parcour du dossier , comme ça plus de ralentissement ;)
Avatar de l’utilisateur
omega
Messages : 633
Inscription : sam. 26/nov./2011 13:04
Localisation : Alger

Re: Evènement Click

Message par omega »

Bonjour Dobro
tu clickais plus d'une fois car l'ordi est en train de scanner ton repertoire, donc, il est bloqué dans la boucle While-Wend
Le problème c'est que ce répertoire (c:\test\) n'existe pas (c fait exprès) ,
le but de mon code est justement l'affichage du message (chemin inexistant)...

Je n'ai pas encore testé ton code mais (dois-je vraiment le faire malgré cette précision?)

Répertoire vide =temps d'exécution très faible (n'est ce pas?)

merci
Win7 (x64) 64 bits Pb 5.72
Azur
Messages : 40
Inscription : ven. 22/mai/2009 23:58

Re: Evènement Click

Message par Azur »

Salut
Je pense que ton problème vient du fait que tu utilises deux fois la commande windowevent()
tu as waitwindowevent() au début de ta boucle
et until windowevent() en fin de boucle

Les commandes windowevent() te transmettent les événements aillant eu lieux, mais efface également cette liste d'événement.

regarde:

remplace ton
Until WaitWindowEvent() = #PB_Event_CloseWindow
de fin de boucle par
forever

nb: tu devras fermer ton prog façon hardcore car il va boucler sans cesse.
Dernière modification par Azur le dim. 10/mars/2013 14:12, modifié 1 fois.
Azur
Messages : 40
Inscription : ven. 22/mai/2009 23:58

Re: Evènement Click

Message par Azur »

D'autre part je me permet de te faire remarquer qu'on constate à ton code que tu as bien saisis le concept général mais qu'en procédant de cette manière tu vas vite galérer sur de plus gros projets.
Je pense que tu gagnerais en essayant de rendre ton code beaucoup plus procédural.
La ton code est trop impératif, et ce n'est pas pratique sur de gros projets.
De plus rendre ton code plus procédural c'est en fait une façon de penser ton application avant de la coder.
Tu pense ton appli comme étant un assemblage de modules aillant chacun une fonction.
une fonction "récupérer les événements"
une fonction "traiter les événements fenêtre"
une fonction "traiter les événements réseaux"
une fonction "quitter le programme proprement"
etc ...

Ce n'est pas une technique de prog uniquement, c'est une façon de penser.
Avec ça, tu vas voir tes programmes d'une façon beaucoup plus claire, et de gros projets te paraitront bien plus simples à coder.

moi je fais toujours comme ça

Code : Tout sélectionner


EnableExplicit

Define win=OpenWindow(#PB_Any,0,0,100,50,"Titre",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
Global gad1=ButtonGadget(#PB_Any,0,0,100,20,"gad1")
Global gad2=ButtonGadget(#PB_Any,0,30,100,20,"gad2")

;___________________________ traitement en cas de clic sur gadget 1  
Procedure travail1()
  Debug "travail1"
EndProcedure

;___________________________ traitement en cas de clic sur gadget 2  
Procedure travail2()
  Debug "travail2"
EndProcedure


; deux procedures vides pour un jeu réseau par exemple
Procedure regarde_reseau()
  ;fais des trucs 
EndProcedure

Procedure render()
  ;affiche des trucs
EndProcedure


;___________________________ fonction de traitement des évenements type gadget
Procedure gadget()
  Select EventGadget()
    Case gad1
      travail1()
    Case gad2
      travail2()
  EndSelect
EndProcedure

;___________________________ procedure sortie 
; c'est pas mal d'avoir une procedure sortie
; si tu veux par exemple sauver des préférences 
; ou sauver l'état de l'interface utilisateur ( taille / position fenetre )
Procedure sortie()
  End
EndProcedure

;___________________________ scan des événements et traitement au cas par cas
Procedure scan()
  Define ev=WaitWindowEvent(5)
  Select ev
    Case #PB_Event_CloseWindow
      sortie()
    Case #PB_Event_Gadget
      gadget()
  EndSelect
EndProcedure

;____________________________ ma boucle principale
Procedure bouclePrincipale()
  Repeat
    scan()
    regarde_reseau() ; procedure bidon pour exemple
    render() ; idem ( disons affichage des sprites dans un jeu )
  ForEver
EndProcedure


;____________________________ lancement du programme
bouclePrincipale()
Si tu penses ton appli comme ça au départ, tu verras ce sera beaucoup plus facile.
Tu auras à gérer le fait que les variables sont locales à la fonction dans lesquelles elles sont déclarées. Ca c'est chiant... mais c'est bien. En trouvant un moyen de gérer tes variables le mieux possibles tu n'auras plus à te demander si le nom d'une variable est déjà pris ou créer des variable du type position_vaisseau_joueur_vivant.

En espérant avoir attiré ton attention. cdmt.
Dernière modification par Azur le dim. 10/mars/2013 14:15, modifié 3 fois.
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Evènement Click

Message par falsam »

+1 Sur ce que vient de dire Azur deux message au dessus. Ta boucle évènementielle est moisi.
Que dit l'aide ?
WaitWindowEvent() ne peut être appelé qu'une seule fois par boucle d'évènements, sinon les évènements seront "perdus" (chaque évènement ne peut être traité qu'une seule fois et n'est plus disponible pour un deuxième traitement).
Remplace ta boucle évènementielle par ce code et ton souci sera réglé.

Code : Tout sélectionner

Repeat
  Select WaitWindowEvent()
    
    Case #PB_Event_CloseWindow
      End

    Case #PB_Event_Gadget
      Select EventGadget()
        Case #ComboExplorer
          n=GetGadgetState(#ComboExplorer)
          If n>=0
            wChemin$=GetGadgetText(#ComboExplorer)
            SetGadgetText(#LocalExplorer,wChemin$)
            ResizeGadget(#LocalExplorer, #PB_Ignore, #PB_Ignore,#PB_Ignore, #PB_Ignore)
          EndIf   
   
        Case #Transmettre
          Debug "clic"
          wdest$=GetGadgetText(#Dest)
          If ExamineDirectory(0, wdest$, "*.*")  
            While NextDirectoryEntry(0)
              Debug DirectoryEntryName(0)  
            Wend
            FinishDirectory(0)  
          Else
            MessageRequester("Erreur...","Chemin de destination inexistant !")    
          EndIf

          ;----------------------------------------------------------------------------------------------------
          ;For item=0 To CountGadgetItems(#LocalExplorer)
          ;    If GetGadgetItemState(#LocalExplorer, item) & #PB_Explorer_Selected
          ;       wFile$=GetGadgetItemText(#LocalExplorer, item)   
          ;      AddGadgetItem(#NetworkExplorer,-1,wFile$)
          ;   EndIf    
          ;Next item                 
        
          ;If #PB_Explorer_Directory
          ;   Debug GetGadgetItemText(#Explorer, GetGadgetState(#Explorer)) + " est une unité ou un dossier"
          ;EndIf
          ;If #PB_Explorer_File
          ;   Debug GetGadgetItemText(#Explorer, GetGadgetState(#Explorer)) + " est un fichier"
          ;EndIf
          ;----------------------------------------------------------------------------------------------------
    
      EndSelect ;Fin EventGadget()
  EndSelect ;Fin WaitWindowEvent()
ForEver ;Fin boucle evenementielle 
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: Evènement Click

Message par Backup »

Azur a écrit :Salut
Je pense que ton problème vient du fait que tu utilises deux fois la commande windowevent()
tu as waitwindowevent() au début de ta boucle
et until windowevent() en fin de boucle.

Arf ! j'avais meme pas vu :mrgreen: :roll:
Azur
Messages : 40
Inscription : ven. 22/mai/2009 23:58

Re: Evènement Click

Message par Azur »

Oui on avait vu ... :)
Avatar de l’utilisateur
graph100
Messages : 1318
Inscription : sam. 21/mai/2005 17:50

Re: Evènement Click

Message par graph100 »

Azur a écrit :Oui on avait vu ... :)
:lol: :lol:

Le mieux c'est encore de stocker la valeur de Waitwindowevent() dans une variable pour pouvoir y accéder n'importe quand dans ton programme.
Et les remarques d'Azur sur les procedures d'évènement ne sont pas mal non plus !
_________________________________________________
Mon site : CeriseCode (Attention Chantier perpétuel ;))
Avatar de l’utilisateur
omega
Messages : 633
Inscription : sam. 26/nov./2011 13:04
Localisation : Alger

Re: Evènement Click

Message par omega »

Bonjour à tous

Je vous remercie tous pour votre aide !

@Dobro
Oui... je ne l'ai pas vu moi aussi, c'est une erreur impardonnable de ma part
(au lieu de faire (until EvenId=#PB_Event_CloseWindow)
j'ai fait (until WaitWindowEvent=#PB_Event_CloseWindow)

J'ai ajouté (hier) au début du code (après repeat) le code suivant:

Code : Tout sélectionner

if EvenId=#PB_Event_CloseWindow)  
  End
EndIf
et j'ai remplacé Until par ForEver
Et ça a marché

Mais je n'ai pas vu ça: (c'est maintenant que je le constate):

Code : Tout sélectionner

WaitWindowEvent=#PB_Event_CloseWindow)
Merci beaucoup à toute l'équipe qui m'a aidé
et merci à Azur pour cette méthode de programmation structurée, ça m'a l'air intéressante mais je dois m'y adapter (c 'est pas facile de changer de méthode mais...)

Merci pour tout
Win7 (x64) 64 bits Pb 5.72
Répondre