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
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é
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
;}