Jump to content

Recommended Posts

I am trying to swap identical windows from monitor 1 and monitor 2 but I don't know how to use the PID with WinMove?

Func Swap()
    Local $Actwin = WinGetHandle("[active]")
    Local $iPID = WinGetProcess($Actwin)
    Local $NamePidActwin = _Findpidname($iPID)
    Local $aProcessList = ProcessList("[active]")
    If $Stall1 = 1 And $Stall2 = 2 Then
    Local $Win1 = $aProcessList[1][0]
    Local $Win2 = $aProcessList[2][0]
    WinMove($Win1, "", 1921, 0)
    Sleep(500)
    WinMove($Win2, "", 0, 0)
    $Stall1 = 0
    $Stall2 = 0
    Else
    Local $Win1 = $aProcessList[2][0]
    Local $Win2 = $aProcessList[1][0]
    WinMove($Win2, "", 1921, 0)
    Sleep(500)
    WinMove($Win1, "", 0, 0)
    $Stall1 = 1
    $Stall2 = 2
    EndIf
EndFunc

Obviously WinMove requires a title but I have to programs open with the same title, so I grab each PID individually and store them in an array. I don't know how to call each array within a WinMove. Is this possible?

It is really sloppy I know, I couldn't figure out a good way to have the logic keep the each window unique.

Share this post


Link to post
Share on other sites

Something like this? Swaps the first two windows with the same title as the active window... Obviously, you can add some checks and validate handles etc...

#include <Array.au3>
Global $aWinList = WinList(WinGetTitle("[active]"))
Global $aPos
Global $x1, $y1, $x2, $y2
$aPos = WinGetPos($aWinList[1][1])
$x1 = $aPos[0]
$y1 = $aPos[1]
$aPos = WinGetPos($aWinList[2][1])
$x2 = $aPos[0]
$y2 = $aPos[1]
WinMove($aWinList[1][1], "", $x2, $y2)
WinMove($aWinList[2][1], "", $x1, $y1)

 


Problem solving step 1: Write a simple, self-contained, running, replicator of your problem.

Share this post


Link to post
Share on other sites

Interesting, when I try and run it, it says "Unable to parse lines" on the last WinMove statement.

With Scite I get "Statement cannot be just an expression. (illegal character)"

I have never seen that before.

Share this post


Link to post
Share on other sites
15 minutes ago, kjpolker said:

Interesting, when I try and run it, it says "Unable to parse lines" on the last WinMove statement.

With Scite I get "Statement cannot be just an expression. (illegal character)"

I have never seen that before.

 

 

Probably wouldn't hurt to add some error checking to make sure each function is succeeding.  Probably best way to debug anything 

 

The last line probably goes out of bounds 

If ubound($winlist)- 1=2 then 

;move

Endif

I give up...editing issues 

 

Oops sorry this is a 1 based array but you can do an _arradisplay($winlist) to see what's in there.  Probably still going out of bounds I think active may only find the top most window.  Probably pointless to have it in there at all if you're searching by title

Edited by markyrocks
Grrr

Share this post


Link to post
Share on other sites

Yeah I am still not having much luck. I switched [active] over to chrome for testing and still having errors everywhere. Everything follows the same setup as the help file under WinGetPos.

What is meant when you say out of bound? I am not familiar with what's going on there?

EDIT:

So what I am finding out through error checking is that the position remains 0,0 even for window 2 which is located at 1920,0?

Global $aWinList = WinList(WinGetTitle("[ACTIVE]"))
    Global $aPos
    Global $x1, $y1, $x2, $y2
    $aPos = WinGetPos($aWinList[1][1])
    $x1 = $aPos[0]
    $y1 = $aPos[1]
    MsgBox(0, '', $aWinList[1][1] & @CRLF & "x: " & $x1 & @CRLF & "y: " & $y1)
    $aPos = WinGetPos($aWinList[2][1])
    $x2 = $aPos[0]
    $y2 = $aPos[1]
    MsgBox(0, '', $aWinList[2][1] & @CRLF & "x: " & $x2 & @CRLF & "y: " & $y2)

Although the handles are uniquely identified as each.

EDIT2:

And when I just hardcode the values to be the proper X and Y I still receive original error.

Edited by kjpolker

Share this post


Link to post
Share on other sites

Can you post a pic of the error and use _arratdisplay($winlist) and see what's in there.  Post that pic too.

Check this out.  Win active only returns one window. 

Out of bounds is when an array exceeds the memory that is allocated to it.  That's why its critical to use ubound()-1 bc it determines the out of bounds range.   The -1 puts you at the last element of the array.

If the ubound ($winlist)-1 is only equal to 2 trying to access the 3rd element will return an out of bounds error bc nothing is their and it exceeds the range of the array.  Use wingettitle("").  Should return every window on the screen even if its hidden.   Just get all the windows and sort through the array.  Using a loop.

 

Screenshot_20200117-192621_Samsung Internet.jpg

Edited by markyrocks

Share this post


Link to post
Share on other sites

So using _arraydisplay() I get only one instance of any program open. It seems to ignore the specified window title (Changed from [active]).

If I focus Notepad 1 it shows the proper handle, then when I focus Notepad 2 it shows that handle as well. But not both instances like I presume it should.

Global $aWinList = WinList(WinGetTitle("Notepad.exe"))
    _arraydisplay($aWinList)

My guess is that you're right in the array being out of bounds because it does not find the 2nd one.

Using some error checks and the IF ubounds statement it does not proceed through the code.

example.png

Share this post


Link to post
Share on other sites

Try those, both will get you all the windows :

#include <Array.au3>

Local $aList = WinList ("[CLASS:Notepad]")
_ArrayDisplay ($aList)

Local $aList = WinList ("[REGEXPTITLE:(?i)(.*Notepad.*)]")
_ArrayDisplay ($aList)

 

Share this post


Link to post
Share on other sites
5 hours ago, Nine said:

Try those, both will get you all the windows :

#include <Array.au3>

Local $aList = WinList ("[CLASS:Notepad]")
_ArrayDisplay ($aList)

Local $aList = WinList ("[REGEXPTITLE:(?i)(.*Notepad.*)]")
_ArrayDisplay ($aList)

 

I see they both work! Could you please explain what the second one is doing? Or direct me to a resource. I don't understand anything with the quotes of

Local $aList = WinList ("[REGEXPTITLE:(?i)(.*Notepad.*)]")

That being said, do I have to use Class to get both window handles then? There's no way to use [ACTIVE] and have the same results?

Bolthead;

I will check into that shortly, as my original code utilized PID but I have switched over because I didn't think it was possible to use the PID to move windows. Thank you!

Share this post


Link to post
Share on other sites

[Active] will only get you one handle.  You can match [active] handle with a WinList array of handles to do whatever you want to do.  If you want a good reference to REGEXP, look at StringRegExp in AutoIt help file.  It is a pretty good start. I, for once, did not want to learn SRE, but it is so powerful that you cannot bypass it...

Share this post


Link to post
Share on other sites
44 minutes ago, Nine said:

[Active] will only get you one handle.  You can match [active] handle with a WinList array of handles to do whatever you want to do.  If you want a good reference to REGEXP, look at StringRegExp in AutoIt help file.  It is a pretty good start. I, for once, did not want to learn SRE, but it is so powerful that you cannot bypass it...

Perfect, I will look into those!

Unfortunately even after using

If ubound($aWinList)- 1=2 Then

I still get an "Error: Unable to parse line."

image.png.9b7b41efcd24400b65c2a29ac4bcce3f.png

Maybe I can't WinMove from an array and I should store the handles in a variable and call them?

EDIT:
It's so weird, when I display both windows using $aWinList[1][1]/[2][1] it properly shows each window and it's handle/positions. I just can call them from WinMove.

Edited by kjpolker
added details

Share this post


Link to post
Share on other sites
Func Swap()
    Local $aWinList = WinList("[CLASS:GxWindowClass]")
;~  _ArrayDisplay($aWinList)
    Global $aPos
    Global $x1, $y1, $x2, $y2
    If ubound($aWinList)- 1=2 Then
    $aPos = WinGetPos($aWinList[1][1])
    $x1 = $aPos[0]
    $y1 = $aPos[1]
;~  MsgBox(0, '', $aWinList[1][1] & @CRLF & "x: " & $x1 & @CRLF & "y: " & $y1)
    $aPos = WinGetPos($aWinList[2][1])
    $x2 = $aPos[0]
    $y2 = $aPos[1]
;~  MsgBox(0, '', $aWinList[2][1] & @CRLF & "x: " & $x2 & @CRLF & "y: " & $y2)
    WinMove($aWinList[1][1], "", $x2, $y2)
    Sleep(500)
    WinMove($aWinList[2][1], "", $x1, $y1)
    Sleep(500)
    EndIf
EndFunc

This is called by a HotKey

Share this post


Link to post
Share on other sites

You probably have a bad character at the end of that line, remove the whole line and rewrite it manually

Share this post


Link to post
Share on other sites

Ubound($winlist)-1=3 ;should be

I know I probably confused you earlier 

It's a 1 based array.   The first element is the count.  So first element is count, 2 is the first window,  3 is the 3rd.  You need to read up on arrays bc they're a pain in the butt and give even experienced users problems. 

Share this post


Link to post
Share on other sites
1 hour ago, Nine said:

You probably have a bad character at the end of that line, remove the whole line and rewrite it manually

That was absolutely the problem... Who the hell would have thought?! Literally nothing changed as far as my eyes can tell but it works.

Thank you!

Edited by kjpolker

Share this post


Link to post
Share on other sites
7 hours ago, markyrocks said:

It's a 1 based array. 

AutoIt only uses "zero(0)-based indexing" for arrays !

==> Variant 1 : [Index=0] -> Count ; [Index=1] -> Element_1 , [Index=2] -> Element_2 ...

==> Variant 2 : [Index=0] -> Element_1 ; [Index=1] -> Element_2 , [Index=2] -> Element_3 ...

The fact, that in Variant 1 the Index=1 contains the first 'real' element does not make it a "one(1)- based array".

I hope I'm not writing nonsense now. Apparently 80% of my brain cells are still fighting the beers from yesterday's party :lol:.


Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Share this post


Link to post
Share on other sites

@kjpolker

Global $aPos
Global $x1, $y1, $x2, $y2

Why creating those variables as Global, doesn't seem to be required. They should have been declared Local instead. In general, try to avoid declaring Global inside functions, it makes programs hard to read and maintain.  If needed, declare the Global vars at the top of the script, this is a good programming practice.

If ubound($aWinList)- 1=2 Then

This is not a very elegant programming usage.  Since WinList returns the number of found windows, you should have use :

If $aWinList[0][0] = 2 Then

 But maybe I am too picky :)

Edited by Nine

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...