Progressbar dans un statusbar avec Pb 4.30 [Résolu]
Progressbar dans un statusbar avec Pb 4.30 [Résolu]
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.
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.
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.
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
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
et j'ai changé dans ta boucle la commande
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é
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
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
parSetGadgetState(#Progre_bar, x)
Code : Tout sélectionner
SetGadgetStateEx(#Progre_bar, x)
Voilà, si ça peut servir.
Et si quelqu'un a d'autres méthodes, je suis intéressé

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
;}
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.
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)


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)
Il n'est pas toujours utile d'utiliser les fonction "Ex" comme je viens de les expliquer.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)
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.
A mon avis parce que çà peut ralentir ton code pour rien, surtout si tu utilises beaucoup d'objets (gadgets, images, ...).Dobro a écrit :dans ce cas me viens une question !
pourquoi tes fonctions "EX" ne sont pas les fonctions natives de Purebasic ??
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.