Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

MouseTrap2Mon - trap mouse to chosen monitor


  • Please log in to reply
17 replies to this topic
Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008
Posted Image

COMPATIBILITY: AutoHotkey 1.0.48.05 (AHK Basic)

Following a request in the Ask for help section, I have developed the following script. When found in a multi-monitor environment, it performs the simple task of confining the mouse cursor within the boundaries of a single monitor, chosen by the user.

EDIT (following SoggyDog's report):
The CTRL key allows the mouse cursor to pass through to the other monitor and stay there until it returns to the locked monitor. This way it's easy to operate on other windows or change script's own settings.
/EDIT

The script can be launched in trayless mode (no tray icon) by specifying a commandline parameter when launching it. While in this mode, the options dialog can be brought up through the Ctrl+Alt+F9 hotkey, configurable by editing the script.

Currently, the images used would have to reside in the script's folder. At a later time, this may change. All icons as well as the script can be found in the archive on the download page.

Settings are automatically saved to an ini file, in the script's folder, on exit. Make sure you have writing permission to that folder, in Vista and later OS.

Final considerations: the script has only been tested in the configuration [primary] [secondary]. I'm quite reluctant to change display configuration to test the reverse (screws up desktop icons and custom toolbars), so if you can, please do and report back if there's problems.

Enjoy!

Download page for MouseTrap2Mon:
MouseTrap2Mon download page

; MouseTrap2Mon by Drugwash
; confines the mouse cursor to chosen monitor only
; Ctrl+Alt+F9 shows options dialog in NoTray mode

#persistent
SetBatchLines, -1
CoordMode, Mouse, Screen
;*****************************************
appname = MouseTrap2Mon		; application name
version = 1.2					; version number
release = July 13, 2009			; release date
type = public					; release type (internal / public)
iconlocal = MT2M.ico			; external icon for uncompiled script
debug = 0					; debug switch (1 = active)
; *****************************************
mylink = [email protected]
ahklink = http://www.autohotkey.com
ffflink = http://www.famfamfam.com
abtwin = About %appname%
inifile := A_ScriptDir "\" appname ".ini"
;************* Custom tray menu *************
notray = %1%
if ! notray
	Menu, Tray, Icon, %iconlocal%
Menu, Tray, NoStandard
Menu, Tray, Add, Settings, options
Menu, Tray, Default, Settings
Menu, Tray, Add, About, about
Menu, Tray, Add
Menu, Tray, Add, Exit, exit
if debug
	Menu, Tray, Add, Reload, Reload
; *****************************************
SysGet, a, 80 ; Check for multi-display environment
if a < 2
	{
	m=1
	MsgBox, 0x40040, %appname% information,
(
This application is designed to work
only in a multi-display environment.
We detected a single display here.

The application will now exit.
)
	ExitApp
	}
pass=0 ; pass-through switch
t=0 ; Enable/Disable toggle switch
; SysGet, p, MonitorPrimary ; not used (yet)
Gui, Add, Picture, xm ym+16 vm1 gms, M1.ico
Gui, Add, Picture, x+10 yp vm2 gms, M2.ico
Gui, Add, Button,xm y+5 w80, Disable
Gui, Add, Button,x+10 yp w80, Exit
Gui, Add, Text, xm ym h14, Click the monitor to trap the mouse in:
if FileExist(inifile)
	{
	IniRead, m, %inifile%, Settings, Monitor, 1
	IniRead, s, %inifile%, Settings, Sub, t1
	gosub msi
	}
else
	Gui, Show,, %appname%
hCurs := DllCall("LoadCursor", "UInt", NULL, "Int", 32649, "UInt") ;IDC_HAND
OnMessage(0x200, "WM_MOUSEMOVE")
OnExit, exit
return

; case 1: primary 1, selected 1 -> m=1, side=rRight, op=>
; case 2: primary 1, selected 2 -> m=2, side=rLeft, op=<
; case 3: primary 2, selected 1 -> m=1, side=rRight, op=>
; case 4: primary 2, selected 2 -> m=2, side=rLeft, op=<
ms:
m := SubStr(A_GuiControl, 2)
msi:
if s
	SetTimer, %s%, Off
SysGet, r, Monitor, %m%
side := ( m = 1) ? rRight : rLeft
s := ( m = 1) ? "t1" : "t2"
off := (m = 1) ? -5 : 5
if t
	gosub ButtonDisable
else
	SetTimer, %s%, 10
GuiClose:
GuiEscape:
Gui, Hide
return

t1:
MouseGetPos, x, y
if (x > side && !pass)
	gosub chk
else if (x < side && pass)
	pass = 0
return

t2:
MouseGetPos, x, y
if (x < side && !pass)
	gosub chk
else if (x > side && pass)
	pass = 0
return

chk:
if GetKeyState("Ctrl", "P")
	pass = 1
else
	DllCall("SetCursorPos", Int, side+off, Int, y)
return

^!F9::
options:
Gui, Show,, %appname%
return

ButtonDisable:
t := !t
GuiControl,, Button1, % t ? "Enable" : "Disable"
SetTimer, %s%, % t ? "Off" : "On"
Gui, Hide
return

Reload:
Reload
exit:
ButtonExit:
IniWrite, %m%, %inifile%, Settings, Monitor
IniWrite, %s%, %inifile%, Settings, Sub
OnMessage(0x200,"")
DllCall("DestroyCursor", "Uint", hCurs)
ExitApp

;************** ABOUT box *****************
about:
Gui 1:+Disabled
Gui, 1:Hide
Gui, 2:+Owner1 -MinimizeBox
if ! A_IsCompiled
	Gui, 2:Add, Picture, x69 y10 w32 h-1, %iconlocal%
else
	Gui, 2:Add, Picture, x69 y10 w32 h-1 Icon1, %A_ScriptName%
Gui, 2:Font, Bold
Gui, 2:Add, Text, x5 y+10 w160 Center, %appname% v%version%
Gui, 2:Font
Gui, 2:Add, Text, xp y+2 wp Center, by Drugwash
Gui, 2:Add, Text, xp y+2 wp Center gmail0 cBlue, %mylink%
Gui, 2:Add, Text, xp y+10 wp Center, Released %release%
Gui, 2:Add, Text, xp y+2 wp Center, (%type% version)
Gui, 2:Add, Text, xp y+10 wp Center, This product is open-source,
Gui, 2:Add, Text, xp y+2 wp Center, developed in AutoHotkey
Gui, 2:Font,CBlue Underline
Gui, 2:Add, Text, xp y+2 wp Center glink0, %ahklink%
Gui, 2:Font
Gui, 2:Add, Text, xp y+5 wp Center, Icon from the Silk package at
Gui, 2:Font,CBlue Underline
Gui, 2:Add, Text, xp y+2 wp Center glink1, %ffflink%
Gui, 2:Font
Gui, 2:Add, Button, xp+40 y+20 w80 gdismiss Default, &OK
Gui, 2:Show,, %abtwin%
return

dismiss:
Gui, 1:-Disabled
Gui, 2:Destroy
;Gui, 1:Show
return

mail0:
mail = mailto:%mylink%
Run, %mail%, UseErrorLevel
return

link0:
Run, %ahklink%,, UseErrorLevel
return

link1:
Run, %ffflink%,, UseErrorLevel
return

WM_MOUSEMOVE(wParam, lParam)
{
Global hCurs, abtwin, appname, m, side, off, pass, t
WinGetTitle, wind
MouseGetPos, x, y, winid, ctrl
if wind in %abtwin%
	if ctrl in Static4,Static9,Static11
		DllCall("SetCursor", "UInt", hCurs)
if wind in %appname%
	if ctrl in Static1,Static2
		DllCall("SetCursor", "UInt", hCurs)
return
}


SoLong&Thx4AllTheFish
  • Members
  • 4999 posts
  • Last active:
  • Joined: 27 May 2007
For those interested, see also ConfineMouse by Skrommel
<!-- m -->http://www.donationc... ... nfineMouse<!-- m -->

Non AHK, but useful at times for games for example:
<!-- m -->http://www.dr-hoiby.com/MouseJail/<!-- m -->
it locks the mouse for a specific program.

@Drugwash: I hope you don't mind, your script is fine but the
more solutions to a problem the better in my opinion :lol:

Z_Gecko
  • Guests
  • Last active:
  • Joined: --
Did you know there is a build-in windows function to limit the mouse to a certain area? You could use ClipCursor.
see this: http://www.autohotke...037.html#141037

i guess using ClipCursor will reduce the resource usage of your script.

SoggyDog
  • Members
  • 803 posts
  • Last active: Mar 04 2013 06:27 AM
  • Joined: 02 May 2006
It might be nice to have the Options dialog open on the monitor in which the mouse has been trapped;
Though you can keyboard your way between Disable and Exit, you can't change the selected monitor.

Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008
SoggyDog:
What I forgot to mention is that the Ctrl key allows the mouse to pass through to the other monitor and stay there until it goes back to the locked monitor. There is no need to Tab through options or whatnot.
(I edited first post adding this information, thanks)

Z_Gecko:
I haven't yet checked the ClipCursor API but it's doubtful it can do the above. Will have a look at it soon, thanks for the heads up.

HugoV:
Compare their capabilities and choose based on personal preferences; I only did what was requested in the thread mentioned in first post. Alternatives are always welcome, for various tastes. Personally I don't feel the need to confine the mouse but it's always a pleasure being able to help others.

Thank you all for your input and apologies for late reply - I've been away from home.

Z_Gecko
  • Guests
  • Last active:
  • Joined: --

I haven't yet checked the ClipCursor API but it's doubtful it can do the above.

let me assure you, it can.
just test this little example by SKAN:
^F2:: ; Hotkey will toggle status
Confine := !Confine
ClipCursor( Confine, 0, A_ScreenHeight/2, A_ScreenWidth, A_ScreenHeight )
Return


ClipCursor( Confine=True, x1=0 , y1=0, x2=1, y2=1 ) {
 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" )
}


Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008
I've read part of that thread, when there were reports of malfunctioning after focus switching. Will go back and read it completely but if additional efforts are required to keep it working then I'd better leave it as is since it does the job.

MikeJ
  • Guests
  • Last active:
  • Joined: --
Nice job Drugwash! Everything works as expected here, and far more than I ever expected when I started the other thread. I`m sure many more will find it useful, as dual monitors become more popular.

Dual Monitor Warning: Habit forming! Especially since this little annoyance has been tamed.

Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008
Thank you, Mike! I'm glad you're happy with the script. :wink:

Dual-monitor is indeed catchy; my current video card (or mobo?) started failing on me and I'm in panic knowing the other card offered to me by a friend has the secondary (digital) output defective and will not be able to continue using dual-video. :cry: :cry: :cry:

ballyhairs
  • Members
  • 112 posts
  • Last active: Sep 14 2009 10:02 PM
  • Joined: 02 Feb 2009
I have been through almost all the threads concerning blocking the mouse from certain area, none work effectively, the one posted above by Z_Gecko seem to work sometimes and sometimes not, but once there a video running on the TV out in my case then it doesn't work ar all, it will even block the upper half of my primary monitor. All I need is to block the mouse from going to TV-Out completely, if someone got something that works please let know. :)

Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008
Doesn't my script work? :? Admittedly, I haven't tested it with TV-Out (don't have a TV set at this location) but works fine with 2 analog monitors on a MSI GeForce 4 Ti4200VTD8X 128MB vRAM under Win98SE.

I won't be around anytime soon but posting your hardware/software details (videocard brand/model, video driver version, operating system version, etc) might help others offer some advices.

ballyhairs
  • Members
  • 112 posts
  • Last active: Sep 14 2009 10:02 PM
  • Joined: 02 Feb 2009
Chip Type:---------------------------NVIDIA GeForce 8500 GT

DAC Type:----------------------------Integrated RAMDAC

Adapter String:----------------------NVIDIA GeForce 8500 GT

Bios Information:--------------------Version 60.86.39.0.0

Total Available Graphic Memory:------1023 MB

Dedicated Video Memory:--------------256 MB

System Video Memory:-----------------0MB

Shared System Memory:----------------767 MB



Vista


Ecto
  • Guests
  • Last active:
  • Joined: --
I keep having the issue that the mouse crosses to the screen and is then moved back. Is there any way to do it that doesn't allow the mouse on to the second screen at all? Basically, I'm trying to use screen-edge scrolling in a game, but the game only registers it as long as the mouse is on the monitor, not when it's crossed across to the other.

  • Guests
  • Last active:
  • Joined: --
look at reply 3 - Z_Gecko's reply
it provides a much solid way to limit mouse moving area

Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008
Indeed the behavior is not perfect, the cursor does step into the other screen and is then brought back on a timer basis (10 ms). The time interval could of course be lowered to 1 ms but I'm afraid it would create too much overhead.

The solution mentioned by Z_Gecko didn't work correctly for me either, in that it kept getting disabled under certain conditions. Dunno of a better solution right now so any new ideas are welcome.