[VB.NET] - Tester existence fenetre et la fermer

jordane45 Messages postés 38221 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 17 juillet 2024 - 4 juil. 2012 à 10:39
 Utilisateur anonyme - 5 juil. 2012 à 22:10
Bonjour,

Je bloque sur la question suivante :
Comment faire pour détécter une fenêtre** dont le titre contient [titre_a_tester] et la fermer ?
[** Fenêtre provenant d'un programme externe ]

Pour l'instant je detecte bien si ma fenetre existe :
Private Function WindowExists(ByVal title As String) As Boolean
        'teste l'existence d'une fenetre dont le titre contient...
        Return Process.GetProcesses().Where(Function(p) p.MainWindowTitle Like title).Count() > 0
    End Function

'Teste si la fentre dont le titre commence par vb_net existe
If WindowExists("vb_net*")=true then Msgbox "OK"



Ensuite pour fermer cette fenêtre, comment puis-je faire ? [auirez-vous des exemples de code ? ]
Sachant qu'on peut :
- Fermer la fenetre par la croix
- Valider la fenetre en cliquant sur le bouton OK (ou en envoyant en ENTER )


Merci pour votre aide.

Cordialement,
______________________________________________________
Règles du forum à lire avant de poster une question : ICI

8 réponses

Utilisateur anonyme
4 juil. 2012 à 19:54
Bonsoir,

Tu peux faire une fonction comme celle-ci :
Private Function GetProcessByWindowTitle(ByVal titre As String) As Process
    'requete de test fenetre
    Dim requete As IEnumerable(Of Process) From p As Process In Process.GetProcesses() Where p.MainWindowTitle titre
    For Each p As Process In requete
        'on retourne le premier process venu
        Return p
    Next
    Return Nothing
End Function


Et tester comme ceci :
Dim p As Process = GetProcessByWindowTitle("Calculatrice")
If p IsNot Nothing Then
    MessageBox.Show(p.ProcessName & " (" & p.MainWindowTitle & ") existe")
    'arret du process
    p.Kill()
Else
     MessageBox.Show("Process inexistant")
End If
jordane45 Messages postés 38221 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 17 juillet 2024 344
5 juil. 2012 à 08:28
Bonjour,
Merci pour ta réponse, mais mon souci n'est pas de fermer le programme en entier...mais juste quelques fenetres.

Par exemple, dans un programme "toto" une fenêtre d'erreur( genre msgbox) apparait.. je veux juste fermer cette fenêtre sans fermer le programme "toto".

Dans mon cas actuel, Il faudrait donc que je trouve le handle de la fenêtre puis que je puisse lui envoyer un "ENTER" .. ou que j'utilise la croix.

Apres quelques recherches, il semble que l'on puisse utiliser un sendmessage ( ou postmessage) pour réaliser une sorte de sendkeys...il faudrait donc que je puisse prendre le Focus sur la fenêtre dont le titre contient le texte recherché.



Cordialement,
Jordane,
______________________________________________________
Règles du forum à lire avant de poster une question : ICI
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 209
5 juil. 2012 à 08:41
Bonjour,

Ce qui se traduit par :
- "espionner" en permanence (avec un timer, donc) l'apparition de toute nouvelle fenêtre
- déterminer son handle
- en analyser la "nature" exacte
- décider ou non de la "tuer" (en fonction de quoi, pour en être certain ?)

Je crains fort que, si tu y parviens (et ... sans failles maladroites ...) ce sera à un coût plus que significatif de tes ressources !
________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
jordane45 Messages postés 38221 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 17 juillet 2024 344
5 juil. 2012 à 11:42
"espionner" en permanence

Non,
en fait un thread se lancera lorsque j'effectuerai certaines opérations afin de vérifier qu'une fenetre d'erreur n'apparaisse pas et sinon la fermera.

(en fonction de quoi, pour en être certain ?)

Juste son titre..Si le titre contient "Erreur d'execution - Error Number "

si tu y parviens (et ... sans failles maladroites ...) ce sera à un coût plus que significatif de tes ressources !

Certe... il y a un cout... mais malheureusement nécessaire.

Pour vous justifier mon besoin :
J'automatise des traitements dans une application...
Le souci c'est que les commandes disponibles (en COM) sont assez limitées.
Par exemple un Monappli.GetValue, si le champ est vide, génère une fenêtre d'erreur impossible à intercepter par programmation..(sauf par son titre )


Mais peu importe le pourquoi.. ma question étant :
Déterminer si une fenetre dont le titre contient (entierement ou partiellement) ["xx Ma chaine de caracteres recherchée xx"] existe.
Si oui, récupérer son Handle pour pouvoir y faire un "sendKeys" (ou équivalent) .


Merci pour votre aide.


Cordialement,
Jordane,
______________________________________________________
Règles du forum à lire avant de poster une question : ICI

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 209
5 juil. 2012 à 13:50
Désolé, mais tu ne pourras dans ce cas pas échapper à la première nécessité, à savoir :
- "espionner" en permanence (avec un timer, donc) l'apparition de toute nouvelle fenêtre


Commence donc par ce premier "espionnage".
Quel code as-tu tenté pour y parvenir ?
On ne pourra parler du "reste", pas à pas, qu'un fois passée cette étape (la plus coûteuse, en passant ...)
(-Et sans même savoir, à ce "petit" stade, si la fenêtre en cours pourra "accepter" tes "intrusions", notamment si en direct X (jeux, entre autres ...). C'est à dire : un premier "travail" pour, peut-être, quelque chose d'irréalisable in fine ... Juste pour le "plaisir" de travailler, donc ...)
________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
Utilisateur anonyme
5 juil. 2012 à 21:26
Le problème se situe dans ton premier message.
Tu dis :
Pour l'instant je detecte bien si ma fenetre existe
Et tu la trouves, dis-tu, grâce à MainWindowTitle.
Le problème est que, si tu ferme MainWindowTitle, tu fermeras le programme en entier.
Utilisateur anonyme
5 juil. 2012 à 21:36
Sinon il y a ce code que j'ai posté tantôt et qui pourrait coller à ton problème.
Il s'agit ici de retrouver le handle d'un programme, ici calc (calculatrice windows) et de récupérer le handle d'un objet (un bouton par exemple) à une coordonnée bien précise :

Option Strict On
Imports System.Runtime.InteropServices
Public Class Form1
    <DllImport("user32.dll")> _
    Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByRef lParam As IntPtr) As IntPtr
    End Function

    <DllImport("user32.dll")> _
    Shared Function ChildWindowFromPoint(ByVal hWnd As IntPtr, ByVal pnt As Point) As IntPtr
    End Function

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'recherche du process calculatrice
        Dim p() As Process = Process.GetProcessesByName("calc")
        's'il existe ...
        If p.Length > 0 Then
            'déterminatrion du handle de la calculatrice
            Dim handle_calc As IntPtr = p(0).MainWindowHandle
            's'il existe ...
            If handle_calc <> IntPtr.Zero Then
                'point (à changer) sur lequel appliquer le clic (ici le bouton 4)
                Dim point_calc As Point = New Point(70, 120)
                'recherche du handle de l'objet sur lequel cliquer selon ses coordonnées
                Dim handle_objet As IntPtr = ChildWindowFromPoint(handle_calc, point_calc)
                's'il existe...
                If handle_objet <> IntPtr.Zero Then
                    'on clique dessus
                    SendMessage(handle_objet, &HF5&, 1, IntPtr.Zero)
                End If
            End If
        End If
    End Sub

End Class
Utilisateur anonyme
5 juil. 2012 à 22:10
Et peut-être que le fait de rajouter au code juste au dessus, la fonction suivante :
<DllImport("user32.dll")> _
Shared Function GetTopWindow(ByVal hWnd As IntPtr) As IntPtr
End Function
... te permettra de retrouver le handle de la fenêtre de ton fameux message.
A tester...
Rejoignez-nous