I've only modified few things which ultimately resolves following limitation,
The original script stops working whenever a new window is created. This modified script doesn’t have this limitation.
This script is particularly suitable for duel monitor usages. For my case I run a virtual machine which is on the second monitor and my 1st monitor I run the Host OS. Now to stop my mouse from interrupting the guest user I use this script to limit its movement within a defined area. I know there are other tools to stop mouse going from 2nd monitor but
function is very useful as I can exclude show desktop area in taskbar, so that host can't minimize application of the 2nd monitor. I sincerely want to thank RUNIE from #ahkscript IRC channel for helping me out on this.Ctrl+F4 ; Trap to rectangle
You can select the context to which trap the mouse
- from the tray menu
- with hotkeys. The default ones are:
Code: Select all
Ctrl+F2 Trap to win
Ctrl+F3 Trap to control
Ctrl+F4 Trap to rectangle
Ctrl+Esc Free mouse
Ctrl+Alt+Q Exit
Code: Select all
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
/*
- Traps the mouse in a rectangular area defined by a window, control or user-drawn rectangle.
- Originally, the script used different tray icons to show the mouse state (trapped to control, free, etc), which were taken from this set: http://b-boy1968.deviantart.com/art/MB-Design-Letter-Icons-2-99406904
Relevant lines are commented out
*/
; Modified by Sobuj53 for multi-monitor use
global using := False
global curpos := [0, 0, A_ScreenWidth, A_ScreenHeight]
help =
(
Ctrl+F2 Trap to win
Ctrl+F3 Trap to control
Ctrl+F4 Trap to rectangle
Ctrl+Esc Free mouse
Ctrl+Alt+Q Exit
)
; Icon_free := A_ScriptDir "\F.ico"
; Icon_win := A_ScriptDir "\W.ico"
; Icon_ctrl := A_ScriptDir "\C.ico"
; Icon_rect := A_ScriptDir "\R.ico"
;---
OnExit, Fin
CoordMode, Mouse, Screen
GroupAdd, all_windows ; include all windows except Program Manager
; Menu, Tray, Icon, % Icon_free
Menu, Tray, Add
Menu, Tray, Add, Trap to Window (Ctrl + F2), Menu_win
Menu, Tray, Add, Trap to Control (Ctrl + F3), Menu_ctrl
Menu, Tray, Add, Trap to Rectangle (Ctrl + F4), Menu_rect
TrayTip, ClipCursor, %help%,,1
SetTimer, KillTrayTip, -6000
; return
;---
Gui +LastFound
hWnd := WinExist()
Ptr := A_PtrSize ? "Ptr" : "UInt"
DllCall("RegisterShellHookWindow", Ptr, A_ScriptHwnd)
OnMessage(DllCall("RegisterWindowMessage", Str, "SHELLHOOK"), "WinActiveChange")
DllCall( "RegisterShellHookWindow", UInt,Hwnd )
MsgNum := DllCall( "RegisterWindowMessage", Str,"SHELLHOOK" )
OnMessage( MsgNum, "ShellMessage" )
if using = True
{
ClipCursor(True, curpos*)
}
; Return
;---
^F2::ClipCursor_wrapper("win")
^F3::ClipCursor_wrapper("ctrl")
^F4::ClipCursor_wrapper("rect")
^!q::
Fin:
using := False
ClipCursor(False)
ExitApp
Menu_win:
Menu_ctrl:
Menu_rect:
SetTimer, KillTrayTip, off
StringTrimLeft, context, A_ThisLabel, 5
if (context = "rect")
{
TrayTip, ClipCursor, Activate the target window
Hotkey, ^Esc, Free_mouse, on
WinWaitActive, ahk_group all_windows
ClipCursor_wrapper(context)
}
else
{
TrayTip, ClipCursor, % "Click on the " (context = "win" ? "window" : "control" ) " you wanna`ntrap the mouse into."
Hotkey, LButton, Done_positioning, on, UseErrorLevel
Hotkey, ^Esc, Free_mouse, on
}
return
Done_positioning:
Hotkey, LButton, off
TrayTip
ClipCursor_wrapper(context)
return
Free_mouse:
using := False
ClipCursor(False)
Hotkey, ^Esc, off
; Menu, Tray, Icon, % Icon_free
TrayTip
return
ClipCursor_wrapper(context) {
if (context = "win")
{
MouseGetPos,,, wid
WinActivate, ahk_id %wid%
WinGetPos, wx,wy,ww,wh, ahk_id %wid%
if not (wx and wy and ww and wh)
return
x1:=wx, y1:=wy, x2:=wx+ww, y2:=wy+wh
}
else if (context = "ctrl") ; FIXME: probably could be done with coordmouse window
{
MouseGetPos,,, wid, cid, 2
WinActivate, ahk_id %wid%
WinGetPos, wx,wy,ww,wh, ahk_id %wid%
ControlGetPos, cx,cy,cw,ch,, ahk_id %cid%
if not (cx and cy and cw and ch)
return
x1:=wx+cx, y1:=wy+cy, x2:=wx+cx+cw, y2:=wy+cy+ch
}
else if (context = "rect")
{
ClipCursor(False)
TrayTip, ClipCursor, Draw the rectangle you wanna`ntrap the mouse into
LetUserSelectRect(x1, y1, x2, y2)
TrayTip
}
else
return
ClipCursor(True, x1, y1, x2, y2)
using := True
Hotkey, ^Esc, Free_mouse, on
; Menu, Tray, Icon, % Icon_%context%
}
; Lexikos', http://www.autohotkey.com/forum/topic49784.html
LetUserSelectRect(ByRef X1, ByRef Y1, ByRef X2, ByRef Y2)
{
static r := 1
; Create the "selection rectangle" GUIs (one for each edge).
Loop 4 {
Gui, %A_Index%: -Caption +ToolWindow +AlwaysOnTop
Gui, %A_Index%: Color, Red
}
; Disable LButton.
Hotkey, *LButton, lusr_return, On
; Wait for user to press LButton.
KeyWait, LButton, D
; Get initial coordinates.
MouseGetPos, xorigin, yorigin
; Set timer for updating the selection rectangle.
SetTimer, lusr_update, 10
; Wait for user to release LButton.
KeyWait, LButton
; Re-enable LButton.
Hotkey, *LButton, Off
; Disable timer.
SetTimer, lusr_update, Off
; Destroy "selection rectangle" GUIs.
Loop 4
Gui, %A_Index%: Destroy
return
lusr_update:
MouseGetPos, x, y
if (x = xlast && y = ylast)
; Mouse hasn't moved so there's nothing to do.
return
if (x < xorigin)
x1 := x, x2 := xorigin
else x2 := x, x1 := xorigin
if (y < yorigin)
y1 := y, y2 := yorigin
else y2 := y, y1 := yorigin
; Update the "selection rectangle".
Gui, 1:Show, % "NA X" x1 " Y" y1 " W" x2-x1 " H" r
Gui, 2:Show, % "NA X" x1 " Y" y2-r " W" x2-x1 " H" r
Gui, 3:Show, % "NA X" x1 " Y" y1 " W" r " H" y2-y1
Gui, 4:Show, % "NA X" x2-r " Y" y1 " W" r " H" y2-y1
lusr_return:
return
}
; SKAN's, http://www.autohotkey.com/forum/post-141037.html#141037
ClipCursor(Confine=True, x1=0 , y1=0, x2=1, y2=1)
{
curpos := [x1, y1, x2, y2]
VarSetCapacity(R,16,0), NumPut(x1,&R+0),NumPut(y1,&R+4),NumPut(x2,&R+8),NumPut(y2,&R+12)
Return Confine ? DllCall( "ClipCursor", UInt,&R ) : DllCall( "ClipCursor" )
}
; https://autohotkey.com/board/topic/66726-method-to-detect-active-window-change/
WinActiveChange(wParam, hwnd) {
if (wParam = 32772 && using = True) {
ClipCursor(True, curpos*)
}
}
Return
; Windows 7 64 bit compitability
ShellMessage( wParam,lParam )
{
WinGetTitle, title, ahk_id %lParam%
If (wParam = 4 && using = True) { ;HSHELL_WINDOWACTIVATED
ClipCursor(True, curpos*)
}
}
Return
;---
KillTrayTip:
TrayTip
return