AutoHotkey Run script while holding down key - autohotkey

I need help with a script, i want it to only run while im holding down a key. Heres the script:
;If you use this, you have to use absolute screen coordinates.
CoordMode, Mouse, Screen
;Suppose a 100x100 px bounding box for your game inventory.
;Eg., from (500, 500) to (600, 600)
#if GetKeyState("joy5")
joy5:: MouseMove, 1771, 531
joy5 Up::MouseMove %oldx%,%oldy%
Numpad8::
{
;Get current Mouse coords
MouseGetPos, xCurrent ,yCurrent
;Calculate future Mouse coords
xMoved := xCurrent
yMoved := yCurrent - 35
;Check if the future mouse postion will be
;below the top border of your bounding box,
;aka still inside it, after it has moved.
;If so, proceed and move the mouse,
;otherwise do nothing.
MouseGetPos, CoordXRec, CoordYRec
MouseMove, xMoved, yMoved
if(yMoved < 503 && yMoved > 350 && yMoved > 360){
MouseMove 1846, 166
}
if(yMoved < 145){
MouseMove, %CoordXRec%, %CoordYRec%, 0
}
if(yMoved < 718 && yMoved < 720 && yMoved > 680){
MouseMove 1771, 671
}
return
}
Numpad5::
{
;Get current Mouse coords
MouseGetPos, xCurrent ,yCurrent
;Calculate future Mouse coords
xMoved := xCurrent
yMoved := yCurrent +35
;Check if the future mouse postion will be
;below the top border of your bounding box,
;aka still inside it, after it has moved.
;If so, proceed and move the mouse,
;otherwise do nothing.
MouseMove, xMoved, yMoved
if(yMoved > 285 && yMoved < 360){
MouseMove 1773, 526
}
if(yMoved > 697 && yMoved < 715){
MouseMove 1772, 736
}
return
}
Numpad4::
{
;Get current Mouse coords
MouseGetPos, xCurrent ,yCurrent
;Calculate future Mouse coords
xMoved := xCurrent -40
yMoved := yCurrent
;Check if the future mouse postion will be
;below the top border of your bounding box,
;aka still inside it, after it has moved.
;If so, proceed and move the mouse,
;otherwise do nothing.
if (xMoved > 1740) {
MouseMove, xMoved, yMoved
}
return
}
Numpad6::
{
;Get current Mouse coords
MouseGetPos, xCurrent ,yCurrent
;Calculate future Mouse coords
xMoved := xCurrent +40
yMoved := yCurrent
;Check if the future mouse postion will be
;below the top border of your bounding box,
;aka still inside it, after it has moved.
;If so, proceed and move the mouse,
;otherwise do nothing.
if (xMoved < 1917) {
MouseMove, xMoved, yMoved
}
return
}
Basicly you control the mouse with WASD and theres some other functionality to it aswell but i want to make it so that you have to hold down a key in order to move. Thanks!
only move when holding down a key.

Move mouse to 500,500 when Number-Pad-8 is pressed and NumLock is on. Return mouse to original location when key is released.
Numpad8::move()
Numpad8 UP::unmove()
move()
{
global oldx,oldy
MouseGetPos oldx,oldy
MouseMove 500,500
}
unmove()
{
global oldx,oldy
MouseMove %oldx%,%oldy%
}

To answer your original question (if the question changed so drastically, please open another one and finish this one):
You can dis/enable hotkeys dynamically, using the Hotkey-command. Assuming your masterkey is Space:
space:: ; this is a static hotkey definition
hotkey, numpad8, moveMouse1 ; this is a dynamic hotkey definition
hotkey, numpad6, moveMouse2
; etc
return
space up::
hotkey, numpad8, OFF ; this is a dynamic hotkey removal
hotkey, numpad6, OFF
; etc
return
moveMouse1: ; this is a label
moveMouse 50, 100
; your actions
return
moveMouse2:
; ....
return

Related

How do I activate a script only if the mouse is at a certain coordinate of the screen without interfering with my keyboard?

I cooked up a script that lets me map my keyboard's media shortcuts to my mouse LRM buttons when they are pressed while the mouse coordinate is leftmost or rightmost of the screen. While it does work, I'm having having strange side effects:
When I have caps lock on, ever few strokes the letter comes out lowercase.
When I use shift to type capital letters for an extended period of time, this will turn on caps lock
Using the keyboard history, I see that my script is constantly sending the "Alt Up" key, I did this so that it release the "Alt Down" state, but something is off.
My goal is to send an modifier key when a mouse is over a certain coordinate, so that when I click with that mouse button, it launches another ahk-programmed shortcut. But can't figure out where the logic error is in my code or thinking process.
Here's the script:
; ------------------------
; Global Initializers
#InstallKeybdHook
#MaxThreadsPerHotkey 1
; ---------------------
; Control Spotify; position your mouse top-most edge and use L/M/R-mouse keys.
SetTimer, WatchCursorx, 1000
return
WatchCursorx:
CoordMode, Mouse, Screen
MouseGetPos, xpos, ypos
;Based on location of the mouse simulate shortcut activation
If (xpos == 2559 || xpos == 0)
{
Send {Alt Down}
}
Else
{
Send {Alt Up}
}
return
;Define shortcuts mentioned above
!RButton::
Send {Media_Next}
return
!LButton::
Send {Media_Prev}
return
!MButton::
send {Media_Play_Pause}
return
#If(docs) is meant for this.
You could use it for example like this:
CoordMode, Mouse, Screen
#If, MouseOnTheRight()
LButton::SendInput, {Media_Prev}
RButton::SendInput, {Media_Next}
MButton::SendInput, {Media_Play_Pause}
#If
MouseOnTheRight()
{
MouseGetPos, x
return x == A_ScreenWidth - 1
}
Per my comments, try it like this:
CoordMode, Mouse, Screen
~RButton::
MouseGetPos, xpos, ypos
If (xpos == 2559 || xpos == 0)
{
Send {Media_Next}
sleep, 500
Send {esc} ' this gets rid of right context menu
}
return
~LButton::
MouseGetPos, xpos, ypos
If (xpos == 2559 || xpos == 0)
Send {Media_Prev}
return
~MButton::
MouseGetPos, xpos, ypos
If (xpos == 2559 || xpos == 0)
Send {Media_Play_Pause}
return
Note, the preceding ~ lets the original mouse click go through so ordinarily the context menu will come up on right click. I add a Sleep and Send Escape key to dismiss . . . Ymmv

OneNote intercepts pen cursor before AHK?

Palm rejection is garbage on my laptop, so I disabled the HID touchscreen to make it so that only pen input registers. So, I used AHK to make a script that will scroll around the page after the user presses ALT, and disables scrolling upon the second ALT press.
It works great, except that in OneNote (the Win 10 app), pen cursor input is hijacked by OneNote. For example, if I make a ToolTip, %xPos% %yPos%, then it won't update while my pen cursor is hovering anywhere above the OneNote window. Anywhere outside this works fine.
How can I make AHK steal pen cursor input before OneNote can get it?
isTabletMode := 1
penScrollActive := 0
#MaxThreadsPerHotkey 2 ; Allows a second instance to modify penScrollActive while PenScroll is looping.
$Alt::
; Check if PC is in tablet mode.
; 1 --> Tablet, 0 --> Desktop
RegRead, isTabletMode, HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\ImmersiveShell,TabletMode
if(isTabletMode) {
if(penScrollActive) {
penScrollActive := 0 ; We are already scrolling, so turn it off.
}
else {
penScrollActive := 1 ; We are not scrolling yet, so turn on pen scrolling.
}
GoSub PenScroll
}
else ; If we aren't in tablet mode, then Alt should just send Alt
Send, {Alt}
return
PenScroll:
loop { ; For some reason, while() logic wasn't working, so this is a workaround. Breaks upon the conditional at bottom.
MouseGetPos, mouseX, mouseY
ToolTip, %mouseX% %mouseY% ; For debugging: Output what cursor pos registers as. (This isn't working in OneNote when using the pen input as a cursor (eg. hover) ).
Sleep, 20
MouseGetPos, mouseX_new, mouseY_new
if (mouseX_new - mouseX > 0) ; Horizontal scrolling
Send, {WheelLeft}
else if (mouseX_new - mouseX < 0)
Send, {WheelRight}
if (mouseY_new - mouseY > 0) ; Vertical scrolling
Send, {WheelUp}
else if (mouseY_new - mouseY < 0)
Send, {WheelDown}
if (penScrollActive = 0) ; Conditional to break out
break
}
return
; To Reload the script: Win+`
#`::Reload
Return
#If penScrollActive
LButton::Return
One thing you could maybe try is my AutoHotInterception library for AHK. You install a custom device driver, then you can hook into input events at the driver level, below the OS.
It supports "Absolute" (Graphics-tablet-like) mouse input
You want the "Subscription Mode" endpoints

Move mouse between two monitors

How can I move the mouse pointer between monitors using a keyboard shortcut? I'm using autohotkey.
I didn't find a straightforward answer to it, so here's what I suggest.
Here's my approach, using Ctrl+Space for this function:
^Space::
CoordMode, Mouse, Screen ; This is needed to assure that you get your mouse coordinates related to the screen, not to the window
MouseGetPos, MouseX, MouseY
if( MouseX > 1920) ; 1920 is the Width of my monitor number 1, replace it with yours
{
MouseMove, -A_ScreenWidth, 0, 0, R
}
else
{
MouseMove, A_ScreenWidth, 0, 0, R
}
return

Click and drag one pixel in given direction

I am looking for a script that will click and hold the right mouse button down and drag in a given direction 1 pixel every "x" or 2 seconds. Something I can either tell to move in given direction by hitting the corresponding direction key or by adjusting the script manually.
Thank you!
Not entirely sure what you want, but try this:
CoordMode, Pixel, Screen
direction = left
secondsBetweenMoves = 0.1
F1:: ;F1 to start it
SendInput, {LButton Down}
SetTimer, Move, %secondsBetweenMoves%
Return
F2:: ;F2 to end it
SendInput, {LButton Up}
SetTimer, Move, Off
Return
Move:
MouseGetPos, mouseX, mouseY
If (direction = "left") {
MouseMove, mouseX-1, mouseY
}
Else If (direction = "right") {
MouseMove, mouseX+1, mouseY
}
Else If (direction = "up") {
MouseMove, mouseX, mouseY-1
}
Else If (direction = "down") {
MouseMove, mouseX, mouseY+1
}
Return
The send event command might make your life a whole lot easier. For example, what you're trying to do in a simplistic infinite loop:
coordmode, mouse, screen
setmousedelay, 0 # This makes the mouse move extremely fast
loop {
mousegetpos, mx, my
mx := mx+1
sendevent {click, r, down}
sendevent {click, %mx%, %my%, r, up}
sleep 2000
}
This loop will hold down the right button and move one pixel to the right every two seconds. If you want it to move to the left, change
mx := mx+1
to
mx := mx-1
Making it move up or down is the same mechanism, but adding or subtracting to the variable "my" instead.
This loop can be made into a timer, with hotkeys to enable or disable it.

pixelsearch and click right pixel

IF NOT A_IsAdmin ; Runs script as Admin.
{
Run *RunAs "%A_ScriptFullPath%"
ExitApp
}
#MaxThreadsPerHotkey, 2
CoordMode, Pixel, Screen
#singleInstance, Force
toggle = 0
upperLeftX := 750
upperLeftY := 400
lowerRightX := 850
lowerRightY := 500
F8:: ; press F8 to toggle the loop on/off.
SoundBeep
Toggle := !Toggle
While Toggle
{ ;-- Begin of loop.
PixelSearch, X, Y,%upperLeftX%, %upperLeftY%, %lowerRightX%, %lowerRightY%, 0x000000, 0, Fast RGB
IF ErrorLevel = 1 ; IF NOTFound.
{
sleep, 100
}
IF ErrorLevel = 0 ; IF Found.
{
MouseClick, left
sleep, 300
}
} ;-- End of Loop.
return
F8 starts loop and this code checks specific pixel in rectangle and sends left click.
It works with [MouseClick, left, %X%, %Y%].But I want to know how can I use dllcall mouse event to click on specific pixel.
for example
DllCall("mouse_event",uint,1,int,%X%,int,%Y%,uint,0,int,0)
But its not working
I doubt that you actually want to do this via DLL calls. mouse_event doesn't even take coordinates, but values between 0-65535.
If you want to be able to click any pixel on the screen make sure you set it to be relative to the screen: CoordMode, Mouse, Screen
Then use ControlClick/PostMessage/SendMessage if you don't want to affect your mouse pointer by that click. Or use MouseClick/Click. Or MouseMove+Send, {LButton}.