Fenster mit sich ändernden Namen auf zweiten Monitor schieben

  • Hallo zusammen,

    kleinere Scripte habe ich schon ohne Probleme hinbekommen. Hier beisse ich mir die Zähne aus.
    Ich bin Systemintegrator und kein Anwendungsentwickler... hoffe die Kollegen können mir weiterhelfen.

    Ich benötige für einen Kunden ein Script das ein Kamerafenster automatisch, wenn es aktiv wird, auf den zweiten Monitor schiebt.
    Aktiviert wird es durch ziehen der Kamera an einer Behandlungseinheit über eine externe Software.
    Das Fenster ändert jeden Tag seinen Namen. Für heute z.B. "VI 13.05.14"
    Danach soll es in eine Schleife gehen und wieder warten bis das Fenster auf dem falschen (ersten) Monitor aktiv wird. Oder aber halt warten bis es beendet wird und wieder von vorne anfangen. Es ist ein Windows7 Rechner. Also ein

    [autoit]

    Send("{SHIFTDOWN}{LWINDOWN}{RIGHT}{SHIFTUP}{LWINUP}")

    [/autoit]

    würde zum verschieben reichen.

    Einmal editiert, zuletzt von daftmab (14. Mai 2014 um 13:26)

    • Offizieller Beitrag

    Schau dir mal mit dem AutoIt-Window-InfoTool das Fenster genau an. Ist evtl. die CLASS auslesbar? Dann kannst du dir den Zugriff über den Titel schenken und die CLASS verwenden. Ansonsten kannst du mit der Option "WinTitleMatchMode" festlegen, dass auch Teile des Fenstertitels zur Erkennung genügen. Ich vermute ein Teil des Fensternamens wird immer identisch sein.

  • Danke für deine Antwort.
    Das Problem ist momentan nicht das Fenster zu erkennen, sonder ehr eine vernünftige Whileschleife hin zu bekommen.
    Ich poste mal zu eurer Erheiterung was ich bis dato gemacht habe. Einer von vielen Versuchen btw.

    Spoiler anzeigen


    fWait()
    Func fWait()
    If WinWaitActive("VI ","") Then
    Call fMove()
    EndIf
    EndFunc
    Func fMove()
    Local $aPos = WinGetPos("VI ")
    If $aPos = 0[1] Then
    Send("{SHIFTDOWN}{LWINDOWN}{RIGHT}{SHIFTUP}{LWINUP}")
    ElseIf $aPos <> 0[1] Then
    Send("{LWINDOWN}{LWINUP}")
    EndIf EndFunc

    beendet mit Fehler: AutoIt3.exe ended.rc:-1073741819

    oder

    Spoiler anzeigen

    While 1=1
    if WinWaitActive("VI ","") Then
    Sleep (500)
    Local $aPos = WinGetPos("VI ")
    If $aPos = 0[1] Then
    Send("{ALTDOWN}{TAB}{ALTUP}")
    ElseIf $aPos <> 0[1] Then
    Send("{LWINDOWN}{LWINUP}")
    EndIf
    EndIf
    WEnd


    beendet mit Fehler: Subscript used on non-accessible variable

    Beide beenden aber erst nachdem das Fenster aktiv wurde. Solange es im Hintergrund ist läuft es.

  • Naja wie wärs mal mit Syntaxcheck in Scite bevor du deine Scripte ausführst? Das wird dir alle Fehler inklusive Zeilenangabe ausgeben. Zum Beispiel das hier:

    [autoit]

    If $aPos = 0[1] Then

    [/autoit]

    Keine Ahnung was du damit erreichen willst. Es ist sowohl syntaktisch falsch (außer 0 wäre ein Array), zum anderen ist $aPos entweder 0 (wenn das Fenster nicht gefunden wurde) oder ein Array. Am sichersten wäre die Prüfung mit

    [autoit]

    isarray()

    [/autoit]


    Nur wenn es ein Array ist hast du Koordinaten des Fensters und kannst $aPos als Array ansprechen. Da kommen wir zum nächsten Punkt.

    [autoit]

    wingetpos()

    [/autoit]


    liefert dir keine Infos darüber ob sich das Fenster auf dem primären oder sekundären Monitor befindet, sondern nur absolute Koordinaten des Fensters bezogen auf die gesamte Desktopfläche. Du musst also schon noch ein wenig mehr Aufwand betreiben um letzlich herauszufinden ob das Fenster woanderst hin soll oder nicht. Solltest du das zuverlässig hinbekommen haben rate ich dir dringendst davon ab mit

    [autoit]

    Send()

    [/autoit]

    zu arbeiten, da das viel zu unzuverlässig ist und ggf. mit Benutzereingaben kollidiert. Besser wäre in deinem Fall wohl die Nutzung von

    [autoit]

    winmove()

    [/autoit]
  • Hat der Fenstertitel denn immer das Schema VI XX.YY.ZZZZ?
    Dann könnte man - wie BugFix sagte - partielle Matches benutzen... Oder einen RegExp-Match mit REGEXPTITLE als Selektor. "VI" z.B. ist wahrscheinlich öfter anzutreffen, und dann lieber ein wenig mehr Aufwand betreiben, und so das Verschieben von z.B. "Windows Live Movie Maker" vermeiden.

    Gruß

  • danke für eure hinweise.
    misterspeed
    wie gesagt. ich habe null mit awe zu tun. arbeite mich grad nur ein bisschen in auto it ein. ich werde mir jetzt erstmal anschauen was ein array ist und vielleicht komme ich damit ja auf den richtigen weg.
    und das mit dem syntaxcheck ist tatsächlich ein hinweis der gold wert ist. ich dachte ich bekomme nicht mehr informationen aus dem scite raus. keine ironie. wie gesagt. kein awe...  ?(

    chesstiger
    sicherlich hast du recht damit. aber das habe ich mir gaaaaanz zum schluß vorgenommen. erstmal hoffe ich das der überhaupt irgend etwas macht...

  • LÄUFT!
    Dank euch! Werde vllt jetzt noch mit Class arbeiten um das "VI " weg zu bekommen.
    Obwohl das mit dem Leerzeichen danach schon selten vorkommen wird.

    Spoiler anzeigen


    While 1=1
    Local $hWnd = WinWaitActive("VI ","")
    Local $aPos = WinGetPos($hWnd)
    If $aPos[0] <> "1080" Then
    WinMove($hWnd, "", 1080, 340, 400, 400, 2)
    ElseIf IsArray($aPos[0]) = "1080" Then
    EndIf
    WEnd

    Beim Kunden muss ich jetzt noch die richtige Position und den Class Namen herausfinden.
    /edit
    Okay... doch nicht erledigt... habe eine Fehler gefunden. Wenn ich das Fenster schließe bricht auch das Script ab.
    /edit2
    WinWaitClose($Whnd)
    fängt es ab. Reicht für meine Zwecke.

    2 Mal editiert, zuletzt von daftmab (13. Mai 2014 um 23:09)

  • Erstmal was zur korrekten Nutzung des Forums hier...

    Poste Autoit Quellcode bitte immer so:

    • [Blockierte Grafik: http://i.imgur.com/0Ad5mrS.png]
    • sinnvollerweise nur bei mehr als 20 Zeilen
    • Formatierten Autoit Quellcode zwischen den Autoit BBcodes einfügen

    Nun zu deinem Code, der immernoch absoluter murks ist:

    [autoit]


    While 1=1 ; while 1 würds genauso tun...
    Local $hWnd = WinWaitActive("VI ","") ; erstmal verwendet man local normalerweie in Funktionen, außerhalb wird mit global deklariert
    Local $aPos = WinGetPos($hWnd) ; zum anderen deklariert man Variablen nicht unendlich oft in Schleifen, sondern bevorzugt nur einmal bevor man sie nutzt, sprich bei dir vor der Schleife
    If $aPos[0] <> "1080" Then ; gewöhn dir besser garnicht erst an Zahlen mit Strings zu vergleichen, die Werte die wingetpos ermittelt sind Zahlen und keine Strings, also vergleich sie bitte auch mit Zahlen (sprich lass die Anführungszeichen weg)
    WinMove($hWnd, "", 1080, 340, 400, 400, 2) ; und wie kommst du darauf, dass alle Monitore auf denne das Script läuft die gleiche Auflösung haben und 1080 überall auf dem 2. Monitor liegen wird?
    ElseIf IsArray($aPos[0]) = "1080" Then
    #cs
    fataler Fehler in mehrerlei Hinsicht, zum einen übergibt man an isArray() ein Array und nicht den Wert eines Arrays, zum anderen ist es längst zu spät zu prüfen ob du überhaupt ein Array hast, das musst du tun bevor du die Variable zum ersten mal als Array ansprichst!
    Ansonsten stürzt dir das Script bereits 2 Zeilen weiter oben ab, wenn die Daten des Fensters nicht ermittelt werden konnten. isArray() gibt außerdem immer 1 oder 0 zurück, der Vergleich mit 1080 ist also sinnfrei, auch hier im übrigen wieder der Vergleich mit einem String.
    Strings werden immer als 0 interpretiert wenn man mit Zahlen vergleicht, dadurch funktioniert der Vergleich sogar, was aber sicher nicht von dir gewollt war.
    #ce
    EndIf
    WEnd

    [/autoit]

    Hier die korrigierte Fassung:

    [autoit]


    Global $hWnd, $aPos

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

    While 1
    $hWnd = WinWaitActive("VI ","") ; besser etwas eindeutigeres wie die class oder einen regulären Ausdruck nutzen (siehe chesstiger), statt winwaitactive(...) könnte auch "if winexists(...) then" Sinn machen
    $aPos = WinGetPos($hWnd)
    If IsArray($aPos) then ; stellt sicher, dass $aPos ein Array ist und nach dem Schema $aPos[x] angesprochen werden kann
    If $aPos[0] <> 1080 Then
    WinMove($hWnd, "", 1080, 340, 400, 400, 2)
    Else
    ; wolltest du überhaupt etwas tun wenn das Fenster bereits da ist wo es sein soll? ich denke nicht, das else kann also wohl weg.
    EndIf
    EndIf
    ;Sleep(100) ; es sollte ja reichen wenn du 10 mal in der Sekunde prüfst ob da ein Fenster zu verschieben ist oder nicht (wäre relevant wenn du winexists verwendest)
    WEnd

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

    ; wie wolltest du das Programm eigentlich beenden? Per Taskmanager oder was?

    [/autoit]

    2 Mal editiert, zuletzt von misterspeed (14. Mai 2014 um 20:58)