Progressbar dans un statusbar avec Pb 4.30 [Résolu]

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
yves86
Messages : 39
Inscription : sam. 26/juil./2008 17:13
Localisation : Poitou

Progressbar dans un statusbar avec Pb 4.30 [Résolu]

Message par yves86 »

Bonjour à tous,
Depuis la version 4.30, la fonction creategadgetlist n'existe plus. Or elle me permettait de créer une Progressbar dans le statusbar d'une fenêtre et maintenant je n'y arrive plus.
Quelqu'un aurait-il trouvé la solution ?

Merci d'avance.
Dernière modification par yves86 le dim. 21/déc./2008 21:33, modifié 1 fois.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

J'ai posé la même question sur le forum anglais il y a quelques semaines et la réponse est que tu peux utiliser UseGadgetList à la place.

A+
yves86
Messages : 39
Inscription : sam. 26/juil./2008 17:13
Localisation : Poitou

Message par yves86 »

Merci Denis. je n'avais pas trouvé ton post sur le forum Anglais.
C'est une fonction que je n'utilisais pas, mais cela marche bien.

A+
yves86
Messages : 39
Inscription : sam. 26/juil./2008 17:13
Localisation : Poitou

Message par yves86 »

Pour ceux qui veulent supprimer une progressbar après utilisation, voici une astuce que j'utilise.

Code : Tout sélectionner

;{- Enumerations / DataSections
;{ Windows
Enumeration
  #Window_0
EndEnumeration

Enumeration
  #StatusBar_Window_0
  #Progre_bar
  #Texte
  #Button_0
  #Nb
EndEnumeration
;}
;}
Procedure OpenWindow_Window_0()
  If OpenWindow(#Window_0, 450, 200, 400, 400, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
    If CreateStatusBar(#StatusBar_Window_0, WindowID(#Window_0))
      AddStatusBarField(500)
      StatusBarText(#StatusBar_Window_0, 0, "", #PB_StatusBar_Center)
      AddStatusBarField(300)
      StatusBarText(#StatusBar_Window_0, 1, "", #PB_StatusBar_Center)
    EndIf
    ;If CreateGadgetList(WindowID(#Window_0)) ; pour pb 4.2 et inférieur
      ButtonGadget(#Button_0, 140, 125, 115, 75, "Avance")
      StringGadget(#Nb,180,250,30,20,"")
      TextGadget(#Texte,100,228,300,20,"Cliquer jusqu'à 11 pour effacer la progressbar")
    ;EndIf
  EndIf
  
  ;If CreateGadgetList(StatusBarID(#StatusBar_Window_0)) ; pour pb 4.2 et inférieur
  If UseGadgetList(StatusBarID(#StatusBar_Window_0))     ; pour pb 4.30
    ProgressBarGadget(#Progre_bar,200,5,100,14,1,10,#PB_ProgressBar_Smooth)
  EndIf 
EndProcedure

OpenWindow_Window_0()

;{- Event loop
Repeat
  Select WaitWindowEvent()
    ; ///////////////////
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Button_0
          x+1
          SetGadgetText(#Nb,Str( x))
          SetGadgetState(#Progre_bar,x)
          If x=11
              If Freegadget(#Progre_bar)     ; pour pb 4.30
            EndIf 
          EndIf
      EndSelect
    ; ////////////////////////
    Case #PB_Event_CloseWindow
      Select EventWindow()
        Case #Window_0
          CloseWindow(#Window_0)
          Break
      EndSelect
  EndSelect
ForEver
;
;}
Dernière modification par yves86 le dim. 21/déc./2008 21:32, modifié 1 fois.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

La commande FreeGadget est la solution ou HideGadget si tu veux la cacher pour la réutiliser plus tard.
yves86
Messages : 39
Inscription : sam. 26/juil./2008 17:13
Localisation : Poitou

Message par yves86 »

Encore merci Denis pour l'info.

A+
yves86
Messages : 39
Inscription : sam. 26/juil./2008 17:13
Localisation : Poitou

Message par yves86 »

Code édité
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Je vais passer pour un radoteur mais je reprécise quelques points de programmation qui me semblent très importants.

Si on fait un petit code pour soi, on peut ne pas appliquer ce qui suit, si ça plante c'est sur notre machine mais si on on distribue, il faut éviter à tout prix que ça plante.

Les petites règles suivantes peuvent s'appliquer facilement.

A chaque création de fenêtre, gadget, statusBar ou autre, il faut tester le résultat.
Si ce n'est pas critique, on laisse continuer le programme mais c'est très rarement le cas. Si c'est critique, on quitte le programme.
Ces problèmes peuvent arriver (c'est pas fréquent mais ...) pour des raisons de mémoire voire des problèmes de l'OS pris dans une boucle et qui ne peut pas initialiser correctement l'élément etc.

Lorsque c'est verrouillé par des tests, on peut avoir des problèmes dans des callback à la fermeture ou l'initialisation ou dans les boucles etc. lorsque l'on supprime un gadget ou fenêtre. C'est pour cette raison en particulier qu'il existe la commande IsGadget(), IsWindow(), IsStatusBar(), IsFont() etc.

Pour des applications stables, je vous conseille de systématiquement tester que l'élément est initialisé avant une opération dessus. J'ai eu tellement de problèmes avec ce genre de choses.

Aujourd'hui j'ai adopté la solution suivante qui me convient. J'utilise des macros qui testent que le gadget, la fenêtre ou autre existe avant de faire l'opération. Je fais attention dans les boucle de ne pas utiliser ces macros dans la mesure du possible, il vaut mieux tester avant la boucle que tous les éléments utilisés dans cette boucle soient initialisés, si ce n'est pas le cas, ça ne sert pas à grand chose de faire la boucle, enfin là chaque cas est un cas particulier.

C'est aussi une des raisons qui fait que je n'utilise aucune librairie personnelle (sauf les miennes que je verrouille).

Un exemple, si on a un TextGadget et que l'on change le texte, on utilise la commande SetGadgetText(#Gadget, Texte$)

Je défini ma macro avec le même nom de commande suivi de Ex (comme bien des API Windows) pour extension de la fonction.

Ca donne

Code : Tout sélectionner

Macro SetGadgetTextEx(Gadget, texte)
     If IsGadget(Gadget)
          SetGadgetText(Gadget, texte)
     EndIf
EndMacro
Pour ton code, si tu le lances avec le débugger tu auras une erreur dans la boucle à partir du moment ou la progressbar n'existe plus

J'ai ajouté la macro suivante

Code : Tout sélectionner

Macro SetGadgetStateEx(Gadget, state)
     If IsGadget(Gadget)
            SetGadgetState(Gadget, state)
     EndIf
EndMacro

et j'ai changé dans ta boucle la commande
SetGadgetState(#Progre_bar, x)
par

Code : Tout sélectionner

SetGadgetStateEx(#Progre_bar, x)
Dans le code qui suit qui est le tien, j'ai appliqué les règles que je viens de te donner, c'est plus long mais c'est du code stable.

Voilà, si ça peut servir.

Et si quelqu'un a d'autres méthodes, je suis intéressé :D

Code : Tout sélectionner

;{- Enumerations / DataSections
;{ Windows
Enumeration
     #Window_0
EndEnumeration

Enumeration
     #StatusBar_Window_0
     #Progre_bar
     #Texte
     #Button_0
     #Nb
EndEnumeration
;}
;}

Macro SetGadgetStateEx(Gadget, state)
     If IsGadget(Gadget)
            SetGadgetState(Gadget, state)
     EndIf
EndMacro 


Procedure.l OpenWindow_Window_0()
     ; retourne #true en cas de succès sinon #False
     If OpenWindow(#Window_0, 450, 200, 400, 400, "Window_0", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_TitleBar)
          If CreateStatusBar(#StatusBar_Window_0, WindowID(#Window_0))
               AddStatusBarField(500)
               StatusBarText(#StatusBar_Window_0, 0, "", #PB_StatusBar_Center)
               AddStatusBarField(300)
               StatusBarText(#StatusBar_Window_0, 1, "", #PB_StatusBar_Center)
               
               ;If CreateGadgetList(WindowID(#Window_0)) ; pour pb 4.2 et inférieur
               
               If ButtonGadget(#Button_0, 140, 125, 115, 75, "Avance") = 0
                    ProcedureReturn #False
               EndIf
               
               If StringGadget(#Nb, 180, 250, 30, 20, "") = 0
                    ProcedureReturn #False
               EndIf
               
               If TextGadget(#Texte, 100, 228, 300, 20, "Cliquer jusqu'à 11 pour effacer la progressbar") = 0
                    ProcedureReturn #False
               EndIf
               ;EndIf
               
               ;If CreateGadgetList(StatusBarID(#StatusBar_Window_0)) ; pour pb 4.2 et inférieur
               If UseGadgetList(StatusBarID(#StatusBar_Window_0))     ; pour pb 4.30
                    If ProgressBarGadget(#Progre_bar, 200, 5, 100, 14, 1, 10, #PB_ProgressBar_Smooth) = 0
                         ProcedureReturn #False
                    EndIf
                    ProcedureReturn #True
               Else
                    ProcedureReturn #False
               EndIf
          Else
               ProcedureReturn #False
          EndIf
     Else
          ProcedureReturn #False
     EndIf
EndProcedure

If OpenWindow_Window_0() = #False
     MessageRequester("Erreur", "Impossible de créer les éléments système" + Chr(10) + "L'application va se terminer", #PB_MessageRequester_Ok)
     End
EndIf


;{- Event loop
Repeat
     Select WaitWindowEvent()
               ; ///////////////////
          Case #PB_Event_Gadget
               Select EventGadget()
                    Case #Button_0
                         x + 1
                         SetGadgetText(#Nb, Str(x))
                         SetGadgetStateEx(#Progre_bar, x)
                         If x = 11
                              FreeGadget(#Progre_bar)     ; pour pb 4.30
                         EndIf
               EndSelect
               
               ; ////////////////////////
          Case #PB_Event_CloseWindow
               Select EventWindow()
                    Case #Window_0
                         CloseWindow(#Window_0)
                         Break
               EndSelect
     EndSelect
ForEver
End
;} 
Avatar de l’utilisateur
Jacobus
Messages : 1559
Inscription : mar. 06/avr./2004 10:35
Contact :

Message par Jacobus »

Excellent, tu viens de me donner une bonne idée/raison d'utiliser les Macro(), fallait y penser.
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

ben oui c'est meme pas mal du tout ! :)
seulement ...

dans ce cas me viens une question !

pourquoi tes fonctions "EX" ne sont pas les fonctions natives de Purebasic ??

parce que là ton system finalement reviens a Re-écrire toutes les fonctions du purebasic , dans ce cas , pourquoi ne pas proposer a fred, de blinder ces fonctions de cette façon ?
puis finalement que ces fonctions blindées renvoient un code d'erreur explicite !
qui indiquerai pourquoi la fonction n'as pas réussi ... ;)

comme ça par exemple (mais en natif)



:)

Code : Tout sélectionner

Macro SetGadgetStateEx(Gadget, state)
  If IsGadget(Gadget)
    SetGadgetState(Gadget, state)
  Else
    MessageRequester("erreur","le gadget "+Str(Gadget)+" n'existe pas",#PB_MessageRequester_Ok)
  EndIf
EndMacro 


SetGadgetStateEx(Gadget, state)
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Dobro a écrit :ben oui c'est meme pas mal du tout ! :)
seulement ...

dans ce cas me viens une question !

pourquoi tes fonctions "EX" ne sont pas les fonctions natives de Purebasic ??

parce que là ton system finalement reviens a Re-écrire toutes les fonctions du purebasic , dans ce cas , pourquoi ne pas proposer a fred, de blinder ces fonctions de cette façon ?
puis finalement que ces fonctions blindées renvoient un code d'erreur explicite !
qui indiquerai pourquoi la fonction n'as pas réussi ... ;)

comme ça par exemple (mais en natif)
Il n'est pas toujours utile d'utiliser les fonction "Ex" comme je viens de les expliquer.

Si tu regardes le code que j'ai modifié, je n'ai pas réécrit la fonction SetGadgetText() car dans l'exemple, si le gadget n'est pas créé, l'application n'existe pas et comme on ne détruit pas le gadget, c'est donc qu'il existe, d'ou l'utilisation de SetGadgetText() et pas SetGadgetTextEx() .

Dans certains gros codes que j'ai écris, je n'ai pas vu de différence de rapidité avec les versions "Ex", il faut simplement éviter si possible le code inutile dans les boucles.
gnozal
Messages : 832
Inscription : mar. 07/déc./2004 17:35
Localisation : France
Contact :

Message par gnozal »

Dobro a écrit :dans ce cas me viens une question !

pourquoi tes fonctions "EX" ne sont pas les fonctions natives de Purebasic ??
A mon avis parce que çà peut ralentir ton code pour rien, surtout si tu utilises beaucoup d'objets (gadgets, images, ...).
C'est pour çà qu'il y a deux sortes de fonctions :
- celles qui plantent quand on fournit de mauvais paramètres (garbage in, garbage out ...)
- celles qui sont 100% sûres, la série des IsMachin(Truc), qui ne plantent pas quelque soit le paramètre fourni.
Tu vois la différence quand tu debogues un code ; le débogueur vérifie tout (pas de plantage en théorie), mais on le paye en vitesse d'exécution.
Répondre