Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1660to1664
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Probleme mit FindwindowEx

Probleme mit FindwindowEx
30.11.2018 16:47:40
Theo
Hallo liebe Experten,
irgendwie bringt mich das automatisieren von Nicht-Office Anwendungen noch an den Rande des Wahnsinns. Ich nutze folgendes Macro um auf einem externen Fenster den "No" Knopf zu drücken:
Private Declare Function FindWindow Lib "user32.dll" _
Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32.dll" _
Alias "FindWindowExA" ( _
ByVal hWndParent As Long, _
ByVal hwndChildAfter As Long, _
ByVal lpszClass As String, _
ByVal lpszWindow As String) As Long
Sub CloseAutoLogoutMessages()
Dim hWnd As Long
Dim hbnd As Long
Dim blWindow As Boolean
blWindow = False
Do
hWnd = GetWindowHandle("SAP GUI for")
If hWnd > 0 Then
blWindow = True
BringWindowToTop (hWnd)
hbnd = FindWindowEx(hWnd, 0, "Button", "&No")
If hbnd > 0 Then
SendMessage hbnd, BM_CLICK, 0, 0
End If
End If
Loop While hWnd > 0
If blWindow Then
Application.Wait Now + TimeSerial(0, 0, 3)
End If
End Sub
Das Fensterhandle hWnd wird korrekt gefunden (deswegen habe ich Euch auch die Funktion GetWindowhandle erspart) - lediglich das FindWindowEx liefert 0 zurück. WinSpy++ liefert für den "No"-Button folgende Werte:
Userbild
Was mache ich falsch?
Vielen Dank im Voraus an dieses tolle Forum!
Theo

6
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Probleme mit FindwindowEx
30.11.2018 21:36:22
Karl-Heinz
Hallo Theo,
ich bin der Meinung, dass Du nichts falsch machst.
Aber ich erinnere mich daran, dass auch ich in früherer Zeit ebenfalls schon kurz vor dem Wahnsinn war mit dieser Funktion. (auch außerhalb von VBA)
Heute verwende ich die nur noch in bestimmten Fällen, also eher selten.
Um die/das Handle von Childwindows zu erhalten, gehe ich fast nur noch über EnumChildWindows.
Hierbei werden alle Child-Handles in ein Array geschafft und dann je nach Bedarf ausgewertet.
Das funktioniert wenigstens.
Vorerst aber auch mal der Tipp; versuch's auch mal über die ID (lt. Win-Spy ID=2):
hWndBtn = GetDlgItem(hWnd, ID)
Eigentlich für Dialogboxen vorgesehen, klappt das auch für andere Fenster, oft zumindest :-).
viele Grüße
Karl-Heinz
Anzeige
AW: Probleme mit FindwindowEx
01.12.2018 14:22:17
Theo
Hallo Karl-Heinz,
leider hat der Tipp mit der ID auch nicht geholfen :-(.
Wie machst Du das mit EnumChildWindows?
Gruß
Theo
AW: Probleme mit FindwindowEx
01.12.2018 16:16:52
Karl-Heinz
Hallo Theo,
mal ein Ansatz (direkt und ohne Array und ungetestet):
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal _
lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, _
ByVal wIndx As Long) As Long
Const GWL_ID = -12
Global bCheck As Boolean
Sub CloseAutoLogoutMessages()
Dim hWnd As Long
Dim hbnd As Long
Dim blWindow As Boolean
blWindow = False
bCheck = False
Do
hWnd = GetWindowHandle("SAP GUI for")
If hWnd > 0 Then
blWindow = True
BringWindowToTop (hWnd)
Call EnumChildWindows(hWnd, AddressOf EnumChilds, 0)
End If
If bCheck Then Exit Do
Loop While hWnd > 0
If blWindow Then
Application.Wait Now + TimeSerial(0, 0, 3)
End If
End Sub
Public Function EnumChilds(ByVal ChWnd&, ByVal lParam&) As Long
'Diese Funktion wird für jedes Child einmal direkt von Windows aufgerufen
If GetWindowLong(ChWnd, GWL_ID) = "2" Then
SendMessage ChWnd, BM_CLICK, 0, 0
End If
EnumChilds = 1
End Function
Hintergrund ist, dass nach Aufruf der Enum-Funktion für jedes Child von Windows die angegebene Callbackfunktion angesteuert wird.
Mit dem Handle kannst Du jetzt machen, was Du möchtest. In unserem Fall fische ich über GetWindowlong die ID des Childs raus und wenn sie passt, kommt der BM-Click. Fertig.
Natürlich kannst Du auch den Buttontext abfischen; ist aber ein wenig umfangreicher.
Schau mal, ob das jetzt klappt. Ich konnte es nicht testen.
VG KH
Anzeige
AW: Probleme mit FindwindowEx
01.12.2018 18:25:35
Karl-Heinz
Edit:
Public Function EnumChilds(ByVal ChWnd&, ByVal lParam&) As Long
'Diese Funktion wird für jedes Child einmal direkt von Windows aufgerufen
If GetWindowLong(ChWnd, GWL_ID) = 2 Then
SendMessage ChWnd, BM_CLICK, 0, 0
bCheck=true: EnumChilds = 0: Exit Function
End If
EnumChilds = 1
End Function
PS: ID muss natürlich eine Zahl und kein String sein, sorry.
Und müsste das nicht 'Loop While hWnd = 0' in Deiner Sub heißen. Sonst haut er doch ständig die Button-Clicks raus, oder?
VG KH
AW: Probleme mit FindwindowEx
01.12.2018 22:19:01
Theo
Hallo Karl-Heinz,
Dein PS hat mich auf die richtige Idee gebracht! Das Loop While hwnd > 0 war schon richtig, weil es mehrere SAP GUI Fenster geben kann, die alle durch den Click auf den No Button geschlossen werden. Der Fehler lag daran, dass ich das Fenster handle nicht durch exakte Übereinstimmung des Fenstertextes gesucht hatte, sondern auch einen partiellen Text erlaubt hatte. Die zu schliessenden Fenster hatten als Titel "SAP GUI for Windows 750" , offensichtlich gab es aber auch ein Fenster mit dem Titel: "SAP GUI for Windows 750 [/M/......". Das Findwindow hatte also immer nur dieses falsche Fenster gefunden, darauf keinen Button gefunden und deshalb das Fenster nicht geschlossen. Im nächsten Durchlauf wurde dann wieder das gleiche Fenster gefunden und nichts passierte. Nach der Änderung von GethandlefrompartialCaption auf die neue Funktion GetHandlefromFullCaption funkioniert mein ursprünglicher Code also einwandfrei!
Der Vollständigkeithalber hier die Funktionen die ich ursprünglich nicht mitgepostet hatte:
Public Function GetWindowHandle(WindowCaption As String) As Long
Dim lhWndP As Long
If GetHandleFromFullCaption(lhWndP, WindowCaption) = True Then
If IsWindowVisible(lhWndP) = True Then
'MsgBox "Found VISIBLE Window Handle: " & lhWndP, vbOKOnly + vbInformation
GetWindowHandle = lhWndP
Else
'MsgBox "Found INVISIBLE Window Handle: " & lhWndP, vbOKOnly + vbInformation
GetWindowHandle = lhWndP
End If
Else
'MsgBox "Window 'Window Caption' not found!", vbOKOnly + vbExclamation
End If
End Function
'hier die nue Function
Private Function GetHandleFromFullCaption(ByRef lWnd As Long, ByVal sCaption As String) As  _
Boolean
Dim lhWndP As Long
Dim sStr As String
GetHandleFromFullCaption = False
lhWndP = FindWindow(vbNullString, vbNullString)    'PARENT WINDOW
Do While lhWndP  0
sStr = String(GetWindowTextLength(lhWndP) + 1, Chr$(0))
GetWindowText lhWndP, sStr, Len(sStr)
sStr = Left$(sStr, Len(sStr) - 1)
If sStr = sCaption Then
GetHandleFromFullCaption = True
lWnd = lhWndP
Exit Do
End If
lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
Loop
End Function
'das war die alte Funktion
Private Function GetHandleFromPartialCaption(ByRef lWnd As Long, ByVal sCaption As String) As  _
Boolean
Dim lhWndP As Long
Dim sStr As String
GetHandleFromPartialCaption = False
lhWndP = FindWindow(vbNullString, vbNullString)    'PARENT WINDOW
Do While lhWndP  0
sStr = String(GetWindowTextLength(lhWndP) + 1, Chr$(0))
GetWindowText lhWndP, sStr, Len(sStr)
sStr = Left$(sStr, Len(sStr) - 1)
If InStr(1, sStr, sCaption) > 0 Then
GetHandleFromPartialCaption = True
lWnd = lhWndP
Exit Do
End If
lhWndP = GetWindow(lhWndP, GW_HWNDNEXT)
Loop
End Function
Vielen Dank für die Bemühungen - ich denke ich habe viel gelernt!
Danke
Theo
Anzeige
AW: Probleme mit FindwindowEx
01.12.2018 22:39:06
Karl-Heinz
Hallo Theo,
vielen Dank für die Rückmeldung.
Ich sehe hier im Forum, war lange nicht dabei, auch immer wieder mal was Interessantes, was meine eigene Denkweise verbessern kann.
Und mit dem SAP R3 hatte ich mich auch bis 2010 herumgeschlagen. :-)
Eine gute Nacht noch. KH

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige