If mouse is clicked, do one thing, if mouse is held down, do the normal thing - autohotkey

I want my code to be able to register if the mouse is clicked, and do something when that happens, but also to be able to register if the mouse is held down and not interrupt the mouse being held down if that is the case. For example,
If AutoCAD is open
If mbutton is clicked
click the escape key
If mbutton is held down
be able to use the mbutton held down as usual
End
I've tried a couple of different ways to do this but I don't have the knowledge to do this exactly. I've got the "If AutoCAD is open", and the "click the escape key" parts down, just not the "use the mbutton as normal if held down part"
Thanks for any help you can provide!

This was a bit of a tricky one. Change the #IfWinExist line accordingly. You can adjust the duration to be what you would consider "holding" MButton
SetTitleMatchMode, 2
#IfWinExist AutoCAD
~MButton::
duration := 100
start := A_TickCount
While(GetKeyState("MButton"))
{
if ((A_TickCount - start) > duration)
{
KeyWait, MButton
Send {MButton Up}
Return
}
}
Send, {Escape}
Return
#IfWinExist AutoCAD

If I understand you right, you are searching for the UP keyword:
The word UP may follow the name of a hotkey to cause the hotkey to
fire upon release of the key rather than when the key is pressed down.
(documentation)
#if autocad()
MButton Up::
send {escape}
return
#if
autocad() {
return true
}

Related

AHK Remapping Middle Mouse button to something else

After a month of trial and error, I've finally found a solution!
How to remap Middle mouse button something else?
If you don't have a three-button mouse, this is a must-have for blender (esp. Laptop)
I'm aware of "emulate 3 button mouse" in Preference>>Input.
But if you check that option then you won't be able to 'Select loop'
which uses ALT leftClick.
What if you could remap Mbutton to any other key you rarely use?
Yes you can!
Nice to see that you tried it yourself.
But here's how a context sensitive remap is actually done:
#IfWinActive ahk_class GHOST_WindowClass
LWin::MButton
#IfWinActive
This script will allow you to remap Mbutton with other key, such as LeftWin.
;~--------------------------------------------------------------------------------------
#IfWinActive ahk_class GHOST_WindowClass ; Blender's class
$LWin:: ; "$" this allows to send the trigger key in a working script***
loop
{
if getkeystate("LWin", "p") ; if a button is Physically held down by the user.
{
send, {MButton DOWN}
}
else
{
send, {MButton UP}
;~ MsgBox, Blender is active ; You dont need this.
return
}
}
#IfWinNotActive ahk_class GHOST_WindowClass ; Other than blender (I'm aware of other methods, but this works for me!)
Send, {LWin} ; *** like here I'm able to use Left Win again without triggering the script.
;~ MsgBox,Blender isnt active ;; You dont need this.
return
;~ --------------------------------------------------------------------------------------

How can I use autohotkey to stop WASD movement while holding down the left mouse button?

I'm interested in disabling the w,a,s, & d keys while holding down the left mouse button.
(Games such as cs:go and valorant penalize shooting while moving, so I'd like to preclude that situation entirely).
I just learned about autohotkey, so I'm sorry if I offend someone with this attempt at code(which obviously doesn't work):
while (GetKeyState("LButton", "P"))
{
w::return
a::return
s::return
d::return
}
Thanks, much appreciated!
I just want to add in the solution that #Spyre hinted at. The script does indeed become much smaller when you use the #If directive, and when the if statement fails, the hotkey doesn't fire, so it doesn't add to your overall hotkeys per interval. Here is my version of the script:
#If GetKeyState("LButton", "P")
w::
a::
s::
d::
Return
Use #If (docs):
#If, GetKeyState("LButton")
w::
a::
s::
d::return
#If
And if #If were to cause you trouble (like warned about in the documentation) (it's not going to happen if your script is this small and simple), you'd want to do turn on and off the hotkeys with the Hotkey command.
For example:
~LButton::ConsumeASDW("On") ;press down
LButton Up::ConsumeASDW("Off") ;release
ConsumeASDW(OnOff)
{
for each, key in StrSplit("asdw")
Hotkey, % key, Consumer, % OnOff
}
Consumer()
{
Return
}
You've got the right idea, but what you currently have will be auto-executed at the beginning of the script, and after one run through of checking whether or not the LMB is held down, the script will stop doing anything.
My approach, using the $ modifier with hotkeys to make sure the hotkey doesn't recursively trigger itself.
$w::
if (GetKeyState("LButton", "P"))
return
Send w
return
$a::
if (GetKeyState("LButton", "P"))
return
Send a
return
$s::
if (GetKeyState("LButton", "P"))
return
Send s
return
$d::
if (GetKeyState("LButton", "P"))
return
Send d
return
There might be some more efficient way of declaring the condition of the hotkeys using the #If directive, but this should the job that you need it to.

AHK script to change RButton Behavior

I want to make a script that would allow me to click once every time I press the mouse, however, if instead of letting go immediately, I hold the RMB for more than 0.25s it would click again on release.
Essentially allowing me to use RMB normally as long as I don't hold it for too long but allowing me to do a double click if held.
This is a work around since my mouse's button gets stuck if I click too fast and I'm not able to get a new one atm.
The purpose of this is to be able to use my mouse on PS and to play the one game i play some times: Black Ops 2 while i save enough for a new mouse. In the context of the game, i want to be able to use Toggle ADS as a base and be able to use the toggle by default by just clicking but be able also do a Hold to ADS with the same button on the fly without changing the game's configuration.
I am not very proficient at AHK and this is all I got so far, holding works fine, however if I don't hold, it does a double click which is annoying.
RButton Down::
Send {Click, Right}
keywait RButton, t.25
if errorlevel
keywait RButton,
Send {RButton Up}
return
You could maybe do some trickery with multiple KeyWaits, but I wouldn't recommend time consuming processing inside hotkey labels in any case due to AHKs single threaded nature.
Here's something very simple I'd recommend instead:
~*RButton::RClickTime := A_TickCount
~*RButton Up::
if (A_TickCount - RClickTime >= 250)
Click, Right
return
So first when we press down RButton (note that there is no "down" state for hotkey names, the key name itself means it being pressed down) we store the current system time with A_TickCount.
And we use the ~ modifier for the hotkey so the keypress itself isn't consumed.
And the * modifier is used so holding down e.g. Ctrl or Shift, etc, wouldn't make the hotkey not work.
Then on RButton release (RButton Up::) we compare the current system time with the stored system time to see if over 250ms passed. If so, we send another right click with Click, Right (don't use a send command here, it isn't really intended for this).
It looks like you're missing some curly braces around your if block; but I think you can implement the right double-click functionality with something as simple as,
RButton::
KeyWait RButton, T.25
numberOfClicks := errorLevel + 1
Send {Click Right %numberOfClicks%}
return
~RButton:: ;*When Right Mouse Button is Down, do the following.*
keywait RButton, T.25 ;*Wait (250 milliseconds) for it to be released.*
if errorlevel { ;*When it exceeds the said time*
keywait RButton ;*Wait for it to be released*
Send, {RButton Up} ;*Send Right Mouse Button up*
}
return

Trigger double press when key held

I am new to stackoverflow and apologize in advance if what I am trying to explain is unclear.
I have tried multiple ways to make this work but have had no success so far.
I am trying to achieve the following:
When F3 is held and left arrow is pressed, left arrow will be pressed twice with no pause (0sec).
When F3 is held and right arrow is pressed, right arrow will be pressed twice with no pause (0sec).
Here's an alternative to Blauhirn's
F3::
While (GetKeyState("F3", "P")) {
If (GetKeyState("Left", "P"))
SendInput, {Left}
If (GetKeyState("Right", "P"))
SendInput, {Right}
}
Return
Alternatively you don't need to Loop to send multiples of of the same key.
You can simply use SendInput, {Left 4} the number represents the number of times that key will be sent.
Edit:
Oops, I didn't address the issue of delay between key presses. So I changed Send to SendInput as that has no delay between key presses.
~F3 & ~left::
send {left}
return
does this work?
This means, that as soon as f3 and left is pressed together, left will be sent a second time. If you want to repeat the send {left}command, use it like
loop, 4 ; 4 times
{
send {left}
}

How to remap key in certain case and not remap in other case with autohotkey?

I want to remap alt+e when caps is on in autocad.
And when capslock is not on, alt+e should open menu edit.
I use script like this
<!e::
if(GetKeyState( "CAPSLOCK", "T" ))
{
SendInput erase{space}wp{space}
}
else
{
Send !e
}
When I turn on capslock, remap key is OK.
When I turn off capslockand alt+e, menu edit opened, but closed immediately.
Thanks.
You will want a $ at the beginning of your hotkey to prevent the endless loop that the !e in your else block will trigger. You will also want to add a Return at the end of the hotkey to prevent the script from continuing into what is below this hotkey.
$!e::
if GetKeyState( "CapsLock", "T" )
Sendinput, erase{space}wp{space}
else
Sendinput, !e
Return
(Brackets are only required when if/else blocks are more than one line.)
Beyond that, the likely issue is that it's an alt hotkey that is also set to send alt.
I say this is an issue because if you press and hold alt, it activates menus,
and then the script sends alt, which will be in conflict with that.
As Ricardo said, the ideal way to script this is with the #IF command (only included with AHK_L).
#If GetKeyState("CapsLock", "T") and WinActive("AutoCAD")
!e:: SendInput, erase{space}wp{space}
#If
Notice that you can add the WinActive() function to the #If command's expression.
Try it without that first, and also realize that the application's title needs to be exactly "AutoCAD" at all times for that to work. I would recommend finding AutoCad's ahk_class,
with AHK's window spy, instead of using the title.
If it still does not work, it is likely that AHK is sending faster than AutoCAD would like to receive.
Info on how to deal with that can be found here.
Try to change your else block to this:
Send, {ALTDOWN}e{ALTUP}
I do not rely on these symbols to send keystrokes in AutoHotKey.