Page 1 sur 1
Comment gérer une fenêtre dans un thread
Publié : dim. 23/mars/2014 21:08
par Lord Nelson
Salut,
J'ai fais des recherches mais qui n'ont rien donné et les choses on l'air d'avoir changé.
Quel est la bonne méthode pour gérer une fenêtre dans un thread svp ?
Je voudrait ouvrir une fenêtre et qu'elle se gère seule dans un thread et pas dans le code principal car dans le code
principale il va y avoir des commandes qui lui serons envoyé pour pouvoir interagir avec cette fenêtre.
Ensuite du code principale j’interagis cette fenêtre et les gadget qui y sont.
Schéma si je me trompe pas:
Code secondaire ou sont toutes les commandes et la gestion de cette fenêtre et des gadget et tout le tralala
Code Principale (Fichier 1, D’où je lance la fenêtre et la gère d'ici)
Suis-je assez clair dans ma demande ?
Re: Comment gérer une fenêtre dans un thread
Publié : dim. 23/mars/2014 21:15
par majikeyric
C'est plutôt une fenêtre qui gère un thread non ?
C'est la fenêtre qui crée le thread, qui lui va faire sa tache en parallèle de la gestion de la boucle d'évènements.
(c'est comme ça que je l'ai fait en tous cas)
Re: Comment gérer une fenêtre dans un thread
Publié : dim. 23/mars/2014 21:55
par Lord Nelson
Bha si tu pouvais faire voir comment tu procède.
Je suis un peut perdus là moi
Dans l'aide il est bien dis que:
Note: Une fenêtre ne devrait pas être ouverte dans un thread, car il y a une limitation sur OS X et Linux. Une erreur débogueur sera levée. Quand une fenêtre est ouverte dans un thread, le thread doit appeler WindowEvent() ou WaitWindowEvent() dans une boucle pour gérer les évènements pour cette fenêtre, car les évènements des fenêtres sont propres à chaque thread.
Or il est aussi dit que:
Note: La boucle d'événements de la fenêtre ne doit pas être traitée dans un thread, car il y a une limitation sur OS X et Linux. Une erreur du débogueur sera soulevée.
Alors moi plus rien comprendre là
Comment ont fais alors

Re: Comment gérer une fenêtre dans un thread
Publié : dim. 23/mars/2014 22:31
par nico
Pourquoi tu veux créer une fenêtre dans un autre thread ?, pourquoi ça ne vas pas le faire dans le thread principal?
Re: Comment gérer une fenêtre dans un thread
Publié : dim. 23/mars/2014 23:24
par Lord Nelson
Pourquoi tu veux créer une fenêtre dans un autre thread ?, pourquoi ça ne vas pas le faire dans le thread principal?
Je sais pas trop comment faire en faite alors je vais donner quelques petit détail pour que vous puissiez m’aiguiller
Je voudrait faire une espèce de console (Non pas une console comme vous l'entendez mais ça y ressemble dans le font)
Une fenêtre avec un éditeur RTF dedans.
Donc ya un code ou l'utilisateur va taper ces commandes pour interagir avec la dite console (Écrire / entrer du texte, afficher des images, etc)
Et donc il dois y avoir le code qui permet de gérer cette fenêtre et les événements que l'utilisateur va entrer mais ça l'utilisateur ne le verra pas, il verras que son code à lui !
Donc je suppose qu'il faut un thread pour gérer la fenêtre et attendre que quelque choses se passe ou que l'utilisateur envoie une commande de par son code
Faut imaginer une console comme la console de PureBasic, on ne gère pas la fenêtre de la console, on l'ouvre, on affiche du texte etc
La c'est pareil sauf que c'est pas une console a proprement parler, je dis console car on va faire de même, interagir avec cette fenêtre en y écrivant du texte, des images, etc
Exemple:
La fenêtre s'ouvre et affiche Blablabla et c'est tout pour cet exemple.
Donc la gestion du code de la fenêtre on ne le voie pas, on ne voie rien, enfin l'utilisateur quoi, lui il s'occupe juste de taper ces commandes et voilà.
Je sais pas si je suis clair

Re: Comment gérer une fenêtre dans un thread
Publié : dim. 23/mars/2014 23:39
par Backup
si si !
Re: Comment gérer une fenêtre dans un thread
Publié : lun. 24/mars/2014 6:52
par graph100
écoute, en faisant une recherche dans mes code j'ai trouvé les 2 suivants :
Désactive le débuggeur pour les lancer sinon l'erreur mentionnée dans l'aide est levée.
Code : Tout sélectionner
;{ init
Structure thread_id
thread_id.l
valeur.l
EndStructure
Global IS_end.b = 0
compteur = 0
Global NewList thread_id.thread_id()
;}
Procedure Thread_Compteur(*id.thread_id)
If *id\valeur > 5
Title$="Thread Timeout"
Y = 60
Else
Title$="Thread Timer"
Y = 120
EndIf
thread_window = OpenWindow(#PB_Any, 200, Y, 200, 25, Title$, #PB_Window_Tool)
If thread_window
thread_textgadget = TextGadget(#PB_Any, 5, 5, 90, 20, "", #PB_Text_Border)
Else
ProcedureReturn
EndIf
time = ElapsedMilliseconds()
Repeat
event = WaitWindowEvent(50)
SetGadgetText(thread_textgadget, Str(ElapsedMilliseconds() - time) + "ms")
If ElapsedMilliseconds() - time > *id\valeur * 1000
event = #PB_Event_CloseWindow
EndIf
Until event = #PB_Event_CloseWindow Or IS_end
If IS_end = 0
ChangeCurrentElement(thread_id(), *id)
DeleteElement(thread_id())
EndIf
CloseWindow(thread_window)
EndProcedure
If OpenWindow(0, 420, 100, 200, 30, "Test", #PB_Window_SystemMenu)
TextGadget(0, 5, 5, 190, 20, "", #PB_Text_Border)
AddWindowTimer(0, 0, 1000) ; ajoute un timer à la fenetre 0, tick toutes les 1 sec
Else
MessageRequester("Erreur", "Impossible de lancer la fenetre principale")
EndIf
Repeat
event = WaitWindowEvent()
If event = #PB_Event_Timer And EventTimer() = 0
compteur + 1
SetGadgetText(0, Str(compteur) + "s")
If compteur = 5
*current.thread_id = AddElement(thread_id())
*current\valeur = 3
*current\thread_id = CreateThread(@Thread_Compteur(), *current)
ElseIf compteur = 10
*current.thread_id = AddElement(thread_id())
*current\valeur = 10
*current\thread_id = CreateThread(@Thread_Compteur(), *current)
compteur = 0
EndIf
EndIf
Until event = #PB_Event_CloseWindow
IS_end = #True
ForEach thread_id()
*current.thread_id = @thread_id()
WaitThread(*current\thread_id)
Next
End
Code : Tout sélectionner
;{ variables Globales, structures
Global EXIT.b = #False
Define.l TT_Aide
;}
Procedure OpenAide(fen_principale.l)
ww_aide = OpenWindow(#PB_Any, WindowX(fen_principale) - 215, WindowY(fen_principale), 200, 400, "Ma fenêtre d'aide", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_Tool)
If ww_aide
EndIf
Repeat
event = WaitWindowEvent(200)
Until event = #PB_Event_CloseWindow Or EXIT
CloseWindow(ww_aide)
EndProcedure
ww_principale = OpenWindow(#PB_Any, 0, 0, 500, 400, "Ma fenêtre principale", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
If ww_principale
gg_button_aide = ButtonGadget(#PB_Any, 10, 10, 200, 20, "Ouvrir la fenetre d'aide")
EndIf
Repeat
event = WaitWindowEvent()
If event = #PB_Event_Gadget
Select EventGadget()
Case gg_button_aide
If IsThread(TT_Aide) = 0
TT_Aide = CreateThread(@OpenAide(), ww_principale)
EndIf
EndSelect
EndIf
Until event = #PB_Event_CloseWindow
EXIT = #True
CloseWindow(ww_principale)
If IsThread(TT_Aide)
WaitThread(TT_Aide, 1000)
EndIf
End
Cependant si je devais reprogrammer ce genre de truc maintenant, je ne m'y prendrais pas de cette façon là.
Regarde avec l'utilisation de la commande EventWindow().
Et ne créé pas tes fenêtres depuis le thread, mais plutot depuis le programme principal.
Simplement, gère les ensuite depuis le thread.
Re: Comment gérer une fenêtre dans un thread
Publié : lun. 24/mars/2014 9:36
par MLD
Salut
Tu peux parfaitement crée une fenêtre et utilisé sa boucle d'évênement dans une procédure. la seule précaution a prendre est que la boucle soit du type : Repeat: ForEver. La sortie de la boucle se faisant par un Break.
J'utilise ceci dans des programmes multi-fenêtres. Donc sans thread.
Re: Comment gérer une fenêtre dans un thread
Publié : lun. 24/mars/2014 10:01
par Lord Nelson
Merci beaucoup pour vos réponses
J'ai procédé comme tel, vous en pensez quoi ?
Si j'ai zappé des choses, je m'en excuse d’avance
Code Secondaire qui gère la fenêtre et tout le reste, nommer le avec l’extension PBI:
Code : Tout sélectionner
Structure StructureFenetre
NumeroFenetre.i
X.i
Y.i
Largeur.i
Hauteur.i
Titre.s
Option.i
EndStructure
Procedure OuvertureFenetre(*Parametres.StructureFenetre)
If OpenWindow(*Parametres \ NumeroFenetre, *Parametres \ X, *Parametres \ Y, *Parametres \ Largeur, *Parametres \ Hauteur, *Parametres \ Titre, *Parametres \ Option)
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
Else
MessageRequester("Erreur lors de l'ouverture de la fenêtre", "Impossible d'ouvrir la fenêtre n° " + Str(NumeroFenetre), #MB_ICONERROR)
EndIf
EndProcedure
Procedure OuvrirFenetre(NumeroFenetre, X, Y, Largeur, Hauteur, Titre$, Option)
*Parametres.StructureFenetre = AllocateMemory(SizeOf(StructureFenetre))
*Parametres \ Hauteur = NumeroFenetre
*Parametres \ X = X
*Parametres \ Y = Y
*Parametres \ Largeur = Largeur
*Parametres \ Hauteur = Hauteur
*Parametres \ Titre = Titre$
*Parametres \ Option = Option
NumeroThreadFenetre = CreateThread(@OuvertureFenetre(), *Parametres)
EndProcedure
Code Principale, c'est là ou l'utilisateur interagir avec la fenêtre, nommer le avec l’extension PB:
Code : Tout sélectionner
XIncludeFile "Votre Code.Pbi"
Enumeration
#Fenetre
EndEnumeration
OuvrirFenetre(#Fenetre, 0, 0, 800, 600, "Console", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
Delay(10000)
Reste plus qu'à comme qui dirait

Re: Comment gérer une fenêtre dans un thread
Publié : lun. 24/mars/2014 17:10
par graph100
c'est une façon de faire. Très bien la structure pour passer les paramètres au thread.
Re: Comment gérer une fenêtre dans un thread
Publié : lun. 24/mars/2014 17:16
par Lord Nelson
Merci, j'ai pris l'exemple super utile tiré de l'aide de PB

Re: Comment gérer une fenêtre dans un thread
Publié : mar. 25/mars/2014 9:55
par Mesa
L'aide est en cours de mis à jour mais ne sera visible que dans la version 5.30 de PB (dans 2 ans). Je posterai une version intermédiaire entre-temps, peut-être cet été.
Il faut lire.
Note: Une fenêtre ne devrait pas être ouverte dans un thread, car il y a une limitation sur OS X et Linux. Une erreur débogueur sera levée.
Même s'il est possible de mettre une fenêtre dans un thread, ça ne concerne que Windows et en plus le bon fonctionnement n'est pas garantie.
Il est donc conseillé de repenser son code afin de n'avoir qu'une seule boucle principale qui gère toutes les fenêtres ( en utilisant : les fenêtres-filles, mdigadget, hidewindow(), #PB_Window_Invisible, ...), c'est plus prudent.
M. .
Re: Comment gérer une fenêtre dans un thread
Publié : lun. 31/mars/2014 15:49
par Lord Nelson
J'ai effacé le sujet en double, je poste tellement que je me souvient même plus de se que je poste
Si ma façon de coder est correcte, je me demande pourquoi PB n'est pas ok lui !
OpenWindow() ne peut être appelée qu'à partir du thread principale.
WindowEvent() et WaitWindowEvent() ne peuvent être appelées qu'à partir de thread principale.
Et comme dis l'aide aussi, tout comme Mesa:
Note: Une fenêtre ne devrait pas être ouverte dans un thread, car il y a une limitation sur OS X et Linux. Une erreur débogueur sera levée.
Je ne sais pas comment faire
Je suis obligé de désactiver le Débogueur pour que cella fonctionne !
Ceci m’embête car sans le débogueur, pas facile de gérer son code
Ma façon fonctionne mais n'est pas correcte et qui plus est quand je veux ajouter des gadgets par la suite à la fenêtre, rien ne va plus !
Qu'elle est la bonne façon de faire svp ?