Live-Forum - Die aktuellen Beiträge
Datum
Titel
29.03.2024 13:14:12
28.03.2024 21:12:36
28.03.2024 18:31:49
Anzeige
Archiv - Navigation
1032to1036
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

VBA: 'fremde' Fensterhandles finden ?

VBA: 'fremde' Fensterhandles finden ?
20.12.2008 10:31:00
Melanie
Hallo allerseits,
ich moechte aus Excel heraus mit VBA code automatisch spezielle Child-Handles eines 'fremden' WindowsapplicationFensters finden (keine Officeanwendung).
Bisher mache ich das immer von Hand: mit dem Autoit windows info tool gibt es folgende Angaben ueber das 'fremde' Fenster :
>>>> Window Title: XXXX
Class: TFrmYYYY
Position: 486, 8
Size: 649, 538
Style: 0x16CF0000
ExStyle: 0x00010100
Handle: 0x0001061A
Diesen Handle finde ich schon mit 'findwindows' (uber den Titel) automatisch. Schon mal gut, aber nun moechte ich folgenden speziellen TextInput Handle (child von dem Window siehe oben) per script finden
(wieder aus dem Autoit window tool):
>>>> Control Class: TValidatorEdit
Instance: 7
ClassnameNN: TValidatorEdit7
Advanced (Class): [CLASS:TValidatorEdit; INSTANCE:7]
ID: 67186
Text:
Position: 51, 4
Size: 95, 22
ControlClick Coords: 57, 8
Style: 0x540100C8
ExStyle: 0x00000200
Handle: 0x00010672
Dieser Handle ist also gesucht, ich weiss nur leider nicht, wie ich diesen mit dem Classname, Instance usw automatisch 'addressiere' únd speichern kann ?
Kann mir jemand 'nen Tipp geben ?
Gruss
Melanie

7
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: VBA: 'fremde' Fensterhandles finden ?
20.12.2008 15:26:27
Tino
Hallo,
die Prozedur listet dir alle Sichtbaren hwnd’s, Titel und Prozess ID’s auf.
Kann umgestellt werden, dass auch nicht Sichtbare Prozesse aufgelistet werden.
Vielleicht kannst Du damit etwas anfangen.
Option Explicit
Private Declare Function GetDesktopWindow Lib "user32" () _
                As Long
Private Declare Function GetWindow Lib "user32" _
       (ByVal hWnd As Long, ByVal wCmd As Long) As Long

Private Declare Function GetWindowText Lib "user32" _
        Alias "GetWindowTextA" _
        (ByVal hWnd As Long, ByVal lpString As String, _
        ByVal cch As Long) As Long

Private Declare Function GetClassName Lib "user32" _
        Alias "GetClassNameA" _
        (ByVal hWnd As Long, ByVal lpClassName As String, _
        ByVal nMaxCount As Long) As Long
        
Private Declare Function GetWindowTextLength Lib "user32" _
        Alias "GetWindowTextLengthA" (ByVal hWnd As Long) _
        As Long

Private Declare Function GetWindowThreadProcessId Lib "user32" _
        (ByVal hWnd As Long, lpdwProcessId As Long) As Long

         
Private Declare Function GetWindowLong Lib "user32" Alias _
        "GetWindowLongA" (ByVal hWnd As Long, ByVal wIndx As _
        Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hWnd _
        As Long) As Long
        
        
Const GW_HWNDFIRST = 0
Const GW_HWNDLAST = 1
Const GW_HWNDNEXT = 2
Const GW_HWNDPREV = 3
Const GW_OWNER = 4
Const GW_CHILD = 5
Const GW_MAX = 5

Const GWL_STYLE = (-16)

Const WS_VISIBLE = &H10000000
Const WS_BORDER = &H800000
Private Sub GetWindowInfo(ByVal hWnd&)
  Dim Parent&, Task&, Result&, X&, Style&, Title$
  
    'Darstellung des Fensters 
    Style = GetWindowLong(hWnd, GWL_STYLE)
    Style = Style And (WS_VISIBLE Or WS_BORDER)

    Result = GetWindowTextLength(hWnd) + 1
    Title = Space$(Result)
    Result = GetWindowText(hWnd, Title, Result)
    Title = Left$(Title, Len(Title) - 1)
    
   If Style = (WS_VISIBLE Or WS_BORDER) Then
     If Title <> "" Then
      
      Cells(Rows.Count, 1).End(xlUp).Offset(1, 0) = CStr(hWnd)
      Cells(Rows.Count, 2).End(xlUp).Offset(1, 0) = Title
      
      'Elternfenster ermitteln 
      Parent = hWnd
      Do
        Parent = GetParent(Parent)
      Loop Until Parent = 0
      
      'Task Id ermitteln 
      Result = GetWindowThreadProcessId(hWnd, Task)
      Cells(Rows.Count, 3).End(xlUp).Offset(1, 0) = Task
     
     End If
  End If
End Sub
Sub vList_Prozesse()
Dim hWnd As Long, tbuf As String, RetVal As Long

'Zellen leeren und Überschrift 
Cells.Clear
Range("A1") = "hwnd"
Range("B1") = "Titel"
Range("C1") = "Prozess ID"
Range("A1:C1").Font.Bold = True
  
  hWnd = GetDesktopWindow()
  hWnd = GetWindow(hWnd, GW_CHILD)
  GetWindowInfo hWnd

Do While hWnd <> 0
    tbuf = String(255, 0)
    RetVal = GetWindowText(hWnd, tbuf, Len(tbuf))
    hWnd = GetWindow(hWnd, GW_HWNDNEXT)
    GetWindowInfo hWnd
Loop
Columns("A:C").EntireColumn.AutoFit
End Sub


Gruß Tino

Anzeige
AW: VBA: 'fremde' Fensterhandles finden ?
20.12.2008 17:20:46
Melanie
Hallo Tino,
das Auflisten der handles der sichtbaren Hauptfenster funktioniert.
Aber leider weiss ich noch nicht, wie ich jetzt bei einem dieser Hauptfenster alle TextField handles (die controls haben keinen 'Titel') aufliste, damit ich den gewuenschten mit speziellem Classname / Instance finden kann.
Class: TValidatorEdit
Instance: 7
ClassnameNN: TValidatorEdit7
Advanced (Class): [CLASS:TValidatorEdit; INSTANCE:7]
Irgendeine Idee ?
Gruss
Melanie
AW: VBA: 'fremde' Fensterhandles finden ?
20.12.2008 19:33:07
Tino
Hallo,
habe noch etwas hinzugefügt, schau mal ob jetzt die nötige Info dabei ist.
Sonst Google mal nach winmgmts: und Win32_Process
Option Explicit
Private Declare Function GetDesktopWindow Lib "user32" () _
                As Long
Private Declare Function GetWindow Lib "user32" _
       (ByVal hwnd As Long, ByVal wCmd As Long) As Long

Private Declare Function GetClassName Lib "user32" _
        Alias "GetClassNameA" _
        (ByVal hwnd As Long, ByVal lpClassName As String, _
        ByVal nMaxCount As Long) As Long
        
Private Declare Function GetWindowTextLength Lib "user32" _
        Alias "GetWindowTextLengthA" (ByVal hwnd As Long) _
        As Long

Private Declare Function GetWindowThreadProcessId Lib "user32" _
        (ByVal hwnd As Long, lpdwProcessId As Long) As Long

         
Private Declare Function GetWindowLong Lib "user32" Alias _
        "GetWindowLongA" (ByVal hwnd As Long, ByVal wIndx As _
        Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd _
        As Long) As Long
        
Private Declare Function GetWindowText Lib "user32" Alias _
      "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString _
      As String, ByVal cch As Long) As Long
        
Const GW_HWNDFIRST = 0
Const GW_HWNDLAST = 1
Const GW_HWNDNEXT = 2
Const GW_HWNDPREV = 3
Const GW_OWNER = 4
Const GW_CHILD = 5
Const GW_MAX = 5

Const GWL_STYLE = (-16)

Const WS_VISIBLE = &H10000000
Const WS_BORDER = &H800000
Private Sub GetWindowInfo(ByVal hwnd&, bVisible As Boolean, booMit_Titel As Boolean)
  Dim Parent&, Task&, Result&, X&, Style&, Title$
  Dim nRetVal&, strClassName$

    'Darstellung des Fensters 
    Style = GetWindowLong(hwnd, GWL_STYLE)
    Style = Style And (WS_VISIBLE Or WS_BORDER)

    Result = GetWindowTextLength(hwnd) + 1
    Title = Space$(Result)
    Result = GetWindowText(hwnd, Title, Result)
    Title = Left$(Title, Len(Title) - 1)
    
   If (Style = (WS_VISIBLE Or WS_BORDER)) Or bVisible = False Then
     
     If Title <> "" Or booMit_Titel = False Then
      
      Cells(Rows.Count, 1).End(xlUp).Offset(1, 0) = CStr(hwnd)
      Cells(Rows.Count, 2).End(xlUp).Offset(1, 0) = Title
      
      'Elternfenster ermitteln 
      Parent = hwnd
      Do
        Parent = GetParent(Parent)
      Loop Until Parent = 0
      
      'Task Id ermitteln 
      Result = GetWindowThreadProcessId(hwnd, Task)
      Cells(Rows.Count, 3).End(xlUp).Offset(1, 0) = Task
     
        strClassName = Space$(64)
        nRetVal = GetClassName(hwnd, strClassName, Len(strClassName))
        strClassName = Left$(strClassName, nRetVal)
        Cells(Rows.Count, 4).End(xlUp).Offset(1, 0) = strClassName
        
     
     End If
  End If
End Sub


Sub vList_Prozesse()
Dim hwnd As Long, tbuf As String, RetVal As Long

'Einstellung nur Sichtbare und mit Fenstertitel 
Const Nur_Sichtbare As Boolean = False
Const Nur_mit_Fenstertitel As Boolean = False

'Zellen leeren und Überschrift 
Cells.Clear
Range("A1") = "hwnd"
Range("B1") = "Titel"
Range("C1") = "Prozess ID"
Range("D1") = "Class Name"
Range("A1:D1").Font.Bold = True
'______________________________
 
'hwnd Deskdopt 
  hwnd = GetDesktopWindow()
  hwnd = GetWindow(hwnd, GW_CHILD)
'hwnd, nur Sichtbar, nur Mit Fenstertitel 
  GetWindowInfo hwnd, Nur_Sichtbare, Nur_mit_Fenstertitel

Do While hwnd <> 0
    tbuf = String(255, 0)
    RetVal = GetWindowText(hwnd, tbuf, Len(tbuf))
    hwnd = GetWindow(hwnd, GW_HWNDNEXT)
    'hwnd, nur Sichtbar, nur mit Fenstertitel 
    GetWindowInfo hwnd, Nur_Sichtbare, Nur_mit_Fenstertitel
Loop

Columns("A:D").EntireColumn.AutoFit
End Sub


Gruß Tino

Anzeige
AW: VBA: 'fremde' Fensterhandles finden ?
20.12.2008 23:00:15
Tino
Hallo,
so jetzt müssten die nötigen Infos dabei sein.
Modul Modul1
Option Explicit 
Private Declare Function GetDesktopWindow Lib "user32" () _
                As Long 
Private Declare Function GetWindow Lib "user32" _
       (ByVal hwnd As Long, ByVal wCmd As Long) As Long 
 
Private Declare Function GetClassName Lib "user32" _
        Alias "GetClassNameA" _
        (ByVal hwnd As Long, ByVal lpClassName As String, _
        ByVal nMaxCount As Long) As Long 
         
Private Declare Function GetWindowTextLength Lib "user32" _
        Alias "GetWindowTextLengthA" (ByVal hwnd As Long) _
        As Long 
 
Private Declare Function GetWindowThreadProcessId Lib "user32" _
        (ByVal hwnd As Long, lpdwProcessId As Long) As Long 
 
          
Private Declare Function GetWindowLong Lib "user32" Alias _
        "GetWindowLongA" (ByVal hwnd As Long, ByVal wIndx As _
        Long) As Long 
Private Declare Function GetParent Lib "user32" (ByVal hwnd _
        As Long) As Long 
         
Private Declare Function GetWindowText Lib "user32" Alias _
      "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString _
      As String, ByVal cch As Long) As Long 
         
Const GW_HWNDFIRST = 0 
Const GW_HWNDLAST = 1 
Const GW_HWNDNEXT = 2 
Const GW_HWNDPREV = 3 
Const GW_OWNER = 4 
Const GW_CHILD = 5 
Const GW_MAX = 5 
 
Const GWL_STYLE = (-16) 
 
Const WS_VISIBLE = &H10000000 
Const WS_BORDER = &H800000 
Private Sub GetWindowInfo(ByVal hwnd&, bVisible As Boolean, booMit_Titel As Boolean) 
  Dim Parent&, Task&, Result&, X&, Style&, Title$ 
  Dim nRetVal&, strClassName$ 
  Dim mCaption 
  Dim A As Long 
    'Darstellung des Fensters 
    Style = GetWindowLong(hwnd, GWL_STYLE) 
    Style = Style And (WS_VISIBLE Or WS_BORDER) 
 
    Result = GetWindowTextLength(hwnd) + 1 
    Title = Space$(Result) 
    Result = GetWindowText(hwnd, Title, Result) 
    Title = Left$(Title, Len(Title) - 1) 
     
   If (Style = (WS_VISIBLE Or WS_BORDER)) Or bVisible = False Then 
      
     If Title <> "" Or booMit_Titel = False Then 
       
      Cells(Rows.Count, 1).End(xlUp).Offset(1, 0) = CStr(hwnd) 
      Cells(Rows.Count, 2).End(xlUp).Offset(1, 0) = Title 
       
      'Elternfenster ermitteln 
      Parent = hwnd 
      Do 
        Parent = GetParent(Parent) 
      Loop Until Parent = 0 
       
      'Task Id ermitteln 
      Result = GetWindowThreadProcessId(hwnd, Task) 
      Cells(Rows.Count, 3).End(xlUp).Offset(1, 0) = Task 
      
        strClassName = Space$(64) 
        nRetVal = GetClassName(hwnd, strClassName, Len(strClassName)) 
        strClassName = Left$(strClassName, nRetVal) 
        Cells(Rows.Count, 4).End(xlUp).Offset(1, 0) = strClassName 
      
     End If 
  End If 
End Sub 
 
Private Sub Read_App() 
    Dim objWMIService As Object, cProcesses As Object, fProcess As Object 
    Dim Bereich As Range, A As Long 
    Dim myArea, myArea2() 
    Set Bereich = Range("C2", Cells(Rows.Count, 3).End(xlUp)) 
    myArea = Bereich 
    Set Bereich = Bereich.Offset(0, 2) 
    myArea2 = Bereich 
     
    Set objWMIService = GetObject("winmgmts:") 
    Set cProcesses = objWMIService.ExecQuery("Select * from Win32_Process") 
     
        For Each fProcess In cProcesses 
            With fProcess 
             For A = 1 To Ubound(myArea) 
              If myArea(A, 1) = .ProcessId Then 
               myArea2(A, 1) = .Name 
              End If 
             Next A 
            End With 
        Next 
    Bereich = myArea2 
End Sub 
 
Sub vList_Prozesse() 
Dim hwnd As Long, tbuf As String, RetVal As Long 
 
'Einstellung nur Sichtbare und mit Fenstertitel 
'True ist ja, False nein 
Const Nur_Sichtbare As Boolean = False 
Const Nur_mit_Fenstertitel As Boolean = False 
 
'Zellen leeren und Überschrift 
Cells.Clear 
Range("A1") = "hwnd" 
Range("B1") = "Titel" 
Range("C1") = "Prozess ID" 
Range("D1") = "Class Name" 
Range("E1") = "Applikation" 
Range("A1:E1").Font.Bold = True 
'______________________________
  
'hwnd Deskdopt 
  hwnd = GetDesktopWindow() 
  hwnd = GetWindow(hwnd, GW_CHILD) 
'hwnd, nur Sichtbar, nur Mit Fenstertitel 
  GetWindowInfo hwnd, Nur_Sichtbare, Nur_mit_Fenstertitel 
 
Do While hwnd <> 0 
    tbuf = String(255, 0) 
    RetVal = GetWindowText(hwnd, tbuf, Len(tbuf)) 
    hwnd = GetWindow(hwnd, GW_HWNDNEXT) 
    'hwnd, nur Sichtbar, nur mit Fenstertitel 
    GetWindowInfo hwnd, Nur_Sichtbare, Nur_mit_Fenstertitel 
Loop 
Call Read_App 
Columns("A:E").EntireColumn.AutoFit 
Columns("B:B").ColumnWidth = 35 
End Sub 
 


Gruß Tino

Anzeige
Korrektur
21.12.2008 09:52:00
Tino
Hallo,
es war noch ein Fehler in der Zuordnung, habe Ihn jetzt erst bemerkt.
Option Explicit
Private Declare Function GetDesktopWindow Lib "user32" () _
                As Long
Private Declare Function GetWindow Lib "user32" _
       (ByVal hwnd As Long, ByVal wCmd As Long) As Long

Private Declare Function GetClassName Lib "user32" _
        Alias "GetClassNameA" _
        (ByVal hwnd As Long, ByVal lpClassName As String, _
        ByVal nMaxCount As Long) As Long
        
Private Declare Function GetWindowTextLength Lib "user32" _
        Alias "GetWindowTextLengthA" (ByVal hwnd As Long) _
        As Long

Private Declare Function GetWindowThreadProcessId Lib "user32" _
        (ByVal hwnd As Long, lpdwProcessId As Long) As Long

         
Private Declare Function GetWindowLong Lib "user32" Alias _
        "GetWindowLongA" (ByVal hwnd As Long, ByVal wIndx As _
        Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd _
        As Long) As Long
        
Private Declare Function GetWindowText Lib "user32" Alias _
      "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString _
      As String, ByVal cch As Long) As Long
        
Const GW_HWNDFIRST = 0
Const GW_HWNDLAST = 1
Const GW_HWNDNEXT = 2
Const GW_HWNDPREV = 3
Const GW_OWNER = 4
Const GW_CHILD = 5
Const GW_MAX = 5

Const GWL_STYLE = (-16)

Const WS_VISIBLE = &H10000000
Const WS_BORDER = &H800000
Dim lRow As Long

Private Sub Read_App() 'Application Name 
    Dim objWMIService As Object, cProcesses As Object, fProcess As Object
    Dim Bereich As Range, A As Long
    Dim myArea, myArea2()
    Set Bereich = Range("C2", Cells(Rows.Count, 3).End(xlUp))
    myArea = Bereich
    Set Bereich = Range(Bereich.Offset(0, 2), Bereich.Offset(0, 3))
    myArea2 = Bereich
     
    Set objWMIService = GetObject("winmgmts:")
    Set cProcesses = objWMIService.ExecQuery("Select * from Win32_Process")
     
        For Each fProcess In cProcesses
            With fProcess
             For A = 1 To Ubound(myArea)
              If myArea(A, 1) = .ProcessId Then
               myArea2(A, 1) = .Caption
               myArea2(A, 2) = .ExecutablePath
              End If
             Next A
            End With
        Next
    Bereich = myArea2
End Sub


Private Sub GetWindowInfo(ByVal hwnd&, bVisible As Boolean, booMit_Titel As Boolean)
  Dim Parent&, Task&, Result&, X&, Style&, Title$
  Dim nRetVal&, strClassName$
  
    'Darstellung des Fensters 
    Style = GetWindowLong(hwnd, GWL_STYLE)
    Style = Style And (WS_VISIBLE Or WS_BORDER)

    Result = GetWindowTextLength(hwnd) + 1
    Title = Space$(Result)
    Result = GetWindowText(hwnd, Title, Result)
    Title = Left$(Title, Len(Title) - 1)
    
    
     If (Title <> "" Or booMit_Titel = False) Or (Style = (WS_VISIBLE Or WS_BORDER)) Or bVisible = False Then
      
      Cells(lRow, 1) = CStr(hwnd)
      Cells(lRow, 2) = Title
      
      'Elternfenster ermitteln 
        Parent = hwnd
        Do
          Parent = GetParent(Parent)
        Loop Until Parent = 0
      
      'Task Id ermitteln 
        Result = GetWindowThreadProcessId(hwnd, Task)
        Cells(lRow, 3) = Task
      
      'Class Name 
        strClassName = Space$(64)
        nRetVal = GetClassName(hwnd, strClassName, Len(strClassName))
        strClassName = Left$(strClassName, nRetVal)
        Cells(lRow, 4) = strClassName
        
        lRow = lRow + 1
     End If

End Sub


Sub vList_Prozesse()
Dim hwnd As Long, tbuf As String, RetVal As Long

'Einstellung nur Sichtbare und mit Fenstertitel 
Const Nur_Sichtbare As Boolean = False
Const Nur_mit_Fenstertitel As Boolean = False

'Zellen leeren und Überschrift 
Cells.Clear
Range("A1") = "hwnd"
Range("B1") = "Titel"
Range("C1") = "Prozess ID"
Range("D1") = "Class Name"
Range("E1") = "App. Name"
Range("A1:E1").Font.Bold = True
lRow = 2 'Liste ab Zeile anfangen 
'______________________________
 
'hwnd Deskdopt 
  hwnd = GetDesktopWindow()
  hwnd = GetWindow(hwnd, GW_CHILD)
'hwnd, nur Sichtbar, nur Mit Fenstertitel 
  GetWindowInfo hwnd, Nur_Sichtbare, Nur_mit_Fenstertitel

Do While hwnd <> 0
    tbuf = String(255, 0)
    RetVal = GetWindowText(hwnd, tbuf, Len(tbuf))
    hwnd = GetWindow(hwnd, GW_HWNDNEXT)
    'hwnd, nur Sichtbar, nur mit Fenstertitel 
    GetWindowInfo hwnd, Nur_Sichtbare, Nur_mit_Fenstertitel
Loop
Call Read_App 'Application Name 
Columns("A:E").EntireColumn.AutoFit
End Sub


Gruß Tino

Anzeige
AW: Korrektur
21.12.2008 10:11:55
Melanie
Hallo Tino,
die Classnames und die Zuordnung sind jetzt zwar richtig. Danke fuer den unermuedlichen Support !
Komischerweise erscheinen aber die gesuchten TextField Handles mit speziellem Classname nicht in der Auflistung. Kann es sein, dass die gar keine Childs der Hauptfenster sind ?!!? (wer-weiss-wie die fremde Applikation geschrieben ist) ... muss man eventuell irgendwie ALLE vergebenen handles durchsuchen und dann nach dem speziellen classname filtern ?
Gruss
Melanie
bin mit meinem Latein am ende oT.
21.12.2008 10:24:51
Tino

300 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige