[SOLVED]Confine mouse cursor to a circular shape?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
ChrisMiller
Posts: 9
Joined: 30 May 2016, 15:51

[SOLVED]Confine mouse cursor to a circular shape?

02 Jun 2016, 02:16

Good morning AHK friends,
I ran into a small problem and I’m not sure how I, or if it is even possible to solve this.
As the title suggests I want to confine my mouse cursor to a certain part of the desktop.
I do that with the help of this at the beginning of the script:

Code: Select all

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" )
}
So when I call my GUI I put this after the <Gui, Show> command:

Code: Select all

 WinGetPos, VarX, VarY, Width, Height, A
		VarX2 := VarX + Width - 15
		VarY2 := VarY + Height - 15
		ClipCursor( True, VarX, VarY, VarX2, VarY2)
This works perfectly fine! My problem is the shape. It obviously confines the mouse to a rectangle.
The GUI I want to confine the mouse in looks like this:
Image
So long story short, can I confine my mouse cursor to a circular shape?
Bit of a luxurious problem I know, but I cant let it go :)

Thanks in advance guys and have a nice day.
Last edited by ChrisMiller on 02 Jun 2016, 15:41, edited 1 time in total.
User avatar
waetherman
Posts: 112
Joined: 05 Feb 2016, 17:00

Re: Confine mouse cursor to a circular shape?

02 Jun 2016, 04:23

That would be my approach:

Code: Select all

smoothness := .8 ;should be between 0 and 1
radius := 135

RButton::
	CoordMode, Mouse, Screen
	MouseGetPos, x, y
	While ( 1 ) {
		GetKeyState, rmb, Rbutton,P
		if ( rmb = "U" ) {
			break
		}
		MouseGetPos, nx, ny
		dx := nx - x
		dy := ny - y
		dist := sqrt( (dx ** 2) + (dy ** 2) )
		
		if ( dist > radius ) {
			dist := radius / dist
			dx *= dist
			dy *= dist
			
			a := smoothness
			b := 1 - smoothness
			nx := a*nx + b*(x + dx)
			ny := a*ny + b*(y + dy)
			MouseMove, nx, ny, 0
		}
	}
	return

 ~#q::ExitApp
Image
User avatar
Nextron
Posts: 1391
Joined: 01 Oct 2013, 08:23
Location: Netherlands OS: Win10 AHK: Unicode x32

Re: Confine mouse cursor to a circular shape?

02 Jun 2016, 08:19

Applying waetherman' code to a hook makes sure the cursor never leaves the target area:

Code: Select all

RButton::
	CircleClip(135)
	KeyWait,RButton
	CircleClip()
Return


CircleClip(radius=0, x:="", y:=""){
	global CircleClipRadius, CircleClipX, CircleClipY
	static hHookMouse, _:={base:{__Delete: "CircleClip"}}
	If (radius>0)
		CircleClipRadius:=radius
		, CircleClipX:=x
		, CircleClipY:=y
		, hHookMouse := DllCall("SetWindowsHookEx", "int", 14, "Uint", RegisterCallback("CircleClip_WH_MOUSE_LL", "Fast"), "Uint", 0, "Uint", 0)
	Else If (!radius && hHookMouse){
		DllCall("UnhookWindowsHookEx", "Uint", hHookMouse)
		CircleClipX:=CircleClipY:=""
	}
}

CircleClip_WH_MOUSE_LL(nCode, wParam, lParam){
	global CircleClipRadius, CircleClipX, CircleClipY
	Critical

	if !nCode && (wParam = 0x200){ ; WM_MOUSEMOVE 
		nx := NumGet(lParam+0, 0, "Int") ; x-coord
		ny := NumGet(lParam+0, 4, "Int") ; y-coord

		If (CircleClipX="" || CircleClipY="")
			CircleClipX:=nx, CircleClipY:=ny
		  
		dx := nx - CircleClipX
		dy := ny - CircleClipY
		dist := sqrt( (dx ** 2) + (dy ** 2) )

		if ( dist > CircleClipRadius ) {
			dist := CircleClipRadius / dist
			dx *= dist
			dy *= dist
			
			nx := CircleClipX + dx
			ny := CircleClipY + dy
		}

		DllCall("SetCursorPos", "Int", nx, "Int", ny)
		Return 1
		
	}else Return DllCall("CallNextHookEx", "Uint", 0, "int", nCode, "Uint", wParam, "Uint", lParam) 
} 

 ~#q::ExitApp
Edit: Applied correction below.
Last edited by Nextron on 03 Jun 2016, 02:36, edited 1 time in total.
User avatar
waetherman
Posts: 112
Joined: 05 Feb 2016, 17:00

Re: Confine mouse cursor to a circular shape?

02 Jun 2016, 09:13

That's awesome!
EDIT: It works on my Windows 10, apparently it doesn't work elsewhere, so it's less awesome now.
EDIT: Apparently it was fixed, so still pretty awesome.
Last edited by waetherman on 02 Jun 2016, 12:03, edited 2 times in total.
Image
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: Confine mouse cursor to a circular shape?

02 Jun 2016, 09:40

@Nextron, your code doesn't work (on Windows 8.1, 64-bit AHK); SetWindowsHookEx returns null, consistently. Haven't tried it on Windows 7 yet. Much too little sleep to figure out why right now, apparently.
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
ChrisMiller
Posts: 9
Joined: 30 May 2016, 15:51

Re: Confine mouse cursor to a circular shape?

02 Jun 2016, 09:41

Thank you both for your answers guys! I really appreciate it.
Sadly I dont get it :D

As far as I see waetherman's script is included in yours, Nextron. But Nextron's script does nothing for me. I dont get an error message but it also doesnt confine the cursor.
What am I doing wrong?

EDIT: @Masonjar13 Thanks for confirming, didnt know SetWindowsHookEx is the issue. I'm on Win7x64 fyi.
User avatar
Nextron
Posts: 1391
Joined: 01 Oct 2013, 08:23
Location: Netherlands OS: Win10 AHK: Unicode x32

Re: Confine mouse cursor to a circular shape?

02 Jun 2016, 10:04

I've kept the example the same as waetherman' script, that when holding down the right mouse button, the cursor should be confined (and Win+q to quit). For me it works with Win7, AHK 32-bit unicode. For 64 bit it's probably getting a 64-bit pointer to the callback function whereas the code uses only 32bits of it?
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
Contact:

Re: Confine mouse cursor to a circular shape?

02 Jun 2016, 10:36

Replacing DllCall("GetModuleHandle", "Uint", 0) with 0 is enough to get it working on Windows 10 64-bit. Thanks for sharing, waetherman and Nextron.
ChrisMiller
Posts: 9
Joined: 30 May 2016, 15:51

Re: Confine mouse cursor to a circular shape?

02 Jun 2016, 15:40

Works perfectly on Windows 7 64bit aswell!

Big thanks to everyone!
ItsGooglesFault

Re: [SOLVED]Confine mouse cursor to a circular shape?

07 Apr 2018, 03:18

How do you make this code run forever until the win+r key is hit?

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: madensuyu1, peter_ahk and 344 guests