Page 1 sur 2
Détection d'une fenêtre
Publié : jeu. 12/févr./2004 18:11
par Le Soldat Inconnu
Salut,
Une question, je ne me suis pas encore trop pencher dessus, ci ça trouve, c'est tout bête, mais pour le moment, je vois pas donc je vais sollicité qlq cerveaux du forum
Ma question est la suivante :
Comment faire pour détecter la création d'une nouvelle fenêtre sous windows. Je m'explique, j'ai un prog PB et je veux qu'il détecte quand on crée une nouvelle fenêtre (n'importe quel programme).
Alors si en plus, ça me donne le handle de la fenêtre, ce serait nickel
voilà
A+
Publié : jeu. 12/févr./2004 21:38
par Oliv
Moi je rajouterai, comment savoir si sont programme tourne déjà pour ne pas le lancer une 2ème fois ?
Publié : jeu. 12/févr./2004 21:52
par T€r$@k€n
Moi je rajouterai, comment savoir si sont programme tourne déjà pour ne pas le lancer une 2ème fois ?
Je ne sais pas si c'est possible, mais je pense qu'il suffirait au lancement de ton programme créer un fichier temporaire.
Lors de chaque execution de ton programme il verifira la presence de ce fichier avant de se lancer.
Il ne faut pas oublier par contre de supprimer ce fichier [ quand tu quittes le programme ]...
Ceci est Juste une idée ...
T£r$Ak£n

Publié : jeu. 12/févr./2004 21:57
par Chris
Ceci est Juste une idée ...
C'est même la meilleure pour ce genre de truc!
Il suffit de vérifier la présence du fichier, donc, pas d'accès disque.
Pas de bidouillage dans la base de registre!
L'idéal, quoi!!
Chris

Publié : jeu. 12/févr./2004 22:05
par filperj
Citation:
Moi je rajouterai, comment savoir si sont programme tourne déjà pour ne pas le lancer une 2ème fois ?
Il y a un post sur le forum anglais:
http://purebasic.myforums.net/viewtopic.php?p=24945
J'ai pas tout compris, mais ça a l'air intéressant

Publié : ven. 13/févr./2004 7:36
par Oliv
Merci Filperj, pour Tersaken, oui mais quand le programme plante ? le fichier reste présent........
Publié : ven. 13/févr./2004 7:59
par T€r$@k€n
Oui, J'y ai aussi Penser ...
Il y a encore quelque chose de plus con,
Je ne connais pas assez bien Pure pour savoir si cela est Possible,
Vu que nous sommes dans application, je pense que tu te sers du mode fenetre. Vu que chaque fenetre porte Un Numero, Un Test en debut de programme qui verifirait que la fenetre 1 [ imaginons que ça soit celle de notre Programme ] ...
J'ai Regardé rapidement l'aide, et cela est tout a fait possible ; a mon avis ...
[ EDIT ] A moins que Window porte aussi ses numeros de fenetre !
T£r$Ak£n

Publié : ven. 13/févr./2004 10:16
par julien
si l'exe plante, il suffit de rediriger le programme avec OnError et d'effacer le fichier
J'ai écrit un petit programme avec un fichier de reférence dans les temp et la gestion des erreur, c'est très basique mais ça marche.
Je pense qu'il doit y avoir une API pour ce truc... reste à la trouver
Code : Tout sélectionner
; Code de Julien
OnErrorGoto(?ERREUR)
; vérifie dans les temp
temp$ = Space(1024):GetTempPath_(1024,temp$)
If FileSize(temp$+"FichierdeRef.run")<>-1
MessageRequester("DSL","Le programme est déja lancé en mémoire !",#MB_ICONINFORMATION)
End
Else
CreateFile(1, temp$+"FichierdeRef.run")
CloseFile(1)
EndIf
If MessageRequester("","Voulez-vous provoquer une erreur ?",#PB_MessageRequester_YesNo)=6
For k=0 To 5
erreur=10/k ; division par 0
Next k
EndIf
MessageRequester("","Le programme est fini",#MB_ICONINFORMATION)
DeleteFile(temp$+"FichierdeRef.run")
End
ERREUR:
MessageRequester("ERREUR","Ce programme va être fermé car il a effectué une"+Chr(10)+"operation non conforme voulue par le programmeur",#MB_ICONERROR)
DeleteFile(temp$+"FichierdeRef.run")
Publié : ven. 13/févr./2004 10:39
par julien
ou mieux, si le titre de la fenêtre est statique, par exemple : "MonProg_By_julien"
il suffit de faire ceci :
Code : Tout sélectionner
; Code de Julien
; c'est la procedure qui permet cela
Procedure exelance2fois(nomfenetre$)
F=FindWindow_(0, nomfenetre$)
If F<>0
ProcedureReturn 1 ; retourne 1 si détecté
Else
ProcedureReturn 0 ; retourne 1 si détecté
EndIf
EndProcedure
; appel de la procedure
res=exelance2fois("MonProg_By_julien")
If res=1
MessageRequester("DSL","Le programme est déja lancé en mémoire !",#MB_ICONINFORMATION)
End
EndIf
;*********** Partie application
Enumeration
#Window_0
EndEnumeration
;- Gadget Constants
;
Enumeration
#Text_0
EndEnumeration
Procedure Open_Window_0()
If OpenWindow(#Window_0, 337, 249, 208, 206, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , "MonProg_By_julien")
If CreateGadgetList(WindowID())
TextGadget(#Text_0, 20, 70, 180, 20, "Relance l'application sans quitter !")
EndIf
EndIf
EndProcedure
Open_Window_0()
Repeat
Event = WaitWindowEvent()
If Event = #PB_EventGadget
;Debug "WindowID: " + Str(EventWindowID())
GadgetID = EventGadgetID()
EndIf
Until Event = #PB_EventCloseWindow
End
.... Par contre si quelqu'un sait comment retrouver la handle d'une fenêtre avec uns partie du titre... cela serai intérrésant.... même pour les titre dynamique...

Publié : ven. 13/févr./2004 10:57
par Fred
Une bonne solution est d'enumerer les fenetres ouvertes sur le system toute les secondes par exemple:
Code : Tout sélectionner
Global OfficeRunning
Procedure.l EnumWindowsProc(hFind, lParam)
WindowName.s = Space(255)
If GetWindowText_(hFind, WindowName, 255)
If FindString(WindowName, "Microsoft Office", 1)
If FindString(WindowName, "Word", 1) Or FindString(WindowName, "Excel", 1)
OfficeRunning = 1
EndIf
ElseIf FindString(WindowName, "Microsoft Word", 1) Or FindString(WindowName, "Microsoft Excel", 1)
OfficeRunning = 1
EndIf
EndIf
ProcedureReturn 1
EndProcedure
EnumWindows_(@EnumWindowsProc(), 0)
Un code qui m'a servi pour savoir si Office etait lancé.
Re: Détection d'une fenêtre
Publié : ven. 13/févr./2004 12:44
par nico
Le Soldat Inconnu a écrit :Salut,
Comment faire pour détecter la création d'une nouvelle fenêtre sous windows. Je m'explique, j'ai un prog PB et je veux qu'il détecte quand on crée une nouvelle fenêtre (n'importe quel programme).
Alors si en plus, ça me donne le handle de la fenêtre, ce serait nickel
voilà
A+
Tu pourrait scanner les fenetres ouvertes plusieurs fois dans ton programme, comparer les résultats obtenus...et à partir de là, tu peux avoir tous les renseignements que tu désires.
Voici un petit programme pour t'aider à lister les programme en cours:
Code : Tout sélectionner
Enumeration
#Window_0
EndEnumeration
Enumeration
#ListIcon_0
EndEnumeration
Dim WindowName.s(200)
Dim WindowClass.s (200)
For a=0 To 199
WindowName(a)=Space(200)
WindowClass(a)=Space(200)
Next a
Global compt.l
Procedure ProcedureEnum(WindowID.l , lParam.l)
GetWindowText_(WindowID,@WindowName(compt),200)
GetClassName_(WindowID,@WindowClass(compt),200)
Getwindowrect_(WindowID,@dimension.RECT)
hwndfenetre=FindWindow_(WindowClass(compt),WindowName(compt))
If WindowName(compt)<>"" :;pour afficher que les fenetres qui portent un nom
AddGadgetItem(#ListIcon_0, compt, WindowName(compt)+Chr(10)+Str(hwndfenetre)+Chr(10)+Str(dimension\right-dimension\left)+"/"+Str(dimension\bottom-dimension\Top)+Chr(10)+WindowClass(compt))
compt=compt+1
EndIf
ProcedureReturn 1
EndProcedure
If OpenWindow(#Window_0, 200, 320, 610, 210, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , "Listing")
If CreateMenu(0, WindowID())
MenuTitle("Rafraichir")
MenuItem( 1, "Go")
EndIf
If CreateGadgetList(WindowID())
ListIconGadget(#ListIcon_0, 10, 10, 600, 200, "Nom", 200, #PB_ListIcon_GridLines)
AddGadgetColumn(#ListIcon_0, 2, "Handle", 100)
AddGadgetColumn(#ListIcon_0, 3, "Long/Larg", 100)
AddGadgetColumn(#ListIcon_0, 4, "Class", 200)
EndIf
EndIf
OpenLibrary(0,"user32.dll")
CallFunction(0,"EnumWindows",@ProcedureEnum(),0)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_EventMenu
Select EventMenuID()
Case 1
compt=0
CallFunction(0,"EnumWindows",@ProcedureEnum(),0)
EndSelect
EndSelect
Until Event = #PB_EventCloseWindow
End
Publié : ven. 13/févr./2004 17:40
par nico
Je l'ai complété:
Exécuter le programme avec le débugger, et ensuite lancer un autre programme , son titre et son handle apparaîtront dans le débugger.
Suivant le programme, plusieurs fenêtres peuvent surgir.
En ce qui me concerne, à chaque fois que je lance un programme, j'ai une fenêtre "program manager" qui apparaît. ???
Code : Tout sélectionner
Enumeration
#Window_0
EndEnumeration
Enumeration
#ListIcon_0
EndEnumeration
Dim WindowName.s(200)
Dim WindowNamecompare.s(200)
Dim resultatcompare.s(200)
Dim WindowClass.s (200)
Dim hwndfenetre.l (200)
For a=0 To 199
WindowName(a)=Space(200)
WindowNamecompare(a)=Space(200)
resultatcompare(a)=Space(200)
WindowClass(a)=Space(200)
Next a
Global compt.l,nombre.l
Procedure compare()
For a=0 To nombre-1
For b=0 To nombre-1
If WindowName(a)=WindowNamecompare(b)
resultatcompare(a)=""
EndIf
Next b
Next a
For a=0 To nombre-1
If resultatcompare(a)<>""
Debug "Titre: "+resultatcompare(a)+" Handle: "+Str(hwndfenetre(a))
EndIf
Next
For a=0 To 199
WindowNamecompare(a)=WindowName(a)
Next a
EndProcedure
Procedure ProcedureEnum(Window.l , lParam.l)
GetWindowText_(Window,@WindowName(compt),200)
GetClassName_(Window,@WindowClass(compt),200)
Getwindowrect_(Window,@dimension.RECT)
hwndfenetre(compt)=FindWindow_(WindowClass(compt),WindowName(compt))
If WindowName(compt)<>"" :;pour afficher que les fenetres qui portent un nom
If IsWindowVisible_(hwndfenetre(compt)) :;seulement les fenêtres visibles
AddGadgetItem(#ListIcon_0, compt, WindowName(compt)+Chr(10)+Str(hwndfenetre(compt))+Chr(10)+Str(dimension\right-dimension\left)+"/"+Str(dimension\bottom-dimension\Top)+Chr(10)+WindowClass(compt))
resultatcompare(compt)= WindowName(compt)
compt=compt+1
EndIf
EndIf
ProcedureReturn 1
EndProcedure
Procedure timerProcedure(WindowID, Message, wParam, lParam)
Resultat.l = #PB_ProcessPureBasicEvents
Select Message
Case #wm_timer
compt=0
ClearGadgetItemList(0)
CallFunction(0,"EnumWindows",@ProcedureEnum(),lParam)
nombre = CountGadgetItems(#ListIcon_0)
compare()
;Debug nombre
EndSelect
ProcedureReturn Resultat
EndProcedure
If OpenWindow(#Window_0, 200, 160, 620, 450, #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar , "Listing")
If CreateGadgetList(WindowID())
ListIconGadget(#ListIcon_0, 10, 10, 600, 400, "Nom", 200, #PB_ListIcon_GridLines)
AddGadgetColumn(#ListIcon_0, 2, "Handle", 100)
AddGadgetColumn(#ListIcon_0, 3, "Long/Larg", 100)
AddGadgetColumn(#ListIcon_0, 4, "Class", 200)
EndIf
EndIf
OpenLibrary(0,"user32.dll")
CallFunction(0,"EnumWindows",@ProcedureEnum(),0)
For a=0 To 199
WindowNamecompare(a)=WindowName(a)
Next a
settimer_( WindowID(),1,2000,0)
SetWindowCallback(@timerProcedure())
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_EventCloseWindow
killtimer_(WindowID(),1)
quit.l=1
EndSelect
Until quit=1
Publié : ven. 13/févr./2004 17:47
par julien
Pour Detecter Si le Programme est lancé plusieurs fois, il y'a une
librairie qui le fait tres bien :
http://www.purearea.net/pb/download/use ... unning.zip
Voici un petit code pour l'utiliser
Code : Tout sélectionner
OpenConsole()
PrintN("Compiler un Exe pour tester cette librairie")
MyApp.s="App"
Result=AppRunning(MyApp.s)
If Result=0
PrintN ("Application lance une fois")
Else
PrintN ("Application lance plusieurs fois")
EndIf
Repeat
Delay(10)
ForEver
Publié : ven. 13/févr./2004 19:01
par Invité
La méthode pour détecter s'il y a plusieurs instances d'un même programme est celle-ci:
Code : Tout sélectionner
#MUTEX_ALL_ACCESS = $1F0001
Application.s="Essai.exe"
If OpenMutex_(#MUTEX_ALL_ACCESS,#False,Application)=0
If CreateMutex_(#Null, #True, Application)= 0
;Fin du programme mutex non créer
End
EndIf
Else
MessageRequester("Information", "programme déja ouvert", #PB_MessageRequester_Ok)
End
EndIf
;Le reste du code ici
MessageRequester("Information", "Fin du programme", #PB_MessageRequester_Ok)
End
sinon on peut utiliser FindWindow.

Publié : ven. 13/févr./2004 19:03
par nico
Je me fait avoir à chaque fois avec le Login, désolé.
