Obtenir les noms des fenêtres dans la barre des tâches (partiellement résolu) [Résolu]

Signaler
Messages postés
661
Date d'inscription
vendredi 2 décembre 2005
Statut
Membre
Dernière intervention
23 mars 2011
-
Messages postés
661
Date d'inscription
vendredi 2 décembre 2005
Statut
Membre
Dernière intervention
23 mars 2011
-
Salut,

Voilà mon soucis, j'ai reussi à faire un petit programme qui me liste les noms des fenêtres ouvertes et qui apparaissent dans la barre des tâches. Mais en réalité en plus d'afficher le nom de ces fenêtres, il me liste plein d'autres choses. Je mets le code de mon programme en dessous :

Public Class Form1

    Const WM_GETTEXT As Long = &HD
    Const WM_GETTEXTLENGTH As Long = &HE

    Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Integer, ByVal lpString As String, ByVal cch As Integer) As Integer
    Private Declare Function EnumWindows Lib "user32" (ByVal x As MyDelegateCallBack, ByVal y As Integer) As Integer
    Private Declare Auto Function SendMessageA Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByRef lParam As IntPtr) As IntPtr
    Public Delegate Function MyDelegateCallBack(ByVal hwnd As Integer, ByVal lParam As Integer) As Boolean
    Private Declare Auto Function SendMessageString Lib "user32.dll" Alias "SendMessage" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wparam As Integer, ByVal lparam As System.Text.StringBuilder) As IntPtr

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim del As MyDelegateCallBack
        del = New MyDelegateCallBack(AddressOf EnumOutput)
        EnumWindows(del, 0)
        EnumWindows(AddressOf EnumOutput, 0)
    End Sub

    Public Function EnumOutput(ByVal hwnd As Integer, ByVal lParam As Integer) As Boolean
        Dim texte As String

        texte = GetWindowText(hwnd)
        If texte <> "" Then
            MsgBox(texte)
        End If
        Return True
    End Function

    Function GetWindowText(ByVal WindowHandle As IntPtr) As String

        Dim ptrRet As IntPtr
        Dim ptrLength As IntPtr

        'get length for buffer...
        ptrLength = SendMessageA(WindowHandle, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero)

        'create buffer for return value...
        Dim sb As New System.Text.StringBuilder(ptrLength.ToInt32 + 1)

        'get window text...
        ptrRet = SendMessageString(WindowHandle, WM_GETTEXT, ptrLength.ToInt32 + 1, sb)

        'get return value...
        Return sb.ToString

    End Function
  
End Class, ----

(Coloration syntaxique automatique par Kenji)

Merci, si vous trouvez comment ne lister que les fenêtres dans la barre des tâches, je vous en serez très reconnaissant 

14 réponses

Messages postés
3172
Date d'inscription
dimanche 15 février 2004
Statut
Membre
Dernière intervention
9 avril 2017
30
Tiens pour faire plus simple avec le framework (désolé, j'avais pas pensé avant, j'étais parti sur les apis)






For Each Process As System.Diagnostics.Process In System.Diagnostics.Process.GetProcesses()
  If Not Process.MainWindowHandle = System.IntPtr.Zero Then
    If Not String.IsNullOrEmpty(Process.MainWindowTitle) Then
      System.Windows.Forms.MessageBox.Show(Process.MainWindowTitle)
    End If
  End If
Next,

----

(Coloration syntaxique automatique par Kenji)







__________
Kenji
Messages postés
2215
Date d'inscription
mardi 11 novembre 2003
Statut
Membre
Dernière intervention
16 juillet 2009
1
Les fenetres qui apparaissent dans la barre des taches sont appelées "les taches".
Elles répondent à des critères :

'              Critères :      - Visible

'                              - Avoir un titre

'                              - Pas de parent

'                              - Pas de propriétaire

'                              - ça ne doit pas etre le TaskManager (Progman)

Voici un lien VB6 d'une fonction qui teste si la fenetre est bien une tache, si jamais tu n'y arrive pas avec ce que je t'ai dit :
http://vbsystemlibrary.free.fr/code.php?ID=39

Voilà j'espère que j'ai répondu à ta question

- MadMatt -
Vb System Library
Messages postés
661
Date d'inscription
vendredi 2 décembre 2005
Statut
Membre
Dernière intervention
23 mars 2011
8
Salut,

J'ai trouvé cà très intéressant et j'ai pu l'adapté facilement en vb.net mais j'ai un problème et j'ai jamais su comment le régler :

Merci
Messages postés
2215
Date d'inscription
mardi 11 novembre 2003
Statut
Membre
Dernière intervention
16 juillet 2009
1
Ah mince j'ai jamais vu ça, est ce que à tout hasard "IsWindowVisible" serait déjà une fonction qui existe dans VB.net ?
As tu bien declaré l'api ?
Faudrait que quelqu'un qui sache faire du .net passe par la

- MadMatt -
Vb System Library
Messages postés
661
Date d'inscription
vendredi 2 décembre 2005
Statut
Membre
Dernière intervention
23 mars 2011
8
Voici, comment j'ai déclaré IsWindowVisible :

Private Declare Function IsWindowVisible Lib"user32" (ByVal hwnd As Long) As Boolean
   
Messages postés
2215
Date d'inscription
mardi 11 novembre 2003
Statut
Membre
Dernière intervention
16 juillet 2009
1
ça a l'air bon, attend quelques jours et si personne n'a répondu, poste une nouvelle question avec la capture d'écran que tu as mis plus haut, généralement tu as plus de chance d'avoir des réponses quand personne ne t'as encore répondu.

- MadMatt -
Vb System Library
Messages postés
3172
Date d'inscription
dimanche 15 février 2004
Statut
Membre
Dernière intervention
9 avril 2017
30
Et non. Ce n'est pas la bonne déclaration.
Il faut remplacer le long par un IntPtr






<System.Runtime.InteropServices.DllImport("user32")> _
Private Shared Function IsWindowVisible(ByVal hWnd As System.IntPtr) As Boolean
End Function,

----

(Coloration syntaxique automatique par Kenji)







__________
Kenji
Messages postés
661
Date d'inscription
vendredi 2 décembre 2005
Statut
Membre
Dernière intervention
23 mars 2011
8
Salut,


J'ai aussi essayé de remplacer le long par IntPtr mais ca ne fonctionne
toujours pas. Il me mets toujours là même erreur (voir ci-dessus)


Est ce que le fait de mettre Shared à la place de Declare (comme tu l'a
fait) peut éventuellement résoudre ce problème ou en revanche ca ne
changeras rien ?


Merci
Messages postés
3172
Date d'inscription
dimanche 15 février 2004
Statut
Membre
Dernière intervention
9 avril 2017
30
Non, le declare fera la même chose, c'est l'anicenne méthode de déclaration des api en dotnet.

Pour l'erreur, il faut aussi que tu remplace les long par des integer ou des IntPtr dans tes fonction et les autres déclarations d'apis.





__________
Kenji
Messages postés
661
Date d'inscription
vendredi 2 décembre 2005
Statut
Membre
Dernière intervention
23 mars 2011
8
Salut,

Je tiens à te remercier Charles Racaud en suivant ton conseil j'ai pu enfin compiler mon projet et voir ce que ca a donné. Mais j'ai un autre souci qui vient d'apparaitre, en effet, j'ai la fonction IsTask (que m'a proposé MadM@tt
qui d'ailleurs je tiens aussi à remercier) qui me permet de savoir si la fenêtre trouvée apparait dans la barre des tâches (Si c'est le cas IsTask rend True sinon False), alors j'ai testé la condition si IsTask a rendue True,
 mais là, la MsgBox n'apparait plus, je suppose que IsTask rends toujours False car dés que je supprimes la condition sur IsTask, ma MsgBox réapparait. Je mets le code pour que vous puissiez voir pourquoi ca fonctionne pas (et merci pour tout) :

Public Class Form1

    Const WM_GETTEXT As Long = &HD
    Const WM_GETTEXTLENGTH As Long = &HE
    Const GWL_HWNDPARENT As Long = -8

    Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As IntPtr, ByVal lpString As String, ByVal cch As Integer) As Integer
    Private Declare Function EnumWindows Lib "user32" (ByVal x As MyDelegateCallBack, ByVal y As Integer) As Integer
    Private Declare Auto Function SendMessageA Lib "user32" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByRef lParam As IntPtr) As IntPtr
    Public Delegate Function MyDelegateCallBack(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean
    Private Declare Auto Function SendMessageString Lib "user32" Alias "SendMessage" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wparam As Integer, ByVal lparam As System.Text.StringBuilder) As IntPtr
    Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As IntPtr) As Boolean
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As IntPtr, ByVal nIndex As Integer) As Long
    Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As IntPtr) As Long
    Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As IntPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long

    Private Function GetWindowClass(ByVal hwnd As Long) As String
        ' On prépare la chaine de caractère avec 255 espaces
        GetWindowClass = Space(255)
        ' On récuère le nom de la classe
        GetClassName(hwnd, GetWindowClass, 255)
        ' On efface les caractères vides
        GetWindowClass = Microsoft.VisualBasic.Left(GetWindowClass, InStr(GetWindowClass, vbNullChar) - 1)
    End Function

    Public Function EnumOutput(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean
        Dim texte As String
        texte = GetWindowText(hwnd)
        If IsTask(hwnd) = True Then
            MsgBox(texte)
        End If
        Return True
    End Function

    Public Function IsTask(ByVal hwnd As IntPtr) As Boolean
        IsTask = False
        'le fenêtre doit être visible
        If IsWindowVisible(hwnd) = True And (GetWindowLong(hwnd, GWL_HWNDPARENT) = 0) And Not (GetWindowTextLength(hwnd)) Then
            ' Vérifie que ce n'est pas le TaskManager
            If GetWindowClass(hwnd) <> "Progman" Then
                IsTask = True
            End If
        End If
    End Function

    Function GetWindowText(ByVal WindowHandle As IntPtr) As String
        Dim ptrRet As IntPtr
        Dim ptrLength As IntPtr

        'get length for buffer...
        ptrLength = SendMessageA(WindowHandle, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero)

        'create buffer for return value...
        Dim sb As New System.Text.StringBuilder(ptrLength.ToInt32 + 1)

        'get window text...
        ptrRet = SendMessageString(WindowHandle, WM_GETTEXT, ptrLength.ToInt32 + 1, sb)

        'get return value...
        Return sb.ToString
    End Function

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim del As MyDelegateCallBack
        del = New MyDelegateCallBack(AddressOf EnumOutput)
        EnumWindows(del, 1)
        EnumWindows(AddressOf EnumOutput, 1)
    End Sub

End Class

(Coloration syntaxique automatique par Kenji)
Messages postés
3172
Date d'inscription
dimanche 15 février 2004
Statut
Membre
Dernière intervention
9 avril 2017
30
Tes déclarations ne sont toujours pas bonnes
Tu as oublier de remplacer des long
Et fait attention, les IntPtr sont que pour les handls, les autre, c'est des int32.









Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As IntPtr, ByVal lpString As String, ByVal cch As Integer) As Integer
Private Declare Function EnumWindows Lib "user32" (ByVal x As MyDelegateCallBack, ByVal y As Integer) As Integer
Private Declare Auto Function SendMessageA Lib "user32" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByRef lParam As Integer) As Integer
Public Delegate Function MyDelegateCallBack(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean
Private Declare Auto Function SendMessageString Lib "user32" Alias "SendMessage" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wparam As Integer, ByVal lparam As System.Text.StringBuilder) As Integer
Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As IntPtr) As Boolean
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As IntPtr, ByVal nIndex As Integer) As Integer
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As IntPtr) As Integer
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As IntPtr, ByVal lpClassName As String, ByVal nMaxCount As Integer) As Integer,

----

(Coloration syntaxique automatique par Kenji)









__________
Kenji
Messages postés
661
Date d'inscription
vendredi 2 décembre 2005
Statut
Membre
Dernière intervention
23 mars 2011
8
Salut,

Merci Charles Racaud, ca fonctionne super bien. Je vais rajouter le code en entier au cas où s'il y en a pour qui cà les interresse. Mais avant, j'aurais juste une question enfin deux :

- Est ce qu'il possible de détecter si une des fenêtres listées fait partie de l'explorateur de Windows (par exemple : Poste de Travail, Mes Documents, ...) Si oui, comment on peut le faire ?

- Est-il possible de pouvoir la fermer ? Si oui, comment ?

Merci pour tout.
Messages postés
661
Date d'inscription
vendredi 2 décembre 2005
Statut
Membre
Dernière intervention
23 mars 2011
8
Voici le code :

Public Class Form1

    Const WM_GETTEXT As Long = &HD
    Const WM_GETTEXTLENGTH As Long = &HE
    Const GWL_HWNDPARENT As Long = -8

    Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As IntPtr, ByVal lpString As String, ByVal cch As Integer) As Integer
    Private Declare Function EnumWindows Lib "user32" (ByVal x As MyDelegateCallBack, ByVal y As Integer) As Integer
    Private Declare Auto Function SendMessageA Lib "user32" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByRef lParam As Integer) As Integer
    Public Delegate Function MyDelegateCallBack(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean
    Private Declare Auto Function SendMessageString Lib "user32" Alias "SendMessage" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wparam As Integer, ByVal lparam As System.Text.StringBuilder) As Integer
    Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As IntPtr) As Boolean
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As IntPtr, ByVal nIndex As Integer) As Integer
    Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As IntPtr) As Integer
    Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As IntPtr, ByVal lpClassName As String, ByVal nMaxCount As Integer) As Integer

    Private Function GetWindowClass(ByVal hwnd As Long) As String
        ' On prépare la chaine de caractère avec 255 espaces
        GetWindowClass = Space(255)
        ' On récuère le nom de la classe
        GetClassName(hwnd, GetWindowClass, 255)
        ' On efface les caractères vides
        GetWindowClass = Microsoft.VisualBasic.Left(GetWindowClass, InStr(GetWindowClass, vbNullChar) - 1)
    End Function

    Public Function EnumOutput(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean
        Dim texte As String
        texte = GetWindowText(hwnd)
        If texte <> "" And IsTask(hwnd) = True Then
            MsgBox(texte)
        End If
        Return True
    End Function

    Public Function IsTask(ByVal hwnd As IntPtr) As Boolean
        IsTask = False
        'le fenêtre doit être visible
        If IsWindowVisible(hwnd) = True And (GetWindowLong(hwnd, GWL_HWNDPARENT) = 0) And Not (GetWindowTextLength(hwnd)) Then
            ' Vérifie que ce n'est pas le TaskManager
            If GetWindowClass(hwnd) <> "Progman" Then
                IsTask = True
            End If
        End If
    End Function

    Function GetWindowText(ByVal WindowHandle As IntPtr) As String

        Dim ptrRet As IntPtr
        Dim ptrLength As IntPtr

        'get length for buffer...
        ptrLength = SendMessageA(WindowHandle, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero)

        'create buffer for return value...
        Dim sb As New System.Text.StringBuilder(ptrLength.ToInt32 + 1)

        'get window text...
        ptrRet = SendMessageString(WindowHandle, WM_GETTEXT, ptrLength.ToInt32 + 1, sb)

        'get return value...
        Return sb.ToString

    End Function

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim del As MyDelegateCallBack
        del = New MyDelegateCallBack(AddressOf EnumOutput)
        EnumWindows(del, 1)
        EnumWindows(AddressOf EnumOutput, 1)
    End Sub
End Class, ----
(Coloration syntaxique automatique par Kenji)
Messages postés
661
Date d'inscription
vendredi 2 décembre 2005
Statut
Membre
Dernière intervention
23 mars 2011
8
Super !!! Je te remercierais jamais assez

@+