Jump to content


Restrict Mouse Movement - Circle round middle of screen

  • Please log in to reply
8 replies to this topic

#1 shivani



  • Normal Members
  • 2 posts

Posted 01 September 2012 - 03:00 PM

How to restrict/limit the mouse movement to a circle area around the middle of the screen?
This will be very usefull <snip>.

I would be VERY grateful for an answer! :bye:

Edited by Melba23, 01 September 2012 - 03:54 PM.
Edited text

#2 FireFox


    It slips through our fingers, like a fist full of sand.

  • MVPs
  • 5,393 posts

Posted 01 September 2012 - 03:31 PM

Take a look at the function _MouseTrap

Br, FireFox.

[color=rgb(105,105,105);]OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.[/color]

[color=rgb(105,105,105);]Hardware : Intel® Core™ i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.[/color]

[color=rgb(0,128,0);]My UDFs :[/color] Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

[color=rgb(0,128,0);]My Projects :[/color] YouTube Multi-downloader[color=#b22222;] [/color]| FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | [color=rgb(105,105,105);]Chrome theme maker[/color]

[color=rgb(0,128,0);]My Examples :[/color] Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

[color=rgb(0,128,0);]My Snippets :[/color] Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

[color=rgb(128,128,128);]Updated 07 November, 2013 - [/color][color=rgb(178,34,34);]If you find dead links please send me a PM, do not post in the topics ![/color]

#3 shivani



  • Normal Members
  • 2 posts

Posted 01 September 2012 - 03:46 PM

Thank you for the fast answer! I understand how this code work, but I dont understand how to trap it in a circle. Is it possible?

Plain Text         
#include <GUIConstantsEx.au3> #include <Misc.au3> _Main() Func _Main() Local $GUI, $coords[4] $GUI = GUICreate("Mouse Trap Example", 392, 323) GUISetState() While 1 $coords = WinGetPos($GUI) _MouseTrap($coords[0], $coords[1], $coords[0] + $coords[2], $coords[1] + $coords[3]) Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case Else ;;; EndSwitch WEnd _MouseTrap() Exit EndFunc   ;==>_Main

#4 Melba23


    I'm old - what's your excuse?

  • Moderators
  • 23,002 posts

Posted 01 September 2012 - 03:57 PM


I have edited your first post. The question is interesting in itself (which is why I am leaving the thread open), but you did not need to specify the usage to which you want to put it - that was not a good idea. :naughty:

Please read the Forum Rules before you post again - you do not get the same treatment if you do it a second time. ;)

My UDFs:

#5 wyzzard



  • Active Members
  • 30 posts

Posted 01 September 2012 - 04:36 PM

Haven't had time to work out the math but what you could do is use mousetrap to define the outside box of a circle. Anything that is outside the circle you want but inside the box could be handled by saving the "old" mouse coords and capturing the "new" ones. Compare the new ones to the result of the equation for a circle and if they are outside the circle then move the mouse back to the "old" coords.

Equation for a circle with any center point is: (x-h)2 + (y-k)2 = r2

x is the X coord of the mouse
y is the Y coord of the mouse
h is the X coord of circle center
k is the Y coord of circle center
r is the radius of a circle

You may need to rearrange the equation to make it easier to use to test against.

So basically plug in the X,Y coords of the mouse position and if the calculated "r" is less than the radius of the circle you want to restrict to then use the new coords, otherwise move mouse back to the old coords.

One problem I could see the mouse might be a little jumpy depending on how fast the user is moving it outside of the circle although the mousetrap will help limit it some.

#6 wyzzard



  • Active Members
  • 30 posts

Posted 01 September 2012 - 08:14 PM

Here's some quick code I came up with that works but does have some limitations.

You can hit the {ESC} to exit the script and reset the _MouseTrap to normal

#include <Misc.au3> HotKeySet("{ESC}", "Terminate") Local $XCenter = Int(@DesktopWidth/2) Local $YCenter = Int(@DesktopHeight/2) Local $OldMouse Local $NewMouse If $XCenter < $YCenter Then      Local $Radius = Int($XCenter/2) Else      Local $Radius = Int($YCenter/2) EndIf _MouseTrap(($XCenter-$Radius), ($YCenter - $Radius), ($XCenter + $Radius), ($YCenter + $Radius)) $OldMouse = MouseGetPos() While 1 $NewMouse = MouseGetPos() If Int(Sqrt((($NewMouse [0] - $XCenter)^2)+(($NewMouse [1] - $YCenter)^2))) > $Radius Then MouseMove($OldMouse [0], $OldMouse [1], 1) Else $OldMouse = $NewMouse EndIf WEnd Func Terminate() _MouseTrap() Exit 0 EndFunc ;==>Terminate

Main thing is that if you have a lot going on in the While/Wend loop it does get jumpy as the mouse can move outside of the circle before it gets a chance to read the new position and fix it.

Here's a picture I made in paint with the program running. You can see where even though I only had mouse position checking in my loop, it would jump outside the circle long enough for it to paint if I made a fast sharp movement outside before it corrected it and moved it back. If you move the mouse at a moderate speed though it does a pretty good job of keeping it inside with out the jerkiness.

I'm sure someone else can come up with something that works a little better.

Not sure but if you look at the _MouseTrap function code in the #include you can see where they use DLL's to limit mouse position so it may be possible to mod that to fit your needs instead.

Hope this helps

Attached Thumbnails

  • MouseTrapCircle.jpg

Edited by wyzzard, 01 September 2012 - 08:23 PM.

#7 kylomas



  • MVPs
  • 3,582 posts

Posted 01 September 2012 - 11:56 PM


This i very specific about the dll call parameter being a rectangle. Good thought, though!


[font="arial, helvetica, sans-serif;"]Forum Rules[/font] Procedure for posting code

#8 martin



  • MVPs
  • 7,331 posts

Posted 02 September 2012 - 03:40 PM

You need to use a mouse hook and then you won't get any movement outside of the circle.
here is a quick mod I made to a mousehook example just to show you.
#region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker #endregion ;**** Directives created by AutoIt3Wrapper_GUI **** ;~~ Mouse Hook ~~ ;For more info, Visit: <a href='http://msdn.microsoft.com/en-us/library/ms644986(VS.85' class='bbc_url' title='External link' rel='nofollow external'>http://msdn.microsoft.com/en-us/library/ms644986(VS.85</a>).aspx ;Include GUI Consts #include <GUIConstants.au3> ;for $GUI_EVENT_CLOSE #include <WinAPI.au3> ;for HIWORD #region bits for the circle trapping HotKeySet("{ESC}", "Terminate") Local $XCenter = Int(@DesktopWidth / 2) Local $YCenter = Int(@DesktopHeight / 2) If $XCenter < $YCenter Then     Local $Radius = Int($XCenter / 2) Else     Local $Radius = Int($YCenter / 2) EndIf MouseMove($XCenter, $YCenter) ;start with the cursor inside the circle or it will never get there $RadSq = $Radius * $Radius ;so we can calculate a bit faster and not do sq roots every time #endregion bits for the circle trapping ;These constants found in the helpfile under Windows Message Codes Global Const $WM_MOUSEMOVE = 0x0200 ;mouse move Global Const $WM_MOUSEWHEEL = 0x020A ;wheel up/down Global Const $WM_LBUTTONDBLCLK = 0x0203 ;left button Global Const $WM_LBUTTONDOWN = 0x0201 Global Const $WM_LBUTTONUP = 0x0202 Global Const $WM_RBUTTONDBLCLK = 0x0206 ;right button Global Const $WM_RBUTTONDOWN = 0x0204 Global Const $WM_RBUTTONUP = 0x0205 Global Const $WM_MBUTTONDBLCLK = 0x0209 ;wheel clicks Global Const $WM_MBUTTONDOWN = 0x0207 Global Const $WM_MBUTTONUP = 0x0208 ;Consts/structs from msdn Global Const $MSLLHOOKSTRUCT = $tagPOINT & ";dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo" ;~ Global Const $WH_MOUSE_LL = 14          ;already declared ;~ Global Const $tagPOINT = "int X;int Y"   ;already declared ;Create GUI $GUI = GUICreate("Mouse Hook", 178, 158, @DesktopWidth - 178, 0) ;Top-Left corner $_Event = GUICtrlCreateLabel("Event: ", 8, 8, 158, 17) $_XYpos = GUICtrlCreateLabel("X=     Y=", 8, 32, 157, 17) $_MData = GUICtrlCreateLabel("Mouse Data: ", 8, 56, 165, 17) $_Flags = GUICtrlCreateLabel("Flags: ", 8, 80, 168, 17) $_Timestamp = GUICtrlCreateLabel("Timestamp: ", 8, 104, 162, 17) $_Extra = GUICtrlCreateLabel("Extra Info: ", 8, 128, 167, 17) GUISetState() WinSetOnTop($GUI, "", 1) ;make GUI stay on top of other windows ;Register callback $hKey_Proc = DllCallbackRegister("_Mouse_Proc", "int", "int;ptr;ptr") $hM_Module = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0) $hM_Hook = DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", $WH_MOUSE_LL, "ptr", DllCallbackGetPtr($hKey_Proc), "hwnd", $hM_Module[0], "dword", 0) While 1     If $GUI_EVENT_CLOSE = GUIGetMsg() Then Exit ;idle until exit is pressed WEnd Func _Mouse_Proc($nCode, $wParam, $lParam) ;function called for mouse events..     ;define local vars     Local $info, $ptx, $pty, $mouseData, $flags, $time, $dwExtraInfo, $Res     Local $xevent = "Unknown", $xmouseData = ""     If $nCode < 0 Then ;recommended, see <a href='http://msdn.microsoft.com/en-us/library/ms644986(VS.85' class='bbc_url' title='External link' rel='nofollow external'>http://msdn.microsoft.com/en-us/library/ms644986(VS.85</a>).aspx         $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _                 "int", $nCode, "ptr", $wParam, "ptr", $lParam) ;recommended         Return $ret[0]     EndIf     $info = DllStructCreate($MSLLHOOKSTRUCT, $lParam) ;used to get all data in the struct ($lParam is the ptr)     ; DllStructGetData($info, 1) ;see notes below..     $ptx = DllStructGetData($info, 1)     $pty = DllStructGetData($info, 2)     DllStructSetData($info, 2, 100)     $mouseData = DllStructGetData($info, 3)     $flags = DllStructGetData($info, 4)     $time = DllStructGetData($info, 5)     $dwExtraInfo = DllStructGetData($info, 6)     ; $ptx = Mouse x position     ; $pty = Mouse y position     ; $mouseData = can specify click states, and wheel directions     ; $flags = Specifies the event-injected flag     ; $time = Specifies the time stamp for this message     ; $dwExtraInfo = Specifies extra information associated with the message.     ;Find which event happened     ConsoleWrite($ptx & ', ' & $pty & @LF)     $Res = 0     Select         Case $wParam = $WM_MOUSEMOVE             $xevent = "Mouse Move"             If ($ptx - $XCenter) ^ 2 + ($pty - $YCenter) ^ 2 > $RadSq Then                 $Res = 1             EndIf         Case $wParam = $WM_MOUSEWHEEL             $xevent = "Mouse Wheel"             If _WinAPI_HiWord($mouseData) > 0 Then                 $xmouseData = "Wheel Forward"             Else                 $xmouseData = "Wheel Backward"             EndIf         Case $wParam = $WM_LBUTTONDBLCLK;double clicks don't seem to work so we would need a timer to decide. There must be a time set in spi or somewhere which windows uses.             $xevent = "Double Left Click"             ConsoleWrite("doubled" & @CRLF)         Case $wParam = $WM_LBUTTONDOWN             $xevent = "Left Down"         Case $wParam = $WM_LBUTTONUP             $xevent = "Left Up"         Case $wParam = $WM_RBUTTONDBLCLK             $xevent = "Double Right Click"         Case $wParam = $WM_RBUTTONDOWN             $xevent = "Right Down"         Case $wParam = $WM_RBUTTONUP             $xevent = "Right Up"         Case $wParam = $WM_MBUTTONDBLCLK             $xevent = "Double Wheel Click"         Case $wParam = $WM_MBUTTONDOWN             $xevent = "Wheel Down"         Case $wParam = $WM_MBUTTONUP             $xevent = "Wheel Up"     EndSelect     ; Set GUI control data..     GUICtrlSetData($_Event, "Event: " & $xevent)     GUICtrlSetData($_XYpos, "X=" & $ptx & "  Y=" & $pty)     If $xmouseData <> "" Then         GUICtrlSetData($_MData, "Mouse Data: " & $xmouseData)     Else         GUICtrlSetData($_MData, "Mouse Data: " & $mouseData)     EndIf     GUICtrlSetData($_Flags, "Flags: " & $flags)     GUICtrlSetData($_Timestamp, "Timestamp: " & $time)     GUICtrlSetData($_Extra, "Extra Info: " & $dwExtraInfo)     ;This is recommended instead of Return 0     If $Res = 1 Then         Return 1     Else         $ret = DllCall("user32.dll", "long", "CallNextHookEx", "hwnd", $hM_Hook[0], _                 "int", $nCode, "ptr", $wParam, "ptr", $lParam)         Return $ret[0]     EndIf EndFunc   ;==>_Mouse_Proc Func terminate()     Exit EndFunc   ;==>terminate Func OnAutoItExit()     DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hM_Hook[0])     $hM_Hook[0] = 0     DllCallbackFree($hKey_Proc)     $hKey_Proc = 0 EndFunc   ;==>OnAutoItExit

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

#9 wyzzard



  • Active Members
  • 30 posts

Posted 02 September 2012 - 06:58 PM

Tested martin's version and it definitely does a better job keeping it inside the circle. Not sure if it was my mouse or not but it seemed a little less responsive sometimes (in particular larger moves towards the edge of the circle) but that could be my perception of things.

Attached a picture of it in action though

Attached Thumbnails

  • MouseTrap-Martin.jpg

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users