Jump to content


Photo

Run script on active window change


  • Please log in to reply
10 replies to this topic

#1 raziel024

raziel024
  • Members
  • 9 posts

Posted 13 May 2012 - 06:53 PM

This is specially useful on multimonitor systems.
This code in particular, move the mouse cursor to the centre of the active window(no matter the screen where the window is) when ALT+TAb is pressed:
~!Tab::
KeyWait, Alt
KeyWait, Tab
WinGetPos,x,y,width,height,A
While (x < 0 Or y < 0)
{
    Sleep,100
    WinGetPos,x,y,width,height,A
    IfGreater,A_Index,2,Break
}
MouseMove,width/2,height/2
return
Now what I want is run this script when the active window change. So it can be used not only when I press ALT+TAb since there are many ways to change active window (like 3rd party software, or Window Taskbar).
I introduce this example for a better understanding: (By windows I mean plural of window)
I have 2 screens, A and B. There are 2 windows, 1 and 2. The window 1 is in the screen A and the window 2 is in the screen B.
The window 1 is currently focused( or active), now when I change using the taskbar to window 2(now the active window is the window 2) run the script.
Is that possible? Any idea?
Regards.

#2 Leef_me

Leef_me
  • Moderators
  • 7704 posts

Posted 13 May 2012 - 11:36 PM

Look at "settimer" command to repeatedly test
look at "WinGet" to get the active ID
add another layer of check, if the current window is the same as the previous window (no alt-tab) :arrow: do nothing
if the window changed, move to the new center

#3 raziel024

raziel024
  • Members
  • 9 posts

Posted 15 May 2012 - 02:41 PM

Yeah, but can someone give me a hand with an example about how to implement this?
Should I use #persistent?.
And how do I know where's the mouse cursor? (Because I wanna implement this: move the mouse only if the newly activated window is in a different screen than the previous one).
This will be awesome for those who use more that one screen.
Regards.

#4 engunneer

engunneer
  • Fellows
  • 9162 posts

Posted 15 May 2012 - 02:48 PM

you only need #persistent if your script doesn't have any hotkeys or guis. it just makes the "auto close at end of script" turn off.

MouseGetPos in conjunction with WinGetPos and CoordMode gives you all information about where everything is on the screen.

#5 Leef_me

Leef_me
  • Moderators
  • 7704 posts

Posted 15 May 2012 - 03:00 PM

See the script from girlgamer in this thread
<!-- l --><a class="postlink-local" href="http://www.autohotkey.com/community/viewtopic.php?t=68440">viewtopic.php?t=68440</a><!-- l -->

#6 raziel024

raziel024
  • Members
  • 9 posts

Posted 15 May 2012 - 03:41 PM

I decide re-design my question better...
I have 2 screens, A and B. There are 2 windows, 1 and 2. The window 1 is in the screen A and the window 2 is in the screen B.
The window 1 is currently focused( or active), now when I change using the taskbar (or whatever other metod to change between windows) to window 2(now the active window is the window 2) if the mouse cursor is not in the same screen than the window 2, move the mouse cursor to the center of the window 2.
Regards.

#7 Pulover

Pulover
  • Members
  • 1253 posts

Posted 15 May 2012 - 04:34 PM

See if this one works for you.
I used WinWaitActive and RegEx in a Loop to wait for any active window and some variables to check if it has changed.
You can get the same results using SetTimer, as mentioned above.

SetTitleMatchMode RegEx

Loop
{
	WinWaitActive, .*
	WinGetClass, ThisWindow
	If ThisWindow <> %LastWindow%
	{
		WinGetPos,x,y,width,height,A
		While (x < 0 Or y < 0)
		{
			Sleep,100
			WinGetPos,x,y,width,height,A
			IfGreater,A_Index,2,Break
		}
		MouseMove,width/2,height/2
		LastWindow = %ThisWindow%
	}
}
return


#8 engunneer

engunneer
  • Fellows
  • 9162 posts

Posted 15 May 2012 - 04:49 PM

we were hoping you'd take the suggested commands and try to write something. Here's an outline

SetTimer, checkActiveWindow, 100
excludelist = 
(LTrim
  Progman
  #32770
  TaskSwitcherWnd
  Any other window/dialog that shouldn't trigger this
)
ActiveLastTitle := ActiveNowTitle
ActiveLastX:= ActiveNowX
ActiveLastY := ActiveNowY
ActiveLastWidth := ActiveNowWidth
ActiveLastHeight := ActiveNowHeight
CoordMode, Mouse, Screen
Buffer := 50
Return

checkActiveWindow:
WinGetTitle, ActiveNowTitle, A
WinGetTitle, ActiveNowClass, A

;exclude some windows from detection
Loop, parse, excludelist, `n, `r
{
  if InStr(ActiveNowTitle, A_LoopField)
    Return
  if InStr(ActiveNowClass, A_LoopField)
    Return
}    

if (ActiveNowTitle <> ActiveLastTitle)
{
  WinGetPos, ActiveNowX, ActiveNowY, ActiveNowWidth, ActiveNowHeight, % ActiveNowTitle
  MouseGetPos, MouseCurX, MouseCurY, MouseCurWin
  if (MouseCurX > ActiveNowX + ActiveNowWidth + Buffer) ;mouse too far to the right of new window
    Gosub, MoveTheMouse
  else if (MouseCurY > ActiveNowY + ActiveNowHeight + Buffer) ;mouse too far to the bottom of new window
    Gosub, MoveTheMouse
  else if (MouseCurX < ActiveNowX - Buffer) ;mouse too far to the left of new window
    Gosub, MoveTheMouse
  else if (MouseCurY < ActiveNowY - Buffer) ;mouse too far to the top of new window
    Gosub, MoveTheMouse
}

ActiveLastTitle := ActiveNowTitle
ActiveLastX:= ActiveNowX
ActiveLastY := ActiveNowY
ActiveLastWidth := ActiveNowWidth
ActiveLastHeight := ActiveNowHeight


Return

MoveTheMouse:
  MouseMove, ActiveNowX + (ActiveNowWidth/2), ActiveNowY + (ActiveNowHeight/2), 0
Return
Esc::ExitApp

tested

#9 raziel024

raziel024
  • Members
  • 9 posts

Posted 18 May 2012 - 01:20 AM

Thanks guys, I really appreciate your help, sorry for not trying your suggestions before.
I'm going to post some code that I made later.

#10 raziel024

raziel024
  • Members
  • 9 posts

Posted 18 May 2012 - 03:24 PM

we were hoping you'd take the suggested commands and try to write something. Here's an outline

SetTimer, checkActiveWindow, 100
excludelist = 
(LTrim
  Progman
  #32770
  TaskSwitcherWnd
  Any other window/dialog that shouldn't trigger this
)
ActiveLastTitle := ActiveNowTitle
ActiveLastX:= ActiveNowX
ActiveLastY := ActiveNowY
ActiveLastWidth := ActiveNowWidth
ActiveLastHeight := ActiveNowHeight
CoordMode, Mouse, Screen
Buffer := 50
Return

checkActiveWindow:
WinGetTitle, ActiveNowTitle, A
WinGetTitle, ActiveNowClass, A

;exclude some windows from detection
Loop, parse, excludelist, `n, `r
{
  if InStr(ActiveNowTitle, A_LoopField)
    Return
  if InStr(ActiveNowClass, A_LoopField)
    Return
}    

if (ActiveNowTitle <> ActiveLastTitle)
{
  WinGetPos, ActiveNowX, ActiveNowY, ActiveNowWidth, ActiveNowHeight, % ActiveNowTitle
  MouseGetPos, MouseCurX, MouseCurY, MouseCurWin
  if (MouseCurX > ActiveNowX + ActiveNowWidth + Buffer) ;mouse too far to the right of new window
    Gosub, MoveTheMouse
  else if (MouseCurY > ActiveNowY + ActiveNowHeight + Buffer) ;mouse too far to the bottom of new window
    Gosub, MoveTheMouse
  else if (MouseCurX < ActiveNowX - Buffer) ;mouse too far to the left of new window
    Gosub, MoveTheMouse
  else if (MouseCurY < ActiveNowY - Buffer) ;mouse too far to the top of new window
    Gosub, MoveTheMouse
}

ActiveLastTitle := ActiveNowTitle
ActiveLastX:= ActiveNowX
ActiveLastY := ActiveNowY
ActiveLastWidth := ActiveNowWidth
ActiveLastHeight := ActiveNowHeight


Return

MoveTheMouse:
  MouseMove, ActiveNowX + (ActiveNowWidth/2), ActiveNowY + (ActiveNowHeight/2), 0
Return
Esc::ExitApp

tested


So after tested your suggestions I want to thank to all the members who participated.
I opted for this, (I do not want to seem ungrateful) but I trying to modify this in order to move the mouse also when the active window go from one screen to another, but with no success. (I know, this can be done with a hotkey, but I'm currently using a program who add some nifty buttons to the titlebar, so with a button I can move the window from one screen to another).
So after hours of trying implement this, I'm stuck and I need some last help. Again thanks.
Regards.

#11 engunneer

engunneer
  • Fellows
  • 9162 posts

Posted 18 May 2012 - 04:33 PM

Using my outline, I'd make another command that is periodically runniing WinGetPos on the active window, and comparing it to the last time WinGetPos was run. That should detect a windo jumping a large distance.

Try making the script look at only the position, and then we can help you merge the two together, if that's easier.