Page 1 sur 2
Fermer programme en arriére-plan
Publié : mar. 22/déc./2015 10:33
par JohnJohnsonSHERMAN
Salut à tous !
Je débute en purebasic, et j´ai réalisé il y a quelque temps une application qui permet de choisir une musique et de la lire en arriére plan (sans fenetre ouverte). Seulement pour la fermer, faut passer par le gestionnaire des taches. Y a t-il une autre solution? (J´ai été voir quelques exemples de codes sur le forum, mais ils sont tous basés sur l´api windows "FindWindow_()", qui demande un titr de fenetre, et donc une fenetre.

) Comment fermer un truc en arriére plan alors?
Merci d´avance de vos réponses ! (Et joyeux noel a tous)

Re: Fermer programme en arriére-plan
Publié : mar. 22/déc./2015 10:49
par microdevweb
Tu doit lancer ton exécutable avec RunProgram() depuis ton application principale, qui va renvoyer un Id après tu peux utiliser CloseProgram().
Maintenant il à moyen de faire des taches en arrière plan sans forcement lancer une exe,
- avec un timer window
- avec un thread
- Dans le boucle principal
Re: Fermer programme en arriére-plan
Publié : mar. 22/déc./2015 10:50
par Marc56
JohnJohnsonSHERMAN a écrit :Salut à tous !
Je débute en purebasic, et j´ai réalisé il y a quelque temps une application qui permet de choisir une musique et de la lire en arriére plan (sans fenetre ouverte). Seulement pour la fermer, faut passer par le gestionnaire des taches. Y a t-il une autre solution? (J´ai été voir quelques exemples de codes sur le forum, mais ils sont tous basés sur l´api windows "FindWindow_()", qui demande un titr de fenetre, et donc une fenetre.

) Comment fermer un truc en arriére plan alors?
Merci d´avance de vos réponses ! (Et joyeux noel a tous)

Une icône et un menu dans la barre de mini-icône (SysTray) est la méthode classique pour gérer un programme qui reste en fond.
Regarde
SysTray() et l'exemple qui y est donné.
Tu peut ainsi ajouter un menu contextuel à cette icône avec choix de la playliste, arrêt, pause, suivant etc
L'autre solution est de faire un service, mais c'est plus complexe.

Re: Fermer programme en arriére-plan
Publié : mar. 22/déc./2015 10:56
par JohnJohnsonSHERMAN
Bie vu pour le SysTray!!! J´avais vu, mais jamais utilisé, je m´y mets de ce pas! (Sinon, ClosProgram(), c´est quand on ferme un canal entre deux exe non? Pour fermer un exe, c´est pas plutot KillProgram(program)?)
En tout ca merci!
Re: Fermer programme en arriére-plan
Publié : mar. 22/déc./2015 11:15
par JohnJohnsonSHERMAN
Oui maitre
Je demandais juste ca parcequ´initialement, j´avais fait un premier exe qui lit la musique, et un second chargé de le fermer (ce qui évidemment ne fonctionne pas, KillProgram demandant un RunProgram auparavant). La fonction end, je la connais, l´ayant déja utilisée.
Mais en effet si je pars sur un mode systray, je pense qu´il n´est pas nécessaire de le fermer , le but étant un petit programme qui laisse l´utilisateur choisir une musique, et qui la lit en arriére plan. Et pourquoi pas ajouter un tache windows via le planificateur de tahces pour que le prog se lance au démarrage...
Bon, merci pour ces réponses rapides, me este plus qu´a lancer purebassic maintenant!
Re: Fermer programme en arriére-plan
Publié : mar. 22/déc./2015 11:44
par Marc56
Un conseil en passant pour que tu ne buttes pas sur la même pierre que moi
Dans mon application, j'utilise les fonctions de la lib PB
Movie (qui comme son nom ne l'indique pas, lit les MP3).
Cela marche très bien, mais le jour où j'ai voulu faire une
playlist (simple fichier texte avec les noms de fichiers à jouer l'un après l'autre), j'ai mis du temps pour comprendre pourquoi il
lisait bien ma liste de fichiers, mais ne jouait toujours
que le dernier ?
J'ai fini par comprendre que
PlayMovie() joue le fichier dans un process séparé (logique pour de la musique) et donc par défaut ne se soucis pas de savoir si le premier morceau est terminé avant d'envoyer le suivant
Problème résolu avec une boucle qui test si un morceau est en cours (if
IsMovie()) avant d'envoyer le suivant.
Donc il faut une boucle, par exemple 1 seconde
Code : Tout sélectionner
Chaque Seconde
Si Mode_Lecture = Oui
Si PAS de fichier en cours de lecture (Not IsMovie(Fichier)
Envoyer le fichier suivant
Simple quand on a compris, mais j'ai mis plusieurs jours à m'arracher le peu de cheveux qui restent

Re: Fermer programme en arriére-plan
Publié : mar. 22/déc./2015 11:47
par JohnJohnsonSHERMAN
Merci d'y avoir pensé pour moi....

Bon J'ai fait un p'tit bout de code (incomplet), mais bon c'est l'architecture principale du truc
Code : Tout sélectionner
If LoadImage(1,"blabla")
Else
MessageRequester("Erreur","L'icone ne peut etre chargée !")
EndIf
Enumeration
#icone
#pause
#stop
#open
EndEnumeration
OpenWindow(0,11,10,300,150,"SherPlay", #PB_Window_TitleBar | #PB_Window_Tool | #PB_Window_ScreenCentered)
status=#True
AddSysTrayIcon(#icone,WindowID(0),ImageID(1))
Repeat
Event=WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case #open
Case #pause
Case #stop
EndSelect
Case #PB_Event_SysTray
Select EventGadget()
Case #icone
If status=#True
HideWindow(0,#True)
status=#False
Else
HideWindow(0,#False)
status=#True
EndIf
EndSelect
EndSelect
ForEver
Voila ! Qu'en pensez-vous?
Re: Fermer programme en arriére-plan
Publié : mar. 22/déc./2015 12:01
par Marc56
JohnJohnsonSHERMAN a écrit :Voila ! Qu'en pensez-vous?
Quasi-parfait. Tu débutes peut-être en PureBasic, mais pas en programmation, ou alors tu assimiles très vite
Profite de l'indentation auto de PB (CTRL+A puis CTRL+I) et il te met tout au carré, ça permet de voir immédiatement si quelque-chose est mal fermé.
Use et abuse de la commande
Debug (ce sera ignoré lors de la compilation si compilation sans débug)
Code : Tout sélectionner
If LoadImage(1,"blabla")
Debug "Image chargée OK - ID = " + Str(ImageID(1))
Else
MessageRequester("Erreur","L'icone ne peut etre chargée !")
End ; Penser à quitter si erreur fatale (ou ProcedureReturn si code non bloquant dans une Procedure)
EndIf
Met des constantes plutôt que des numéros pour les objets même pour un petit programme
(on a vite fait de perdre le fil et de réutiliser le même numéro)
WindowID(0) -> WindowID(#Win_Main)

Re: Fermer programme en arriére-plan
Publié : mar. 22/déc./2015 12:44
par microdevweb
@JohnJohnsonSHERMAN,
Perso je te conseille l'usage des bind à la place de la gestion événementiel dans la boucle
Code : Tout sélectionner
Enumeration Img
#Icone
EndEnumeration
Enumeration Form
#MainForm
#MainSysTray
#MainBtPlay
#MainBtStop
#MainBtPause
EndEnumeration
Global gStatus.b=#False
Procedure EventBtPlay()
Debug "Event Play"
EndProcedure
Procedure EventBtStop()
Debug "Event Stop"
EndProcedure
Procedure EventBtPause()
Debug "Event Stop"
EndProcedure
Procedure EventMainForm()
Select gStatus
Case #True
HideWindow(#MainForm,#True)
gStatus=#False
Case #False
HideWindow(#MainForm,#False)
gStatus=#True
EndSelect
EndProcedure
Procedure OpenMainForm()
Protected Flag=#PB_Window_TitleBar|#PB_Window_Tool|#PB_Window_ScreenCentered
Protected M=10,X=M,Y=M,H=30,W=60
LoadImage(#Icone,"make.ico")
OpenWindow(#MainForm,0,0,300,150,"SherPlay",Flag)
AddSysTrayIcon(#MainSysTray,WindowID(#MainForm),ImageID(#Icone))
gStatus=#True
ButtonGadget(#MainBtPlay,X,Y,W,H,"Play")
X+M+W
ButtonGadget(#MainBtStop,X,Y,W,H,"Stop")
X+M+W
ButtonGadget(#MainBtPause,X,Y,W,H,"Pause")
BindGadgetEvent(#MainBtPlay,@EventBtPlay())
BindGadgetEvent(#MainBtStop,@EventBtStop())
BindGadgetEvent(#MainBtPause,@EventBtPause())
BindEvent(#PB_Event_SysTray,@EventMainForm(),#MainForm)
EndProcedure
OpenMainForm()
Repeat:WaitWindowEvent():ForEver
Re: Fermer programme en arriére-plan
Publié : mar. 22/déc./2015 13:03
par JohnJohnsonSHERMAN
Yes! tout marche nickel maintenant!!
Merci de votre aide les amis!!
Re: Fermer programme en arriére-plan
Publié : mar. 22/déc./2015 18:13
par JohnJohnsonSHERMAN
Encore un truc : Est-ce que c'est possible avec PureBasic ou avec une api de faire afficher une notification a une icone systray? (pas une tooltip, le genre de truc "une mise a jour avast est dispo" qui poppe juste sur l'icone) ?
Merci d'avance
Re: Fermer programme en arriére-plan
Publié : mer. 23/déc./2015 10:49
par microdevweb
Tu peux (window only) créer une fenêtre transparente et y dessiner par exemple du texte ou un image png, mon exemple est avec du texte en rouge, la couleur noir est transparente
Code : Tout sélectionner
Enumeration Img
#Icone
EndEnumeration
Enumeration Font
#InfoFont
EndEnumeration
Enumeration Form
#MainForm
#InfoForm
#InfoCanvas
#MainSysTray
#MainBtPlay
#MainBtStop
#MainBtPause
EndEnumeration
LoadFont(#InfoFont,"Arial",36,#PB_Font_HighQuality)
Global gStatus.b=#False
Declare OpenInfo()
Procedure EventBtPlay()
Debug "Event Play"
EndProcedure
Procedure EventBtStop()
Debug "Event Stop"
EndProcedure
Procedure EventBtPause()
Debug "Event Stop"
EndProcedure
Procedure EventMainForm()
Select gStatus
Case #True
HideWindow(#MainForm,#True)
CloseWindow(#InfoForm)
gStatus=#False
Case #False
HideWindow(#MainForm,#False)
OpenInfo()
gStatus=#True
EndSelect
EndProcedure
Procedure OpenInfo()
OpenWindow(#InfoForm,400,400,200,200,"",#PB_Window_BorderLess)
SetWindowLong_(WindowID(#InfoForm), #GWL_EXSTYLE, #WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID(#InfoForm), RGB(0,0,0), 0, #LWA_COLORKEY)
CanvasGadget(#InfoCanvas,0,0,WindowWidth(#InfoForm),WindowHeight(#InfoForm))
StartDrawing(CanvasOutput(#InfoCanvas))
Box(0,0,GadgetWidth(#InfoCanvas),GadgetHeight(#InfoCanvas),RGB(0,0,0))
DrawingFont(FontID(#InfoFont))
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(30,30,"Teste",RGB(255,0,0))
StopDrawing()
EndProcedure
Procedure OpenMainForm()
Protected Flag=#PB_Window_TitleBar|#PB_Window_Tool|#PB_Window_ScreenCentered
Protected M=10,X=M,Y=M,H=30,W=60
LoadImage(#Icone,"make.ico")
OpenWindow(#MainForm,0,0,300,150,"SherPlay",Flag)
AddSysTrayIcon(#MainSysTray,WindowID(#MainForm),ImageID(#Icone))
gStatus=#True
ButtonGadget(#MainBtPlay,X,Y,W,H,"Play")
X+M+W
ButtonGadget(#MainBtStop,X,Y,W,H,"Stop")
X+M+W
ButtonGadget(#MainBtPause,X,Y,W,H,"Pause")
BindGadgetEvent(#MainBtPlay,@EventBtPlay())
BindGadgetEvent(#MainBtStop,@EventBtStop())
BindGadgetEvent(#MainBtPause,@EventBtPause())
BindEvent(#PB_Event_SysTray,@EventMainForm(),#MainForm)
OpenInfo()
EndProcedure
OpenMainForm()
Repeat:WaitWindowEvent():ForEver
Re: Fermer programme en arriére-plan
Publié : mer. 23/déc./2015 11:30
par JohnJohnsonSHERMAN
Arf.. j'ai la démo gratuite, donc pas d'api pour moi... Dommage. Mais bon c'est pas grave, j'ai le programme que je voulais... tant pis pour les notifications (au pire on s'en fout c'est qu'un détail).
Re: Fermer programme en arriére-plan
Publié : mer. 23/déc./2015 17:11
par venom
Après tu peut sans APi tu fait afficher une fenêtre sans bordure en bas a droite de l’écran en récupérant les donner de ce dernier.
Mais c'est sur que ça ne fera pas une bulle qui sera rediriger vers ton icône.
@++
Re: Fermer programme en arriére-plan
Publié : mer. 23/déc./2015 17:47
par JohnJohnsonSHERMAN
Ouaip, la fenétre sans bordure je l´ai déja fait (je trouve le #PB_Window_Tool dégeu).
Mais comment que c´est qu´on fait pour la déplacer (oh celui ci exigent hein !

)?
J´ai essayé avec un bouton mais ca fait de la merde, sinon ca doit etre possible avec un CanvasGadget en récupérant les coordonnées de la souris, mais dans le cas du canvas, ca risque pas de gener les gadgets qui sont "au dessus" si je le mets au fond de la fenetre?