Identifikation von Fenstern mit gleichen AU3-Infos anhand mehrerer Parameter? Möglichkeit der Identifikation durch Ausschließen von Parametern?

  • Hallo liebe Community,

    als begeisterter Newbie von Autoit bin ich derzeit fleißig am programmieren, bin jetzt aber wiederholt auf ein Problem gestoßen und wäre euch dankbar wenn ihr mir weiterhelfen könntet.

    Folgender Sachverhalt:

    Ich öffne mit Autoit ein Fenster, welches lt. AU3-Info-Tool folgende Window-Parameter besitzt:
    Title:
    Class: class_470
    Position: 1088, 292
    Size: 890, 470
    Style: 0x14CF0000
    ExStyle: 0x00000100
    Handle: 0x00020598

    Da das Fenster keinen Titel besitzt, sich über class, style... (erweiterte Fensterfunktionen) nicht ansteuern lässt und die Position des Fenster beim Öffnen dynamisch ist bleibt mir nur die Ansteuerung über "Size".

    [autoit]


    WinActivate("[W: 890; H: 470]")
    WinWaitActive("[W: 890; H: 470]", "", 1)
    $Handle_Fenster1 = WinGetHandle("[W: 890; H: 470]")

    [/autoit]

    Im nächsten Schritt öffne ich ein weiteres dieser Fenster mit den gleichen AU3-Tool-Infos (kein Titel, gleicher classname, gleiche Size) allerdings einem anderen Handle.
    Bisher habe ich dieses Fenster ebenfalls über Size angesteuert, hin und wieder kommt es allerdings vor, dass dadurch fälschlicherweise das erste (zuvor geöffnete) Fenster angesteuert wird.
    Da im nächsten Schritt noch ein weiteres dieser Fenster geöffnet wird, kann es durch die alleinige Ansteuerung über "Size" zu Problemen führen.

    Gibt es programmiertechnisch die Möglichkeit, dass ich Autoit beim zweiten Fenster die Anweisung gebe:
    Suche das Fenster mit der "Size" [W: 890; H: 470] und schließe gleichzeitig das Fenster mit dem Handle von Fenster1 aus (im Sinne von: not $Handle_Fenster1), so dass nur noch das zweite Fenster übrig bleiben kann?
    Also, dass Autoit zuerst alle Fenster mit der "Size" [W: 890; H: 470] sucht und dann im Ausschlussverfahren über das Handle das richtige Fenster ansteuert (nämlich das einzige, welches noch nicht zuvor als Handle definiert wurde)

    Kann man das mit booleschen Operatoren nach folgender Logik definieren (funktioniert so leider nicht):

    [autoit]


    WinActivate("[W: 890; H: 470]" and not $Handle_Fenster1)

    [/autoit]

    bzw. bei mehrere Handles zum ausschließen:

    [autoit]


    WinActivate("[W: 890; H: 470]" and not ($Handle_Fenster1 and $Handle_FensterX))

    [/autoit]

    Oder kennt ihr vielleicht eine andere möglichst sichere Lösung?


    Vielen Dank vorab

    Grüße
    tobius

  • Danke, aber die Fenster sind alle identisch, sie haben die gleiche Klasse (und lassen sich zudem nicht über "[CLASS:class_470]" ) ansprechen), die gleiche Größe und keinen Text.
    Demnach muss das Fenster wohl irgendwie über das Handle angesteuert werden..
    Können die booleschen Operatoren bei Parametern nicht verwendet werden oder weiß jemand noch einen anderen Ansatz?

    Danke

  • Danke, aber die Fenster sind alle identisch, sie haben die gleiche Klasse (und lassen sich zudem nicht über "[CLASS:class_470]" ) ansprechen), die gleiche Größe und keinen Text.
    Demnach muss das Fenster wohl irgendwie über das Handle angesteuert werden..
    Können die booleschen Operatoren bei Parametern nicht verwendet werden oder weiß jemand noch einen anderen Ansatz?

    Danke


    Zudem haben sie keinen Titel...
    Was soll das bitte für eine Anwendung sein? 8|
    Könntest du uns bitte mal einen Screenshot dieser *ominösen* Anwendung zeigen? :rolleyes:

    MfG

    There's a joke that C has the speed and efficieny of assembly language combined with readability of....assembly language. In other words, it's just a glorified assembly language. - Teh Interwebz

    C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, you blow off your whole leg. - Bjarne Stroustrup
    Genie zu sein, bedeutet für mich, alles zu tun, was ich will. - Klaus Kinski

  • Das dass jemand fragt, da hab ich drauf gewartet :D

    Um Missverständnisse zu vermeiden, mein Name rührt vom Sternenbild und nicht vom Shop her :D


    Rainbow Dash :rock:

    "Das, wobei unsere Berechnungen versagen, nennen wir Zufall." (Albert Einstein)

  • Leider kann ich keinen Screenshot hier rein stellen (sonst hätt ich es direkt gemacht), da es sich um eine Software von der Arbeit handelt und die angezeigten Daten vertraulich sind und im Startfenster nicht ausgeblendet werden können.
    Es handelt sich um ein Tool zur Datenaufbereitung, mehr Infos wie oben beschrieben gibt das AU3-Info-Tool aber leider nicht her.
    Ich habe aber herausgefunden, dass ich einen Titel mittels WinSetTitle setzen kann, das bringt mich aber auch nicht wirklich weiter, oder?
    Falls noch jemand einen Ansatz hat wäre ich sehr dankbar.

  • Ich hätte da noch paar Ansätze, allerdings fehlen mir noch wichtige Informationen:
    - Haben die Fenster unterschiedliche Positionen?
    -> Wenn ja: Sind die Fensterpositionen zufällig irgendwo gespeichert für den nächsten Programmstart?
    - Beinhalten sie unterschiedliche Controls worüber sie idenfizierbar wären?
    - Unterscheiden sie sich farblich voneinander?

    Liste am besten ALLE unerschiede auf die du an deinen Fenstern finden kannst. Es gibt noch zich Möglichkeiten um eines dieser Fenster anzusprechen! Screenshots wären wirklich nicht schlecht...

  • Leider kann ich keinen Screenshot hier rein stellen (sonst hätt ich es direkt gemacht), da es sich um eine Software von der Arbeit handelt und die angezeigten Daten vertraulich sind und im Startfenster nicht ausgeblendet werden können.


    Du könntest in der Arbeit einen Screenshot machen und zuhause dann via Paint o.Ä. einen schwarzen Balken über die angezeigten, sensiblen Daten legen. ;)

    MfG

    There's a joke that C has the speed and efficieny of assembly language combined with readability of....assembly language. In other words, it's just a glorified assembly language. - Teh Interwebz

    C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, you blow off your whole leg. - Bjarne Stroustrup
    Genie zu sein, bedeutet für mich, alles zu tun, was ich will. - Klaus Kinski

  • Danke für eure Rückmeldungen.
    @ PainTain: Dann bleibt nur noch der Fensterrahmen als Screenshot übrig ;)
    @ Make-Grafik:
    Die Fenster besitzen keine Controls und die Positionen beim Öffnen sind mehr oder weniger zufällig.
    Grafisch sind die Fenster exakt identisch, imagesearch/pixelsearch ist daher nicht möglich.
    Nur das Handle unterscheidet sich, alle anderen Infos sind identisch.

    Ich löse es jetzt folgendermaßen:
    Ich öffne das erste Fenster und identifiziere es über die Grüße (die ist immer gleich).
    Danach vergebe ich dem Fenster einen Titel und ändere die Größe.
    Wenn ich anschließend ein neues Fenster öffne kann ich es an der ursprünglichen Größe identifizieren (die Größe des ersten Fensters habe ich ja geändert).
    Dem zweiten Fenster vergebe ich dann wieder einen neuen Titel u. ändere auch hier die Größe.
    So mache ich das für alle Fenster. Am Ende ändere ich die veränderten Größen wieder in ihre Ursprungsgröße zurück (notwendig für den nächsten Programmstart, da anscheinend die Größe des letzten Fensters beibehalten wird) und steuere letztlich alle Fenster über ihren Titel.

    [autoit]


    WinActivate("[W: 890; H: 470]")
    WinWaitActive("[W: 890; H: 470]", "", 1)
    WinSetTitle("[W: 890; H: 470]", "", "Fenster1")
    WinMove("Fenster1", "", "", "", 891, 471)
    ; Neues Fenster wird geöffnet
    WinActivate("[W: 890; H: 470]")
    WinWaitActive("[W: 890; H: 470]", "", 1)
    WinSetTitle("[W: 890; H: 470]", "", "Fenster2")
    WinMove("Fenster2", "", "", "", 891, 471)
    ; usw

    [/autoit]

    Vielen Dank für eure Unterstützung.

    • Offizieller Beitrag

    Demnach muss das Fenster wohl irgendwie über das Handle angesteuert werden..

    Und wo ist das Problem?
    Die WinXXX-Befehle lassen sich doch auch mit dem Handle anstelle des Titels nutzen:

    [autoit]

    WinActivate($handle)

    [/autoit]


    funktioniert doch...
    Wobei man folgendes beachten sollte:

    Zitat

    When you use a window handle for the title parameter then the text parameter is completely ignored.

  • Ja stimmt, über Handles lassen sich die Fenster auch steuern.
    Entweder über Titel (gleich mit eigenem Namen) oder Handles.

    In beiden Fällen muss ich aber ja erstmal das Fenster erkennen, oder?
    Das Handle würde ich dann anhand "Size" auslesen, weil es sich bei jedem Programmstart ändert.

    Handle:

    [autoit]

    $Handle_Fenster1 = Wingethandle("[W: 890; H: 470]")

    [/autoit]

    Titel:

    [autoit]

    $Titel_Fenster1 = Winsettitle("[W: 890; H: 470]")

    [/autoit]


    .."leerer Titel" oder aktives Fenster könnte bestimmt auch gehen aber ist mir bißchen zu schwammig.

    Wenn ich jetzt aber das zweite Fenster öffne ist ein Ansteuern über "Size" sehr fehleranfällig, da beide Fenster die gleiche Größe haben.
    In den meisten Fällen nimmt er dann das zweite, aktive Fenster aber leider nicht immer.

    Somit kann ich wohl nur noch am Handle oder Titel unterscheiden, macht ja keinen Unterschied.

    Am Beispiel Handle:
    fürs erste Fenster = $Handle_Fenster1
    fürs zweite Fenster = "noch unbekannt"

    Zur Unterscheidung muss ich doch noch das Handle des zweiten Fenster über Wingethandle auslesen oder sehe ich das falsch?
    Welche Parameter nehme ich dann für die Funktion?

    Ich dachte eine sichere Lösung sei es, nun alle Fenster mit der Größe ("[W: 890; H: 470]") zu ermitteln, um dann das Handle des "noch unbekannten" (zweiten) Fensters zu ermitteln, indem ich das Handle des ersten Fensters $Handle_Fenster1 ausschließe.

    • Offizieller Beitrag

    Kannst Du die Anwendung über RUN starten?
    Dann hättest Du die PID und damit kann man Title und Handle bekommen:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    $PID = Run('cmd.exe')
    ConsoleWrite('PID: ' & $PID & @CR)
    Sleep(100)
    $aTitleHandle = _PID2WinTitleHandle($PID)
    ;~ _ArrayDisplay($title)
    ConsoleWrite('Title: ' & $aTitleHandle[0][0] & @CR)
    ConsoleWrite('Handle: ' & $aTitleHandle[0][1] & @CR)
    WinClose($aTitleHandle[0][1])

    [/autoit] [autoit][/autoit] [autoit]

    Func _PID2WinTitleHandle($PID)
    Local $aTH[1][2], $aList = WinList()
    For $i = 1 To $aList[0][0]
    If $PID = WinGetProcess($aList[$i][1]) Then
    $aTH[UBound($aTH) - 1][0] = $aList[$i][0]
    $aTH[UBound($aTH) - 1][1] = $aList[$i][1]
    ReDim $aTH[UBound($aTH) + 1][2]
    EndIf
    Next
    If UBound($aTH) > 1 Then ReDim $aTH[UBound($aTH) - 1][2]
    Return $aTH
    EndFunc ;==>_PID2WinTitleHandle

    [/autoit]
  • Ich habe noch einen weiteren Ansatz über Winlist, scheitere aber leider an der Umsetzung.
    Weiß jemand wie ich das Folgende in "Programmierschrift" bekomme?

    Ermittle zum Zeitpunkt x alle Fensterhandles über Winlist.
    Öffne Fenster 1
    Ermittle zum Zeitpunkt y alle Fensterhandles über Winlist.
    Vergleiche alle Fensterhandles zum Zeitpunkt y mit den Fensterhandles zum Zeitpunkt x, so dass Handle_Fenster1 = (Fensterhandles Zeitpunkt y - Fensterhandles Zeitpunkt x)

    Hier mal Code von Schnitzel (danke!) wie ich alle aktuellen Fensterhandles ausgebe (funktioniert soweit auch wunderbar):

    [autoit]


    #include <Array.au3>
    Global $winlist, $sichtbareFenster[1]
    $winlist = WinList()

    [/autoit][autoit][/autoit][autoit]

    For $i = 1 To $winlist[0][0]
    If IsVisible($winlist[$i][1]) Then
    _ArrayAdd($sichtbareFenster, $winlist[$i][1])
    $sichtbareFenster[0] = UBound($sichtbareFenster) - 1
    EndIf
    Next

    [/autoit][autoit][/autoit][autoit]

    _ArrayDisplay($sichtbareFenster)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func IsVisible($handle)
    If BitAnd( WinGetState($handle), 2 ) Then
    Return 1
    Else
    Return 0
    EndIf
    EndFunc

    [/autoit]


    Danke vorab