C'est un ancien poste, mais un problème commun. J'ai une situation similaire où j'essaie de contrôler le comportement d'une application logicielle disponible sur le marché. Je parvins la plupart du temps en utilisant Kixstart, mais il est venu contre les limites de l'utilisation SETFOCUS et sendkeys car à certains points le logiciel impromptu affiche les fenêtres où WindowTitle est vide. J'ai donc développé un petit utilitaire qui identifie Windows visible par leur ProcessName ainsi que WindowTitle (ou son absence) et envoie un message pour fermer une fenêtre qui correspond.
La plupart des exemples que j'ai vu des fonctions de rappel EnumWindows ignorer les fenêtres qui ne sont pas visibles ou qui ont des titres vides, alors que ce code énumère toutes les fenêtres, y compris les invisibles.
Ce code est Visual Basic et utilise un fichier de configuration dans le format
PRC=process name
WIN=window title
Espérons que cela est utile à quelqu'un
Imports System
Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Text
Module Module1
Dim hShellWindow As IntPtr = GetShellWindow()
Dim dictWindows As New Dictionary(Of IntPtr, String)
Dim dictChildWindows As New Dictionary(Of IntPtr, String)
Dim currentProcessID As Integer = -1
<DllImport("USER32.DLL")>
Function GetShellWindow() As IntPtr
End Function
<DllImport("USER32.DLL")>
Function GetForegroundWindow() As IntPtr
End Function
<DllImport("USER32.DLL")>
Function GetWindowText(ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
End Function
<DllImport("USER32.DLL")>
Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer
End Function
<DllImport("user32.dll", SetLastError:=True)>
Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, <Out()> ByRef lpdwProcessId As UInt32) As UInt32
End Function
<DllImport("USER32.DLL")>
Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
End Function
Delegate Function EnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
<DllImport("USER32.DLL")>
Function EnumWindows(ByVal enumFunc As EnumWindowsProc, ByVal lParam As Integer) As Boolean
End Function
<DllImport("USER32.DLL")>
Function EnumChildWindows(ByVal hWndParent As System.IntPtr, ByVal lpEnumFunc As EnumWindowsProc, ByVal lParam As Integer) As Boolean
End Function
<DllImport("USER32.DLL")>
Function PostMessage(ByVal hwnd As Integer, ByVal message As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Boolean
End Function
<DllImport("USER32.DLL")>
Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
End Function
Function enumWindowsInternal(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
Dim a As String = ""
Dim length As Integer = GetWindowTextLength(hWnd)
If (length > 0) Then
Dim stringBuilder As New System.Text.StringBuilder(length)
GetWindowText(hWnd, stringBuilder, (length + 1))
a = stringBuilder.ToString
End If
dictWindows.Add(hWnd, a)
EnumChildWindows(hWnd, AddressOf enumChildWindowsInternal, 0)
Return True
End Function
Function enumChildWindowsInternal(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
Dim a As String = ""
Dim length As Integer = GetWindowTextLength(hWnd)
If (length > 0) Then
Dim stringBuilder As New System.Text.StringBuilder(length)
GetWindowText(hWnd, stringBuilder, (length + 1))
a = stringBuilder.ToString
End If
dictChildWindows.Add(hWnd, a)
Return True
End Function
Function cleanstring(ByVal a As String) As String
Dim c As String = ""
Dim b As String = ""
Dim i As Integer
Do While i < Len(a)
i = i + 1
c = Mid(a, i, 1)
If Asc(c) > 31 And Asc(c) < 128 Then
b = b & c
End If
Loop
cleanstring = b
End Function
Sub Main()
'
'
Dim a As String = ""
Dim b As String = ""
Dim c As String = ""
Dim d As String = ""
Dim f As String = "C:\FIS5\WK.txt"
Dim a1 As String = ""
Dim a2 As String = ""
Dim p As Process
Dim windows As IDictionary(Of IntPtr, String)
Dim kvp As KeyValuePair(Of IntPtr, String)
Dim windowPid As UInt32
Dim hWnd As IntPtr
Dim fhWnd As IntPtr
Dim WM_CLOSE As UInteger = &H12
Dim WM_SYSCOMMAND As UInteger = &H112
Dim SC_CLOSE As UInteger = &HF060
Dim x As Boolean = True
Dim y As IntPtr
Dim processes As Process() = Process.GetProcesses
Dim params As String = File.ReadAllText("C:\FIS5\WindowKiller.txt")
Dim words As String() = params.Split(vbCrLf)
Dim word As String
Dim myprocname As String = ""
Dim mywinname As String = ""
Dim i As Integer = 0
Dim v1 As Integer = 0
For Each word In words
word = Trim(cleanstring(word)).ToUpper
i = InStr(word, "=", CompareMethod.Text)
' a = a & word & " " & i.ToString & vbCrLf
If i = 4 And 4 < Len(word) Then
If Left(word, 4) = "PRC=" Then
myprocname = Mid(word, 5)
End If
If Left(word, 4) = "WIN=" Then
mywinname = Mid(word, 5)
End If
End If
Next
a = a & params & vbCrLf & "procname=" & myprocname & ", winname=" & mywinname & vbCrLf
fhWnd = GetForegroundWindow()
dictWindows.Clear()
dictChildWindows.Clear()
EnumWindows(AddressOf enumWindowsInternal, 0)
windows = dictChildWindows
For Each kvp In windows
hWnd = kvp.Key
GetWindowThreadProcessId(hWnd, windowPid)
b = ""
c = ""
For Each p In processes
If p.Id = windowPid Then
b = p.ProcessName
c = p.Id.ToString
End If
Next
d = "hidden"
If IsWindowVisible(hWnd) Then
d = "visible"
End If
If hWnd = fhWnd Then
d = d & ", foreground"
End If
a = a & "Child window=" & hWnd.ToString & ", processname=" & b & ", procid=" & c & ", windowname=" & kvp.Value & ", " & d & vbCrLf
Next
windows = dictWindows
For Each kvp In windows
v1 = 0
hWnd = kvp.Key
GetWindowThreadProcessId(hWnd, windowPid)
b = ""
c = ""
For Each p In processes
If p.Id = windowPid Then
b = p.ProcessName
c = p.Id.ToString
End If
Next
d = "hidden"
If IsWindowVisible(hWnd) Then
d = "visible"
v1 = 1
End If
If hWnd = fhWnd Then
d = d & ", foreground"
End If
word = kvp.Value
a = a & "Window=" & hWnd.ToString & ", processname=" & b & ", procid=" & c & ", windowname=" & word & ", " & d & vbCrLf
If Trim(cleanstring(b).ToUpper) = myprocname Then
a = a & "procname match" & vbCrLf
If Trim(cleanstring(word)).ToUpper = mywinname And v1 <> 0 Then
a = a & "ATTEMPTING To CLOSE: " & b & " # " & word & " # " & c & vbCrLf
' x = PostMessage(hWnd, WM_CLOSE, 0, 0)
'If x Then
'a = a & "PostMessage returned True" & vbCrLf
'Else
'a = a & "PostMessage returned False" & vbCrLf
'End If
y = SendMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0)
a = a & "SendMessage returned " & y.ToString & vbCrLf
End If
End If
Next
My.Computer.FileSystem.WriteAllText(f, a, False)
End Sub
End Module
Merci d'envoyer, de nouvelles réponses à de vieilles questions toujours aider! –