Button in minimierter Anwendung klicken

  • VB.NET

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von Shinigami.

    Button in minimierter Anwendung klicken

    Hallo Leute,

    Ich habe mir bereits verschiedene Threads wie dies hier durchgelesen, jedoch habe ich immer noch ein Problem beim Ermitteln von Knöpfen.
    Ich verstehe leider nicht genau wie ich die Knöpfe ermitteln kann.
    Die Informationen vom Knopf das ich ansprechen will findet ihr im Anhang.

    Diesen Teil verstehe ich nicht:

    VB.NET-Quellcode

    1. iHwndButton = FindWindowEx ( iHwndForm, 0, "WindowsForms10.BUTTON.app.0.378734a", vbNullString)


    Dies wäre mein Code:

    VB.NET-Quellcode

    1. Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    2. Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As IntPtr, ByVal hWnd2 As IntPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As IntPtr
    3. Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    4. Private Const BM_CLICK As Integer = &HF5
    5. Private iHwndForm As IntPtr 'Fensterhanlde ermitteln
    6. Private iHwndButton As IntPtr 'Buttonhandle ermitteln
    7. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    8. 'Fenster Handle ermitteln
    9. iHwndForm = FindWindow(vbNullString, "RoboForm installieren")
    10. 'Button Handle ermitteln
    11. iHwndButton = FindWindowEx(iHwndForm, 0, "Weiter", vbNullString)
    12. 'Click auf Button in EXE senden
    13. SendMessage(iHwndButton, BM_CLICK, 0, 0) 'Button drücken
    14. If iHwndForm <> 0 Then
    15. MsgBox("Successfully obtained Window Handle")
    16. Else
    17. MsgBox("Could not obtain Window Handle")
    18. End If
    19. If iHwndButton <> 0 Then
    20. MsgBox("Successfully obtained iHwndButton Handle")
    21. Else
    22. MsgBox("Could not obtain iHwndButton Handle")
    23. End If
    24. End Sub
    Bilder
    • knopf.jpg

      44,14 kB, 333×301, 125 mal angesehen

    Shinigami schrieb:

    wie ich die Knöpfe ermitteln kann.
    Klicke auf das Suchtool-Icon und bewege dann die Maus über das Dich interessierende Fenster / Control. Lies dann die Beschreibung dazu im Spy-Fenster.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Shinigami schrieb:

    wie ich die Knöpfe ermitteln kann.
    Klicke auf das Suchtool-Icon und bewege dann die Maus über das Dich interessierende Fenster / Control. Lies dann die Beschreibung dazu im Spy-Fenster.
    Ja, dies habe ich doch gemacht und wie du in meinem Code sehen kannst steht da ja auch Weiter. Fensterbeschriftung des Knopfes ist ja Weiter

    VB.NET-Quellcode

    1. iHwndButton = FindWindowEx(iHwndForm, 0, "Weiter", vbNullString)

    Es geht dennoch nicht. Bei AutoIT hatte ich verschiedene Möglichkeiten um diese Knöpfe anzusteuern. Über den Namen kann man es hier wie es aussieht nicht ansteuern, oder ich mache etwas falsch. Geht es auch über eine Art ClassID oder so?
    OK.
    Unternimm mal einen Versuch mit EnumChildWindows().
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    OK.
    Unternimm mal einen Versuch mit EnumChildWindows().
    Tut mir leid aber ich kenne mich mit den APIs kaum aus. Ich habe mich versucht etwas schlau zu machen und auch ein wenig ausprobiert, jedoch habe ich es nicht ganz geschafft den EnumChildWindows richtig zu benutzen.
    Magst du mir zeigen wie bei dir der Code aussehen würde?

    Ich finde es schon recht umständlich in Vergleich zu AutoIT so etwas zu machen. Ich will doch lediglich paar Knöpfe im Hintergrund steuern.

    Shinigami schrieb:

    ich kenne mich mit den APIs kaum aus.
    Na aber.

    Shinigami schrieb:

    VB.NET-Quellcode

    1. Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    2. Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As IntPtr, ByVal hWnd2 As IntPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As IntPtr
    3. Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    Da Du siese Funktionen einsetzt, sollte Dir EnumChildWindows() nicht schwer fallen. Dazu findest Du auch was über die Suchfunktion. Gugst Du hier.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Nun, dies habe ich aus einem anderen Thread. Ich habe mich jedoch intensiv damit befasst jedoch gibt es irgend etwas das ich bei diese APIs nicht verstehe. Ich weiss nicht ob ich einfach nur blöd bin oder ka was... Obwohl ich in VB eigentlich nie Probleme hatte will es bei mir bezüglich diese APIs nicht klick machen.
    Meine PTBS machts mir auch gerade nicht einfach. Nun, ich danke dir für deine Hilfe. Ich werde mich wohl wieder den Basics widmen bevor ich mich wieder mit APIs beschäftigen werde.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Shinigami“ ()

    @Shinigami: Zunächst musst Du nicht den kompletten Post über Dir zitieren, das ist hier nicht gern gesehen.
    Und dann kannst Du auch im Forum und bei Frau Google mal nach EnumChildWindows() suchen, da gibt es genügend Code-Beispiele.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Wirklich? in diesen Thread hier wird erklärt wie das geht. Ich habe gerade Ausprobiert ob der FileZilla Installer erkannt wird und ja dies tut es. Sowohl minimiert als auch maximiert. Ich weiss jedoch nicht ob das Knopf drücken auch auf minimierte Fenster geht, oder ob es wie du sagst nicht geht. Dies spielt jedoch auch nicht so eine grosse Rolle. Mir würde es auch reichen wenn es auf maximierte Fenster gehen würde.

    Edit: da war ja jemand schneller :)

    Bilder habe ich hochgeladen @ Anhang.
    Mit

    VB.NET-Quellcode

    1. iHwndForm = FindWindow(vbNullString, "FileZilla Client 3.7.0.2 Setup ")
    wird das Fenster erkannt. Dies überprüfe ich mit einem

    VB.NET-Quellcode

    1. If iHwndForm <> 0 Then ...
    Mit

    VB.NET-Quellcode

    1. iHwndButton = FindWindowEx(iHwndForm, 0, "I &Agree", vbNullString)
    habe ich versucht den Knopf auszuwählen jedoch wird es nicht gefunden.

    Quellcode:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    3. Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As IntPtr, ByVal hWnd2 As IntPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As IntPtr
    4. Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    5. Private Const BM_CLICK As Integer = &HF5
    6. Private iHwndForm As IntPtr 'Fensterhanlde ermitteln
    7. Private iHwndButton As IntPtr 'Buttonhandle ermitteln
    8. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    9. 'Fenster Handle ermitteln
    10. iHwndForm = FindWindow(vbNullString, "FileZilla Client 3.7.0.2 Setup ")
    11. 'Button Handle ermitteln
    12. iHwndButton = FindWindowEx(iHwndForm, 0, "I &Agree", vbNullString)
    13. 'Click auf Button in EXE senden
    14. SendMessage(iHwndButton, BM_CLICK, 0, 0) 'Button drücken
    15. If iHwndForm <> 0 Then
    16. MsgBox("Successfully obtained Window Handle")
    17. Else
    18. MsgBox("Could not obtain Window Handle")
    19. End If
    20. If iHwndButton <> 0 Then
    21. MsgBox("Successfully obtained iHwndButton Handle")
    22. Else
    23. MsgBox("Could not obtain iHwndButton Handle")
    24. End If
    25. End Sub
    26. End Class
    Bilder
    • Programm.jpg

      76,63 kB, 513×399, 61 mal angesehen
    • Fenster.jpg

      213,09 kB, 1.124×591, 67 mal angesehen
    • knopf.jpg

      223,73 kB, 1.124×591, 53 mal angesehen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Shinigami“ ()

    Gonger96 schrieb:

    @Dodo
    Ich habs bei mir grad ausprobiert, klappt problemlos bei minimierten Anwendungen.


    Ah ja sry ich habe mich geirrt, die GUI Schläft zwar, das ist richtig, aber Events werden trotzdem noch behandelt. Ich weiß nur da sich mal Probleme mit minimierten Anwendungen hatte und zwar wenn ich ein Snapshot machen wollte, dies ist nämlich dann nicht möglich weil es kein Neuzeichnen der Anwendung gibt den man abgreifen kann.
    Hab mir jetzt mal spontan das Setup reuntergeladen und ausprobiert.

    VB.NET-Quellcode

    1. Dim hWnd As IntPtr = FindWindow(Nothing, "FileZilla Client 3.7.1 Setup ")
    2. If hWnd <> IntPtr.Zero Then
    3. Dim hBtn As IntPtr = FindWindowEx(hWnd, Nothing, "Button", "I &Agree")
    4. If hBtn <> IntPtr.Zero Then
    5. SendMessage(hBtn, &H201, IntPtr.Zero, IntPtr.Zero) ' ButtonDown
    6. SendMessage(hBtn, &H202, IntPtr.Zero, IntPtr.Zero) ' ButtonUp
    7. End If
    8. End If

    Normal wird im w/lParam noch was angegeben aber das lassen wir mal
    So ein banaler Fehler... Ich habe vbNullString eingegeben. Dabei hätte ich dann Button und I &Agree angeben müssen.

    VB.NET-Quellcode

    1. iHwndButton = FindWindowEx(iHwndForm, 0, "I &Agree", vbNullString)
    Dies war der Teil den mir gefehlt hat. Nun wollte ich noch fragen... Funktioniert bei dir dies mit dem Klicken? Sprich

    VB.NET-Quellcode

    1. SendMessage(hBtn, &H201, IntPtr.Zero, IntPtr.Zero) ' ButtonDown
    2. SendMessage(hBtn, &H202, IntPtr.Zero, IntPtr.Zero) ' ButtonUp

    Bei mir passiert da nämlich nichts.
    BN_CLICKED ist eigentlich = 0 und ist ausserdem im wParam. Zum Fenster wird dann WM_COMMAND. So geht: zuerst holhn wir uns den ID des Buttons mit seinem Handle, dann wird WM_COMMAND zum Fenster gesendet. Im wParam ist das LOWORD der ButtonID und im HIWORD das Event (hier BN_CLICKED = 0 wird also vernachlässigt) und im lParam ist das Handle des Buttons.
    Klick

    VB.NET-Quellcode

    1. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    2. Private Shared Function FindWindow( _
    3. ByVal lpClassName As String, _
    4. ByVal lpWindowName As String) As IntPtr
    5. End Function
    6. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    7. Private Shared Function FindWindowEx(ByVal parentHandle As IntPtr, _
    8. ByVal childAfter As IntPtr, _
    9. ByVal lclassName As String, _
    10. ByVal windowTitle As String) As IntPtr
    11. End Function
    12. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    13. Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
    14. End Function
    15. <DllImport("user32.dll")> _
    16. Public Shared Function GetDlgCtrlID(ByVal hwndCtl As IntPtr) As Integer
    17. End Function
    18. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    19. Dim hWnd As IntPtr = FindWindow(Nothing, "FileZilla Client 3.7.1 Setup ")
    20. If hWnd <> IntPtr.Zero Then
    21. Dim hBtn As IntPtr = FindWindowEx(hWnd, Nothing, "Button", "I &Agree")
    22. If hBtn <> IntPtr.Zero Then
    23. Dim ID As Integer = GetDlgCtrlID(hBtn)
    24. SendMessage(hWnd, &H111, New IntPtr(ID), hBtn)
    25. End If
    26. End If
    27. End Sub

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Gonger96“ ()