Kann man bestimmte Fenster durch bestimmte Funktionen ansteuern?

  • Allgemein

Es gibt 40 Antworten in diesem Thema. Der letzte Beitrag () ist von Gonger96.

    Kann man bestimmte Fenster durch bestimmte Funktionen ansteuern?

    Hi Leute,

    eine kleine und vielleicht schnell zu beantwortende Frage:

    Kann ich bestimmte Fenster, die erscheinen, mit bestimmten Befehlen ansteuern?
    Zum Beispiel öffnet sich ja bei Word, sofern sich mein Text verändert hat, und ich diesen Prozess beenden möchte das Frage-Fenster "Möchten Sie dieses Dokument speichern? JA|NEIN|ABBRECHEN"

    ..Ich dachte ich könnte diese Fenster über vbYes,vbNo,vbCancel ansteuern, da ich in diesem Moment aktiv in diesem Prozess bin.
    Habe aber leider gaaaaar keine Ahnung ob dies funktionieren sollte.
    Habe es mal mit Sendkeys versucht, aber irgendwie.. Will es nicht. ;)


    Kann ich mir etwas basteln das den Titel des Fensters aufsucht und dem entsprechend "Nein" anwählt?

    Ideen?


    Grüße!
    @Confuzi Us: Such mal im Forum Programm fernsteuern, da findest Du genug.
    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!
    Na ja,...
    Im endeffekt mache ich zur Zeit händig "Nach-Rechts" und "Enter"-
    wenn ich das meinem Programm sagen möchte passiert gar nix..

    Bin auf der aktiven Form aber irgendwie komm ich da in eine endlos-schleife.

    Erst durch das aufrufen des Task-Managers via strg+alt+entf kann ich wieder meine Windows-Oberfläche ansteuern.

    Gibt aber auch keine Methode das ich genau dieses Fenster absuche, sprich Titel abfragen und los geht's?

    Confuzi Us schrieb:

    Gibt aber auch keine Methode das ich genau dieses Fenster absuche
    API.FindWindow(), API.EnumerateWindows().
    Wenn Du das "Fremdprogramm" per Process startest, hatt Du das Handle des Hauptensters ja bereits als Member in einer Process-instanz.
    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!
    Würde auf mittels FindWindow API erstmal die MessageBox ausfindig machen und dann den Button Handle und ein Klick ausführen.

    Ich habe sowas schonmal gemacht, wo auf eine DialogBox gewartet wird und dann "Nein" geklickt wird. NAtürlich kannst du mein Codebeispiel nicht 1:1 übernehmen, aber es soll dir verdeutlichen wie es realisieren kannst.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Function getClassName(ByVal handle As IntPtr) As String
    2. Dim sb As New StringBuilder("", 256)
    3. WinAPI.GetClassName(handle, sb, sb.Capacity)
    4. Return sb.ToString()
    5. End Function
    6. Private Function getText(ByVal Handle As IntPtr) As String
    7. Dim iLength As Integer = WinAPI.GetWindowTextLength(handle)
    8. If iLength <= 0 Then Return String.Empty
    9. Dim sb As New StringBuilder("", iLength + 1)
    10. WinAPI.GetWindowText(handle, sb, sb.Capacity)
    11. Return sb.ToString()
    12. End Function
    13. Private Sub setText(ByVal handle As IntPtr, ByVal Text As String)
    14. WinAPI.SendMessage(handle, &HC, IntPtr.Zero, Text)
    15. End Sub
    16. Private Sub pressButton(ByVal handle As IntPtr)
    17. WinAPI.SendMessage(handle, &HF5, IntPtr.Zero, "")
    18. End Sub
    19. 'background worker
    20. dialogHandle = IntPtr.Zero
    21. iTimeout = 0
    22. ' search result dialog handle
    23. While dialogHandle.Equals(IntPtr.Zero)
    24. If bg.CancellationPending Then Exit Sub
    25. dialogHandle = WinAPI.FindWindow("#32770", "Titel der Messagebox")
    26. Threading.Thread.Sleep(100)
    27. iTimeout += 1
    28. If iTimeout > (mItem.Duration * 10) + 35 Then
    29. MessageBox.Show("Resultdialog not found. Measurement abort!", "Sequence Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1)
    30. Me.abordMeasure = True
    31. Exit Sub
    32. End If
    33. End While
    34. ' search dialog buttons
    35. buttonHandle = IntPtr.Zero
    36. childWindow = WinAPI.GetChildWindows(dialogHandle)
    37. For Each i As IntPtr In childWindow
    38. If getClassName(i) = "Button" AndAlso getText(i) = "&No" Then
    39. buttonHandle = i
    40. Exit For
    41. End If
    42. Next
    43. ' press 'No' Button
    44. If Not buttonHandle.Equals(IntPtr.Zero) Then
    45. Me.pressButton(buttonHandle)
    46. Else
    47. MessageBox.Show("Buttonhandle not found. Measurement abort!", "Sequence Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1)
    48. End If
    Moin @Dodo:,
    @Confuzi Us: Wenn Du das die MessageBox erzeugende Fenster hast, kannst Du auf dessen Child warten, das erspart Dir, alle Fenster durchzuklickern.
    Das ganze sollte natürlich in einem Timer ablaufen.
    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!
    @Dodo
    Okay.. ist mir jetzt etwas peinlich, aber.. Das beherrsche ich noch gar nicht,..
    Ich denke da muss ich mir erstmal ein kleines Projekt erstellen, um das zu verstehen. Also generell, vom QC her sieht es eigentlich selbstverständlich aus..

    aber das tut es ja immer ^^


    Gibt es da evtl. eine Seite die das etwas hervorbringt??

    @RodFromGermany
    Wie kann ich denn das Child-Fenster analysieren, bzw. diese Information abgreifen?
    ..ich muss sagen das ich auf dieser Ebene noch nie etwas gemacht habe.. :-/
    @Confuzi Us: Such mal nach Beispielen mit API.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!
    Woah..
    ich suche und suche und finde gar nichts.

    Eigentlich müsste ich doch durch "Imports System.Runtime.InteropServices" auf die WinAPI Klasse zugreifen können?
    Bin ich total auffem Holzweg??
    Ich bin totaaaal verwirrt...

    Habe da noch nie wirklich was gemacht, und ich verstehe gar nicht genau was das bedeutet was ich da lese.. Oh.. X(

    der eine schreibt

    VB.NET-Quellcode

    1. <DllImport("User32", CallingConvention:=CallingConvention.Winapi, SetLastError:=True, CharSet:=CharSet.Unicode)> _



    der andere wieder was anderes...

    Confuzi Us schrieb:

    Bin ich total auffem Holzweg??
    Die API-Funktionen mit ihren korrekten .NET-Deklarationen findest 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!

    Confuzi Us schrieb:

    was ich nun tun kann..
    Such mal Programm fernsteuern, erweiterte Suche mit mir als Autor (siehe Post #5).
    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!

    Confuzi Us schrieb:

    Anwendung fernsteuern
    Sorry.
    Programm fernsteuern ist das Suchwort. Sieh Dir mal diesen Thread an.
    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!
    Hallöle...
    könnte mir einer erklären was das alles bedeutet?

    VB.NET-Quellcode

    1. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long


    Ich weiß nicht wieso ich damit so massiv Probleme habe, momentan verstehe ich einfach nicht was ich damit anfangen kann.

    Ich deklariere hier eine Funktion "FindWindow" durch die DLL "user32" und muss dieser Funktion einen anderen Namen geben "FindWindowA" damit diese in der externen DLL eine neue Bedeutung erlangt?

    ?( ?( ?(
    Richtiges programmieren.. nehme ich mal an- das ist ein Tick schwerer als erwartet.
    ..
    Grüße,
    Confuzi Us

    Confuzi Us schrieb:

    "FindWindowA"
    Außerdem gibt es noch "FindWindowW". "A" steht für "ANSI", "W" für "WideChar", also 8- bzw. 16-Bit pro Char in den Strings bei der Übergabe, gleichbedeutend mit Ansi bzw. Unicode. Das gilt für alle API-Funktionen, bei denen Strings übergeben werden.
    Was die Funktionen an sich machen, da solltest Du einfach Deine Recherche-Fähigkeiten trainieren.
    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!