AutoHotKey sporadic mouse movement behavior in particular program with Click/MoveMouse - autohotkey

I made a quick ahk script that moved the mouse and found that the mouse wasn't getting moved to the desired location. I set up a loop that continually moved the cursor to the same position every couple of seconds, and the mouse would be moved to different, seemingly-random positions instead. I found that this was only the case with a specific program's window focused and if I had any other program focused the mouse moved as expected. I tried using Click/MouseMove, and they both exhibited this behavior. I also tried DllCall("SetCursorPosition"), but that wouldn't even move the mouse. Just to further clarify, all three of those worked fine when the problem program wasn't focused -- I only had issues when the problem program was focused.
Upon further inspection, this seemed to be due to the program's custom mouse sensitivity implementation. If I used MouseMove to move the cursor 1 pixel down relative to the current position, it'd move down ~50. If I increased the program's mouse sensitivity, it'd move down even further. I assume this is also why I was getting seemingly-random mouse positions with Click.
For now I've implemented a custom click function which unfocuses the program, moves the mouse, re-focuses the program, and then clicks, but the program doesn't like that. Sometimes it works, but sometimes the program will ignore mouse clicks from the position the mouse was when the window was focused, leading to the script not being able to do the things I want it to be able to do.
Is there a way for me to take into account this program's mouse sensitivity while using Click x,y/MouseMove? Or maybe an alternative method of moving the mouse that isn't affected by the program's mouse sensitivity. I've tried using all types of CoordMode, but all of them have the same problem.
Edit: Script I'm using
CoordMode, Mouse,Screen ; I've tried every CoordMode but none solve the problem
AppsKey::
while true {
Click 500,500,0
sleep,2000
}
Return

Or, it could be that you are not making use of CoordMode, and by default when you don't specify this, unfortunately mouse positions are reliant on the active window, which can cause unpredictable results as you discovered. For more reliability, I like to always precede my mouse movement commands with this command that sets the coordinate system of the mouse to the refer to the screen instead:
CoordMode, Mouse
Explanation
Documentation about CoordMode:
If this command is not used, all commands except those documented otherwise (e.g. WinMove and InputBox) use coordinates that are relative to the active window.
The full command is
CoordMode, Mouse, Screen
But documentation says we can omit the second parameter and it defaults to Screen:
If Param2 is omitted, it defaults to Screen.
So for more consistent results, use CoordMode command.

Try it with SendPlay (but see below if you use UAC):
AppsKey::
while true {
SetMouseDelay, 20, Play ; or play around with the delay amt
sleep, 50 ; or play around with the sleep amt
SendPlay {Click 500,500,0}
sleep, 50 ; or play around with the sleep amt
SetMouseDelay, 0
sleep,2000
}
Return
SendPlay [v1.0.43+]
SendPlay's biggest advantage is its ability to "play back" keystrokes and mouse clicks in a broader variety of games than the other modes. For example, a particular game may accept hotstrings only when they have the SendPlay option. However, SendPlay may have no effect at all on Windows Vista or later if User Account Control is enabled, even if the script is running as an administrator. The following script provides a workaround for this problem: http://www.autohotkey.com/forum/topic75595.html.
Of the three sending modes, SendPlay is the most unusual because it does not simulate keystrokes and mouse clicks per se. Instead, it creates a series of events (messages) that flow directly to the active window (similar to ControlSend, but at a lower level). Consequently, SendPlay does not trigger hotkeys or hotstrings.

Related

Exiting out of a running Python script when script window is hidden

I have a Python script written using Visual Studio Code that periodically moves the mouse icon to keep the computer active and stop it from falling asleep. This computer is used for displaying other info, so when the program is running the script window is minimized and another window is selected and opened and then the computer is left alone. When I want to use the computer again the Ctrl+C keyboard interrupt to terminate the script does not work unless the script window is reopened. This proved to be annoying as the script takes control of the mouse away from the user. I have a 'time.sleep' command that pauses the mouse movement to allow for user control again for a bit, but I would like to be ab le to just exit the script without having to wait for this pause to be able to open up the script window.
I am fairly new to Python, so I am unsure of other commands or keyboard inputs that might allow this to be possible.
The code I have does utilize the pyautogui module and has the default failsafe of moving the mouse icon to the corner of the screen enabled. However, this still requires me to wait for the pause in the script when I have control of the mouse again.
This is for a Windows environment.
If you are using pyautogui, just quickly move your mouse to the top left corner of the screen and your program will stop

Prevent WheelUp on !WheelUp

I am trying to send the letter "a" when ALT is pressed and the mouse wheel is scrolled up.
This code works partially:
!WheelUp::
Send, a
return
In Vscode or just the plain Windows Texteditor however, I notice some scrolling if I scroll to hard with my mouse while pressing ALT.
Can this be fixed?
First thing is to check for running applications with high priority. These may interfere with AHK. For example I had similar issues while running AIMP (music player) in the background.
Setting the script's priority might be worth trying too.

What's the difference between Send and ControlSend?

AutoHotkey's official documentation lists two different sets of commands for sending simulated keyboard input to a window.
Send / SendRaw / SendInput / SendPlay / SendEvent
Sends simulated keystrokes and mouse clicks to the active window.
ControlSend / ControlSendRaw
Sends simulated keystrokes to a window or control.
What's the difference between Send and ControlSend?
Is there a reason to use one over the other?
Send/SendXXX commands send input to the active window. That is the window that currently has focus, usually by clicking it with your mouse, tabbing to it, or when a window sets focus to itself.
If your AHK script were to target a Notepad window that you have open, and you were to click on another window such as Chrome, your inputs would now be sent to Chrome.
On the flipside, using ControlSend/ControlSendXXX commands will send input to a specified window or control. A control might be a textbox, button, or similar interactive elements.
Here, the above example would still output to Notepad even if you switched focus to another window such as Chrome. The downside is that you must specify which control to send to.

AHK - mouseclick coordinates relative to app window

I was reading through AHK documentation but couldn't find one where it explains how to define the coordinates WITHIN a certain application window.
For example, I want to be able to minimize/maximize the ribbon in all microsoft office apps (top right corner). This should work reliably no matter whether the window is maximized or not, and the mouse cursor should not shift (or at least it should shift back) while doing so.
Any idea how i can achieve this?
If you want coordinates to be relative to the active window, you need to use the CoordMode command at the top of your script. The second parameter specifies the coordinate mode will be for mouse coordinates. The third parameter you can specify either Screen or Relative. Relative is what you are looking for.
CoordMode, Mouse, Relative

Autohotkey - capture extra mouse buttons

Can autohotkey capture nonstandard mouse buttons? I use a five-button mouse (Microsoft Wireless Laser Mouse 6000).
XButton1 and XButton2 according to the documentation on autohotkey.com.
The following URLs show how to have autohotkey log all keyboard and mouse events, and how to look at the log autohotkey generates of those events.
http://www.autohotkey.com/docs/commands/_InstallMouseHook.htm
http://www.autohotkey.com/docs/KeyList.htm#SpecialKeys (special keys section)
Based on this, you can find out about all mouse and keyboard events by creating an autohotkey script as such:
#InstallKeybdHook
#InstallMouseHook
Once you run the script, you can double click on the tray icon for that script, then go to View > Key History and Script Info (Ctrl K)
Based on this information, I figured out that my mouse driver is already redefining the extra mouse buttons to other keys. However, I can re-map those keys by going to Control Panel > Mouse, selecting the desired button, and using the "Macro..." option in the mouse configuration (this is a special configuration only for the Microsoft Wireless Laser Mouse 6000 v2). In the macro dialog, I can define keystrokes for those mouse buttons to send (only one per mouse button). Next, I can use AutoHotkey to watch for whatever keystrokes I have defined, and perform specific actions based on those keystrokes.
You need to capture the scancode of the key and then use that. You can find a script in 5th post of this thread, written by Skan, which will allow you to do this. Just run that and click on the GUI with the mouse button you wish to determine the scancode. Then use the scancode in place of the normal key when you create the hotkey.
There is also a built in method of retrieving keys which is documented at the bottom of this page under the heading "Special Keys". Essentially, AHK logs your key presses and automatically records the scancodes for you.
To use the scancode as a hotkey, you just do the following:
SC###:: ;Your code here
Where ### is replaced with the code of your key (or mouse button).