Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1444to1448
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

Fensterhandle ermitteln

Fensterhandle ermitteln
16.09.2015 16:27:06
Barbara
Hallo
zum Thema
"Alle Fensterhandle und Tasks ermitteln"
habe ich hier in einer früheren Anfrage den Hinweis auf folgende Seite bekommen:
http://www.activevb.de/tipps/vb6tipps/tipp0123.html
Nur leider kann ich damit nichts anfangen, weil es nicht funktioniert.
Hätte gerne erklärt, wie ich diesen Code nutzen kann. In den VBA-Editor einfügen und ein Sub abarbeiten geht nicht, weil da eine Menge Fehlermeldungen kommen.
Habe auch probiert, kritische Zeilen auszukommentieren, damit wenigstens die schrittweise Abfolge gestartet werden kann.
Dann kommt zB bei Me.hWnd eine Fehlermeldung. Ich glaube, da fehlt es an grundsätzlichem Wissen.
Dabei will ich doch nur an ein bestimmtes beliebiges Fenster mit Sendkeys was schicken.
Oder gibt es eine andre Lösung?
Bitte um Hilfe oder Anleitung.
LG,
Barbara

20
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Fensterhandle ermitteln
16.09.2015 16:40:29
Nepumuk
Hallo,
hier hast du fast das selbe mit Ausgabe in einer Exceltabelle:
Option Explicit

Private Declare Function EnumWindows Lib "user32.dll" ( _
    ByVal lpEnumFunc As Long, _
    ByVal lParam As Long) As Boolean
Private Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" ( _
    ByVal hwnd As Long, _
    ByVal lpString As String, _
    ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32.dll" Alias "GetWindowTextLengthA" ( _
    ByVal hwnd As Long) As Long
Private Declare Function GetClassName Lib "user32.dll" Alias "GetClassNameA" ( _
    ByVal hwnd As Long, _
    ByVal lpClassName As String, _
    ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" ( _
    ByVal hwnd As Long, _
    ByVal nIndex As Long) As Long

Private Const GWL_STYLE = (-16)
Private Const WS_VISIBLE = &H10000000
Private Const WS_BORDER = &H800000

Private llngRow As Long

Public Sub Start()
    llngRow = 1
    Columns("A:C").ClearContents
    With Range("A1:C1")
        .Value = Array("Hwnd", "Klasse", "Caption")
        .Font.Bold = True
    End With
    Call EnumWindows(AddressOf WindowCallBack, ByVal 0&)
    Columns("A:C").AutoFit
    Tabelle1.Sort.SortFields.Clear
    Tabelle1.Sort.SortFields.Add Key:=Columns(2)
    With Tabelle1.Sort
        .SetRange Columns("A:C")
        .Header = xlYes
        .MatchCase = False
        .Apply
    End With
End Sub

Private Function WindowCallBack(ByVal lngHwnd As Long, ByVal lngParam As Long) As Long
    Dim strCaption As String, strClassName As String
    Dim lngReturn As Long, lngStyle As Long
    lngStyle = GetWindowLong(lngHwnd, GWL_STYLE)
    If Cbool(lngStyle And (WS_VISIBLE Or WS_BORDER)) Then
        strClassName = Space$(256)
        lngReturn = GetClassName(lngHwnd, strClassName, 256)
        lngReturn = GetWindowTextLength(lngHwnd)
        strCaption = Space$(lngReturn)
        Call GetWindowText(lngHwnd, strCaption, lngReturn + 1)
        llngRow = llngRow + 1
        Cells(llngRow, 1).Resize(1, 3) = Array(lngHwnd, Trim$(strClassName), strCaption)
    End If
    WindowCallBack = 1
End Function

Gruß
Nepumuk

Anzeige
OT - API?
16.09.2015 16:51:18
Michael
Hallo zusammen,
ich hätte gerne gewußt, wozu bei API-Aufrufen manchmal ein Alias mit angegeben wird (eigentlich immer mit angehängtem "A"), manchmal auch nicht, und warum die jeweilige Fkt. dann aber *nie* mit dem Alias angesprochen wird?
Schöne Grüße,
Michael

AW: OT - API?
16.09.2015 17:09:21
Nepumuk
Hallo,
der Alias-Name ist der eigentliche Name der Funktion in der DLL. Die mit dem Endbuchstaben A verarbeiten Ansi-Code also die ASCII-Zeichen. Es gibt dann die selbe Funktion noch mit einem W am Ende für Wide also Unicode-Zeichen.
Auf diese Weise kannst du den Funktionen eigene Namen geben, der Bezug zur DLL erfolgt über den Alias-Namen. Ich hab z.B. die selbe Funktion mit unterschiedlichen Parameterdeklarationen im Einsatz.
Obiger Code ist schon ziemlich alt, da ich seit längerem die Aliase weg lassen und die Funktion so deklariere:
Private Declare Function GetWindowLongA Lib "user32.dll" ( _
    ByVal hwnd As Long, _
    ByVal nIndex As Long) As Long

Und nachdem ich sowieso nur noch in Windows 64Bit schreibe so:
Private Declare PtrSafe Function GetWindowLongA Lib "user32.dll" ( _
    ByVal hwnd As LongPtr, _
    ByVal nIndex As Long) As LongPtr

Gruß
Nepumuk

Anzeige
AW: OT - API? Aha...
16.09.2015 17:31:15
Michael
Hi Nepumuk,
vielen Dank für Deine Hinweise.
Ich habe zwischenzeitlich eine Runde recherchiert, wie man überhaupt an die Funktionen kommt, die irgendwelche DLLs zur Verfügung stellen. Viele schlagen nirsofts dll viewer vor, wenn man nicht ne "große" Programmiersprache einsetzen will, dort lese ich aber wiederum, daß es rund 50000 Methoden/Eigenschaften geben dürfte, wenn man sich denn alle anzeigen ließe.
Hier setzt eine gewisse Verwirrung ein: das eine sind DLLs, die man explizit als solche anspricht, das andere Objekte, die man einfach mal so benutzt, wie das Dictionary. Letzteres läßt sich ja problemlos recherchieren, aber gibt es einen allgemeinen Weg, sich Methoden/Eigenschaften eines externen Objekts anzeigen zu lassen?
Kennst Du einen "handlichen" Weg, sich in so Sachen zu vertiefen?
Gruß,
Michael

Anzeige
AW: OT - API? Aha...
16.09.2015 17:37:41
Nepumuk
Hallo,
Kennst Du einen "handlichen" Weg, sich in so Sachen zu vertiefen?
Klar, knapp 30 Jahre Erfahrung mit API.
Es gibt ein wirklich gutes Buch von Dan Applemann: Visual Basic Programmer's Guide to the Win32 API
Ist allerdings auf Englisch. Das kannst du bei AMAZON bestellen.
Gruß
Nepumuk

Achso
16.09.2015 17:49:10
Nepumuk
Hallo,
der Unterschied zwischen den DLL's wie scrrun.dll und kernell32.dll.
In der einen sind registrierte Klassen wie das Dictionary implementiert, welches du also über die Registry ansprichst. In der anderen sind Sub's und Functions implementiert welches du über die Declare-Anweisung importierst.
Gruß
Nepumuk

Anzeige
AW: Achso
16.09.2015 22:17:38
Michael
Hi Nepomuk,
jetzt bin ich beim Lesen Deiner Antworten durcheinandergekommen.
Ich sehe schon, um das wirklich zu begreifen (und nicht nur das eine oder andere Häppchen zu verwenden), muß ich etwas weiter ausholen und 30 Jahre Zeit investieren.
Aber deshalb habe ich extra die Maschine nochmal hochgefahren. Weil ich das "knapp" überlesen hatte. Mann, vor (exakt) 30 Jahren gab's grad mal DOS 2.11 (wenn überhaupt), und "grafische Betriebssystemzusätze" für 808x waren auch noch nicht in Sicht.
Im Grunde hat man aber damals schon Funktionen des jeweiligen OS (oder BIOS) benutzt - ist ja prinzipiell nix anderes als API.
Danke und tschüß,
Michael

Anzeige
... von denen ich fast alle verpennt habe,
16.09.2015 17:49:48
denen
Mann, Mann.
Ich habe, als die Zeit da war, versäumt, mich von DOS auf Win zu stürzen, derweil ich damals beruflich ganz andere Sachen um die Ohren hatte...
Excel taugt mir schon, aber heute frage ich mich wiederum, ob nicht die Zeit wäre, sich mit Schmarr-Phones und deren Programmierung auseinander zu setzen. Ach, sollen's die Jungen machen.
Herzlichen Dank für den Buchtip, die elffuffzich kann und werde ich noch investieren.
Schöne Grüße,
Michael

AW: Fensterhandle ermitteln
16.09.2015 19:18:16
Barbara
Hallo Nepomuk,
danke für Deine Antwort. Habe Deinen Code eingefügt und wollte Public Sub Start() starten.
Ergebnis: Fehlermeldung:
"Fehler beim kompilieren
Unzulässige Verwendung des AdressOf-Operators"
Mach ich da was falsch?
LG,
Barbara

Anzeige
AW: Fensterhandle ermitteln
16.09.2015 19:29:57
Nepumuk
Hallo,
hast du noch Excel97? Da war dieser Operator noch nicht implementiert.
Gruß
Nepumuk

AW: Fensterhandle ermitteln
16.09.2015 19:48:53
Nepumuk
Hallo,
oder hast du Office2010 in der 64Bit-Version? Wenn ja, dann benutze folgenden Code:
Option Explicit

Private Declare PtrSafe Function EnumWindows Lib "user32.dll" ( _
    ByVal lpEnumFunc As LongPtr, _
    ByVal lParam As LongPtr) As Long
Private Declare PtrSafe Function GetWindowTextA Lib "user32.dll" ( _
    ByVal hwnd As LongPtr, _
    ByVal lpString As String, _
    ByVal cch As Long) As Long
Private Declare PtrSafe Function GetWindowTextLengthA Lib "user32.dll" ( _
    ByVal hwnd As LongPtr) As Long
Private Declare PtrSafe Function GetClassNameA Lib "user32.dll" ( _
    ByVal hwnd As LongPtr, _
    ByVal lpClassName As String, _
    ByVal nMaxCount As Long) As Long
#If Win64 Then
Private Declare PtrSafe Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongPtrA" ( _
    ByVal hwnd As LongPtr, _
    ByVal nIndex As Long) As LongPtr
#Else
Private Declare PtrSafe Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" ( _
    ByVal hwnd As LongPtr, _
    ByVal nIndex As Long) As LongPtr
#End If

Private Const GWL_STYLE = (-16)
Private Const WS_VISIBLE = &H10000000
Private Const WS_BORDER = &H800000

Private llngRow As Long

Public Sub Start()
    llngRow = 1
    Columns("A:C").ClearContents
    With Range("A1:C1")
        .Value = Array("Hwnd", "Klasse", "Caption")
        .Font.Bold = True
    End With
    Call EnumWindows(AddressOf WindowCallBack, ByVal 0&)
    Columns("A:C").AutoFit
    Tabelle1.Sort.SortFields.Clear
    Tabelle1.Sort.SortFields.Add Key:=Columns(2)
    With Tabelle1.Sort
        .SetRange Columns("A:C")
        .Header = xlYes
        .MatchCase = False
        .Apply
    End With
End Sub

Private Function WindowCallBack(ByVal pvlngptrHwnd As LongPtr, ByVal lngptrParam As LongPtr) As Long
    Dim strCaption As String, strClassName As String
    Dim lngReturn As Long
    Dim lngptrStyle As LongPtr
    lngptrStyle = GetWindowLong(pvlngptrHwnd, GWL_STYLE)
    If Cbool(lngptrStyle And (WS_VISIBLE Or WS_BORDER)) Then
        strClassName = Space$(256)
        lngReturn = GetClassNameA(pvlngptrHwnd, strClassName, 256)
        strClassName = Left$(strClassName, lngReturn)
        lngReturn = GetWindowTextLengthA(pvlngptrHwnd)
        strCaption = Space$(lngReturn)
        Call GetWindowTextA(pvlngptrHwnd, strCaption, lngReturn + 1)
        llngRow = llngRow + 1
        Cells(llngRow, 1).Resize(1, 3) = Array(pvlngptrHwnd, strClassName, strCaption)
    End If
    WindowCallBack = 1
End Function

Gruß
Nepumuk

Anzeige
AW: Fensterhandle ermitteln
16.09.2015 20:00:01
Barbara
Auch hier, selbe Fehlermeldung. Und dann ist
"AddressOf WindowCallBack" markiert.
Meine Version: Microsoft Excel 2010(14.0) SP2 MSO (32-bit)
Muss ich vielleicht was dazu laden?

Tester gesucht
16.09.2015 20:14:40
Nepumuk
Hallo,
jetzt bin ich echt überfragt. Beide Codes laufen bei mir unter Excel 2013 32 Bit.
Kann das mal jemand anders mit Excel 2010 testen
Gruß
Nepumuk

Klappt 1A!
16.09.2015 20:29:50
Sepp
Hallo Max,
der Code läuft wie erwartet.
Office Professional Plus 2010, Win 7 32 Bit
Gruß Sepp

Anzeige
AW: Tester gesucht
16.09.2015 20:31:45
Mullit
Hallo Nepumuk,
ich vermute den Klassiker, sie hat den Code nicht in ein Standardmodul, sondern in ein Tabellenblattmodul oder Arbeitsmappenmodul gepackt, läuft sonst wie geschnitten Brot...
Gruß, Mullit

Danke an die Tester !!!
16.09.2015 20:36:00
Nepumuk
Hallo Mullit,
Ohhhhhhhhhhhhh Mann !!!! Daran hab ich gar nicht gedacht. Vielen Dank !!!!!!!!!!
Also Barbara, der Code muss in ein Standardmodul. Menüleiste - Einfügen - Modul.
Gruß
Nepumuk

AW: Danke an die Tester !!!
16.09.2015 21:19:19
Mullit
Hallo Nepumuk,
null Problemo, in den Fehler bin ich wohl schon zu oft reingekachelt....
Gruß, Mullit

AW: Danke an die Tester !!!
16.09.2015 22:48:47
Barbara
Danke, jetzt geht's.
Mit meinem bescheidenen Horizont wäre ich nicht drauf gekommen.
Dennoch trete ich weiter auf der Stelle mit meine eigentlichen Problemchen:
Siehe auch angehängte Beispieldatei.
https://www.herber.de/bbs/user/100236.xlsm
Da ist in Modul1 ein Makro, das Folgendes macht:
Der Werte der Zellen A1 bis A5 werden im Sekundentakt in die Zwischenablage kopiert.
Diese muss ich genauso im Sekundentakt woanders so abladen (dzt. händisch):
Nachdem ich dieses Makro gestartet habe, gehe ich innerhalb einer Sekunde mit einem Mausklick in ein bereits offenes anderes Programm und mache Folgendes fünf Mal im Sekundentakt:
STRG+V (um den Inhalt dort einzufügen)
und dann drücke ich ohne eine andere Taste nur die rechte (!) STRG-Taste der Tastatur oder die Enter-Taste vom Num-Block. (Ob das mit Sendkeys geht?)
Das ist eine Eigenheit dieses anderen 20 Jahre alten Programms, um dort die Eingabe zu verarbeiten.
Diese händische Prozedur sollte ins bestehende Makro eingebaut werden, denn in Wirklichkeit sind es 50 solche Zyklen, die ich jetzt händisch abarbeite. Und dabei jedes Mal die Existenz dieses Zielfensters geprüft werden, damit nichts ins Leere geht.
Vielen Dank für Eure Bemühungen.
LG,
Barbara

Anzeige
Danke für Eure Hilfe.
16.09.2015 23:49:28
Barbara
Jetzt geht alles Durcheinander.
BITTE MEINEN LETZTEN BEITRAG IGNORIEREN.
ICH MACHE DAZU EIN NEUES THEMA AUF.
Danke für Eure Hilfe.

x2000/Vista auch ok - bis auf Sortieren owT
16.09.2015 22:43:10
Michael

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige