Jump to content
Sign in to follow this  
romulous

Restricting Mouse Movement

Recommended Posts

Hi everyone,

I've recently had a second monitor set-up on my PC, and it's taking me a little getting used to. What I find is that I constantly move my mouse over to the right hand side of my first/primary monitor (which is on the left hand side of my desk, the second monitor is on the right hand side) to use a program's scroll bar, and I move too far, and the cursor disappears onto the second monitor. I then have to drag my mouse back to the left to bring it back onto the first monitor so I can click the scroll bar. I can't find an already built utility to restrict mouse movement to the first monitor, so I thought I would see if I could make one in AutoIt. Basically what I wanted the utility to do is:

1. To always run in the background while-ever I was logged onto Windows (I would drag a copy of the exe into the Windows start-up folder).

2. To - as long as I don't press a predefined hot key like Alt - restrict my mouse movement to a maximum width that is equal to the current resolution I have my primary monitor set to. In this case, I would be able to move my mouse to a maximum 'x' co-ordinate of 1680 pixels (both monitors are set to 1680x1050 resolution). Once I move my mouse to the x position of 1680, the cursor would stop and would not be able to move any further to the right. The 'y' position is not relevant in my case, because I have the monitors set-up horizontally, not vertically.

3. If I press a hot key, then the program would temporarily deactivate and allow me to move my mouse onto the second monitor (i.e. past the 1680x1050 boundary) - and then when I release the hot key, the program restricts the mouse movement again.

Can anyone tell me definitively if this can actually be done in AutoIt?

Thanks,

CM

Share this post


Link to post
Share on other sites

I'd say it can be done, but I'm not sure what way would be the best in terms of taking up the least processing power. Although I'd imagine processing power isn't a big problem for you if you have two ginormous monitors :)

Something I would do would probably be...

While 1
    
    $mousepos=mousegetpos() ; checks where the mouse is
    If $mousepos[0] >= 1680 Then ; if its too far to the right then
        MouseMove(1680,$mousepos[1],0) ; instantly moves the mouse back to 1680, leaving it in the same vertical position as it was before
    EndIf
    
WEnd

I don't know much about dual monitors, so I hope that works. Maybe someone can make it better.

edit: Changed a tiny parameter ^_^

Ah shit, I totally forgot about the ALT keypress.

Edited by Nevin

Share this post


Link to post
Share on other sites

what a funny request :) I have one on each side and mouse set to extreme and love it. my scroll bar is tiny since I have my 15in middle laptop monitor set at 1400 by 1050 but I understand your delima

take the following code and modify it to use mousegetpos and mousemove with an if statement -should do the trick (drop the gui and label stuff)

#include <GUIConstants.au3>
Opt("GUIOnEventMode", 1)
HotKeySet("{ESC}", "_Toggle")
;GUICreate ( "title" [, width [, height [, left [, top [, style [, exStyle [, parent]]]]]]] )
$GUI = GUICreate("", 5000, 5000, -1600, -20, $WS_POPUPWINDOW, $WS_EX_TOPMOST)

$Black = GUICtrlCreateLabel("", 0, 0, 5000, 5000)
GUICtrlSetBkColor(-1, 0x000000)
GUICtrlSetState(-1, $GUI_DISABLE)
$Show = True

; ============================================================================
; Main Loop
; ============================================================================

While 1
    Sleep(10)
WEnd

; ============================================================================
; Functions
; ============================================================================
Func _Toggle()
    If $Show = True Then
        Global $Show = False
        MouseMove(Default, 1600, 0)
        GUISetState(@SW_SHOW, $GUI)
    Else
        Global $Show = True
        GUISetState(@SW_Hide, $GUI)
    EndIf
EndFunc   ;==>_Toggle

Share this post


Link to post
Share on other sites

Won't that only call the function once when you press alt? Anyhow, I'm gonna try and fix mine ^_^

um no :) you drop the gui stuff as stated and use your code inside the while statement only if show = true

ofcourse you should rename show to $restrict or something :)

-I just posted the toggle and how to derive the mouse position.

good post -it appears you posted the other half -yes it is correct

Edited by Hatcheda

Share this post


Link to post
Share on other sites

Alright, here we go. ESC will toggle the lock on and off. It's initially on.

#include <Misc.au3>
HotKeySet("{ESC}", "_Toggle") ;ESC key is the hotkey

while 1
    Sleep(10) ;small delay to save some CPU time
    $mousepos=mousegetpos() ; checks where the mouse is
    If $mousepos[0] >= 1680 Then ; if its too far to the right then
        MouseMove(1680,$mousepos[1],0) ; instantly moves the mouse back to 1680, leaving it in the same vertical position as it was before
    EndIf
   
WEnd

Func _Toggle() ;Waits until ESC is pressed again to resume
    While 1
        Sleep(10)
        If _IsPressed(1B) Then
            ExitLoop
        EndIf   
    WEnd
    Return
EndFunc

The hotkey is ESC because ALT cannot be used with hotkeyset. If you really want ALT badly enough, you could just use _IsPressed for both instances.

Like I said, I am probably not writing this the best way.

um no ^_^ you drop the gui stuff as stated and use your code inside the while statement only if show = true

ofcourse you should rename show to $restrict or something :)

-I just posted the toggle and how to derive the mouse position.

good post -it appears you posted the other half -yes it is correct

Ah, okay. I never use HotKeySet, so your code helped me figure that out without looking much up :) Edited by Nevin

Share this post


Link to post
Share on other sites

well I was thinking more like this -also I lowered the mouse right to test it on a single monitor -good mouse formula Nevin :)

HotKeySet("{ESC}", "_Toggle")
$Restrict = True

; ============================================================================
; Main Loop
; ============================================================================

While 1
    Sleep(10)
    If $Restrict = True Then
    $mousepos=mousegetpos()
        If $mousepos[0] >= 1080 Then MouseMove(1080,$mousepos[1],0)
    EndIf
WEnd

; ============================================================================
; Functions
; ============================================================================
Func _Toggle()
    If $Restrict = True Then
        Global $Restrict= False
    Else
        Global $Restrict = True
    EndIf
EndFunc   ;==>_Toggle
Edited by Hatcheda

Share this post


Link to post
Share on other sites

Why did you put GUIConstants at top? There isn't a GUI.

because it was derived from the above post and simply omitted when removing the rest. -however, since it is not being used it does nothing to slow the script.

Share this post


Link to post
Share on other sites

actually when you compile it is removed if not used if you use obfucscate and select to do so, however, who said anything about compiling it? again, why do you bother? are you actually chasing me around to throw in your little tidbits? As I said, it was simply omitted when removing the rest.

Share this post


Link to post
Share on other sites

Then why are you still here 6 minutes later?

And besides, you don't need to mke a huge seen because GUIconstants is in there.

Edited by JustinReno

Share this post


Link to post
Share on other sites

Hi everyone,

Wow, thanks for all the responses. There are a few different ways for me to experiment with :) I wasn't set on having the hot key as Alt, it was just the first key that popped into my mind when I was typing the original request. And processing power isn't an issue thankfully (plenty of CPU cycles to spare), so hopefully this should get me sorted until I can get used to having that second monitor there (I need to adjust my mouse moving technique - with one monitor, I tended to quickly 'throw' my mouse to the right hand side of the screen because I knew the screen edge would stop the cursor when it reached the scroll bar, but when I do that with two monitors the cursor slips onto that second monitor).

Regards,

CM

Share this post


Link to post
Share on other sites

#include <Misc.au3>
While 1
_MouseTrap(0,0, 1280,1024)
WEnd
Hi Paulie,

Thanks - I modified that slightly. This is my modified version:

#include <Misc.au3>

$width = @DesktopWidth; Sets the resolution (width) to a variable - used in the _MouseTrap loop so you don't have to hardcode the desktop resolution
$height = @DesktopHeight; Sets the resolution (height) to a variable - used in the _MouseTrap loop so you don't have to hardcode the desktop resolution

While 1
_MouseTrap ( 0, 0, $width, $height ); Stops the mouse from moving outside the current resolution (i.e. the first monitor)
Sleep ( 2000); Sleeps for 2 seconds to avoid 100% CPU usage. Note that if it wasn't for the hotkey part of this script, what delay you used here would not matter, as the _MouseTrap would still be acting whether the loop was sleeping or not
WEnd

Using @DesktopWidth and @DesktopHeight stops me from having to hardcode the desktop resolution into the script (if I did so, it would break the script should I change my desktop resolution). The Sleep line is in there so CPU usage doesn't shoot up to 100% (a real downside to the While 1 part of a script in AutoIt, everytime you use While 1 you have to insert a Sleep line).

Now to just add the hotkey part. Then I will have a bit of an experiment with the other solutions posted here, and see which one I think works the best :)

Regards,

CM

Share this post


Link to post
Share on other sites

Hi again everyone,

Got a minor (but puzzling) problem. I've actually used a bit of a mix of the couple of scripts posted here:

#include <Misc.au3>

HotKeySet ( "{ESC}", "Disable" ); ESC key is the hotkey to disable the script

$height = @DesktopHeight; Sets the resolution (height) to a variable - used in the _MouseTrap loop so you don't have to hardcode the desktop resolution
$restrict = True
$width = @DesktopWidth; Sets the resolution (width) to a variable - used in the _MouseTrap loop so you don't have to hardcode the desktop resolution

While 1
    Sleep ( 100 )
    If $restrict = True Then
        _MouseTrap ( 0, 0, $width, $height ); Stops the mouse from moving outside the current resolution (i.e. the first monitor)
    EndIf
WEnd

Func Disable()
    If $restrict = True Then
        Global $restrict = False
    Else
        Global $restrict = True
    EndIf
EndFunc

I did try the 'If _IsPressed' command for the hotkey part of the script, but I couldn't get it to work (it would disable, but not re-enable), so I went with the '$restrict' version. Now - here's what happens. I run the script, it restricts the mouse movements to the first monitor. Put a tick beside that one, that works fine. I then press Esc - but until I actually do something with my task bar (either minimise or un-minimise a program window, it doesn't seem to matter which program as long as it is a program window), the mouse is still restricted to the first monitor. Once I minimise or un-minimise a program window, the script disables and then allows me to move onto the second monitor. Put a half tick beside that one. Lastly, if I press Esc again, the mouse is once again restricted to the first monitor. Put a tick beside that one, that part works fine. So, can anyone tell me why I need to perform a taskbar action to persuade the Esc press to take effect? It's a strange one - it's almost as if Windows needs to be refreshed for the change to take effect, and doing something with your task bar is one way to refresh Windows.

CM

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...