Autohotkey - Send key when clicked at certain position on the screen - autohotkey

I am attempting to write AutoHotkey code that results in sending the Space key when the Left Mouse Button is clicked at some position in the screen (ranges shown below). If the mouse is clicked outside the range, it should result in default behavior. The code below is not working. Example, if I click the Application's Close button whose ypos is less than 170, nothing happens. Request help/inputs. Thanks.
#IfWinActive ahk_class IrfanView
LButton::
MouseGetPos,xpos, ypos
If (ypos >170 and ypos <570)
{
Msgbox %ypos%
Send, {Space}
}
#IfWinActive
Return

You almost had it.
Since, you are handling the left mouse click, nothing further will happen mouse-wise.
So you have to re-issue the click event like this:
#IfWinActive ahk_class IrfanView
LButton::
MouseGetPos, xpos, ypos
If (ypos >170 and ypos <570) {
Msgbox %ypos%
Send, {Space}
}
Else {
Click
}
Return
Also note I removed your second #ifWinActive
That shouldn't happen before the return statement.
If you are only adding hotkeys for IrfanView, then that statement won't be necessary at all. If, like me, you are trapping keys for different windows/programs all in one big script, then follow a pattern like this
#IfWinActive ahk_class CabinetWClass ;Windows Explorer
...keydefs here...
#IfWinActiveahk_class XLMAIN ;Excel
...keydefs here...
#IfWinActive ahk_exe OUTLOOK.exe ;Outlook
...keydefs here...
#IfWinActive ;Keys that work anywhere
...all other keydefs here...

Related

Why autohotkey deos not send Ctrl-Space where Space is an input

Consider the following assignment:
When I type - followed by a key, the result is Ctrl-key. This work for ordinary keys.
But when the key is whitespace, it does not work.
Any idea why this happens? And how to fix the code?
-::
Input, key, L1,{LCtrl}
send, ^{%key%}
return
Edit.
Try to run the above script a program which has Ctrl-Space as a shortcut to see that it does not work. In fact, if you press - followed by Space, the script is suppose to call Ctrl-Space but it is not the case. For example:
In Microsoft Excel or in Libreoffice Calc, Ctrl-Space can select the current column.
In Emacs Ctrl-Space is reserved for setting a Mark.
Use SendInput instead.
Tested in Excel to mimic ^a, ^x, ^v, ^space
-::
Input, key, L1,{LCtrl}
SendInput, ^%key%
Return
If you want to handle "special" keys, add those keys to the list of endkeys using this syntax
Input [, OutputVar, Options, EndKeys, MatchList]
And then check to see which endkey was pressed
Tested in Firefox to mimic ^PgDn, ^PgUp
Input, key, L1,{LCtrl}{PgUp}{PgDn}
If (ErrorLevel = "EndKey:PgUp") {
SendInput ^{PgUp}
}
Else If (ErrorLevel = "EndKey:PgDn") {
SendInput ^{PgDn}
}
Else If (ErrorLevel = "EndKey:LCtrl") {
Return ;assumed you just want to abort input with the control key
}
Else {
SendInput, ^%key%
}
Return

AutoHotKey: Remap Alt, Ctrl, and Alt+Ctrl

I'd like to use AutoHotKey to remap:
RAlt::Volume_Down
RCtrl::Volume_Up
RAlt & RCtrl::SendInput {Volume_Mute}
While Vol up works fine with the script as above, vol down is non-repeating & mute only works if the buttons are pressed as Alt,Ctrl (not Ctrl,Alt). I understand why, I just haven't been able to come up with a solution. I can map either volume up/down or mute - but if I try to do both, the behavior is always finicky. I think what I need is something to the effect of:
if GetKeyState("RAlt") and GetKeyState("RCtrl")
{
SendInput {Volume_Mute}
}
else if GetKeyState("RAlt")
{
SendInput {Volume_Down}
}
else if GetKeyState("RCtrl")
{
SendInput {Volume_Up}
}
But this just runs & terminates. Is there a way to achieve what I'm after?
The problem with your solution is that RAlt & RCtrl::SendInput {Volume_Mute} turns RAlt into a "prefix key" and according to the Hotkeys section of Autohotkey help "The prefix key loses its native function".
Try this instead:
RAlt::Volume_Down
RCtrl::Volume_Up
#if GetKeyState("RAlt", "P")
RCtrl::Volume_Mute
#if GetKeyState("RCtrl", "P")
RAlt::Volume_Mute

AutoHotkey - Detect double press of AltGr

I want to detect double press on AltGr.
According to documentation:
; Example #4: Detects when a key has been double-pressed (similar to double-click).
; KeyWait is used to stop the keyboard's auto-repeat feature from creating an unwanted
; double-press when you hold down the RControl key to modify another key. It does this by
; keeping the hotkey's thread running, which blocks the auto-repeats by relying upon
; #MaxThreadsPerHotkey being at its default setting of 1.
; Note: There is a more elaborate script to distinguish between single, double, and
; triple-presses at the bottom of the SetTimer page.
~RControl::
if (A_PriorHotkey <> "~RControl" or A_TimeSincePriorHotkey > 400)
{
; Too much time between presses, so this isn't a double-press.
KeyWait, RControl
return
}
MsgBox You double-pressed the right control key.
return
AltGr is actually a combination of LControl & RAlt. So, for AltGr, script should be something like this:
~LControl & RAlt::
if (A_PriorHotkey <> "~LControl & RAlt" or A_TimeSincePriorHotkey > 400)
{
click
KeyWait, LControl & RAlt
return
}
click 2
return
But when I try to load this script, AutoHotkey gives an error:
Maybe there is a way to make an alias for key combinations.
As mentioned in the comments, KeyWait can only wait on one key (not hotkey) at a time. You only need to wait for RAlt to be released, not the combination of LCtrl and RAlt.
This works:
~LControl & RAlt::
if (A_PriorHotkey <> "~LControl & RAlt" or A_TimeSincePriorHotkey > 400)
{
KeyWait, RAlt
return
}
MsgBox Double-click
return
However, in this case KeyWait is only being used (in combination with the default #MaxThreadsPerHotkey setting of 1) to prevent key-repeat from activating the hotkey. You can remove KeyWait and it will still detect double-presses; but it will also activate if you hold AltGr down until it auto-repeats.
Note that in your case, double-pressing the hotkey would click three times: once on the first press and an additional two times on the second press.
If you just want to use AltGr as a mouse button and allow double-click, all you need is <^RAlt::Click.
If you want to perform two different actions depending on whether it is a single or double click, you must delay the response to the first click until you know whether there's a second click. For example:
<^RAlt::
KeyWait RAlt
KeyWait RAlt, D T0.4
if ErrorLevel
MsgBox Single
else
MsgBox Double
return

AHK: Assign hotkey only for one specific active window and not for others

I have just done a piece of code that does the following thing. When I make a selection by mouse in Firefox or EndNote, the script sents a Ctrl+c and checks the clipboard for a regex match. If there is a match, it changes the clipboard contents and shows a tooltip. It works fine for these two programs. Adobe Acrobat sometimes shows an error when a Ctrl+c is sent (even if a user presses a ctrl-c Acrobat sometimes shows famous "There was an error while copying to the Clipboard. An internal error occurred). So it decided to assign an F9 hotkey, but it works for all programs and not just for Acrobat. How do I assign an hotkey for only one window – Acrobat? Here's my code. I know it's lame – I am a newbie to programming in general, and in AHK in particular.
#If WinActive("ahk_exe firefox.exe") || WinActive("ahk_exe EndNote.exe") || WinActive("ahk_exe Acrobat.exe")
if WinActive("ahk_exe Acrobat.exe")
F9::
{
Clipboard:=""
send,^c
ClipWait, 1
ToolTip % Clipboard := RegExReplace(Clipboard, "\r\n", " ")
SetTimer, ToolTipOff, -1000
}
return
~LButton::
now := A_TickCount
while GetKeyState("LButton", "P")
continue
if (A_TickCount-now > 500 )
{
Send ^c
if WinActive("ahk_exe firefox.exe")
{
If RegExMatch(Clipboard, "[0-9]\.\s[A-Za-z,]*\s[A-Za-z]*")
{
regex := "[0-9]\.\s*|\s?\([^)]*\)|\."
replace := ""
}
else If RegExMatch(Clipboard,"[0-9]{2}[-\/][0-9]{2}[-\/][0-9]{4}")
{
Clipboard := RegExReplace(Clipboard, "^0", "")
regex := "\/"
replace := "."
}
else return
}
else if WinActive("ahk_exe EndNote.exe")
{
If RegExMatch(Clipboard, "[a-z]+\,\s[A-Z0-9‘“]")
{
regex := "\??!?\:|\?|!"
replace := "."
}
else return
}
ToolTip % Clipboard := RegExReplace(Clipboard, regex, replace)
SetTimer, ToolTipOff, -1000
}
return
#If
ToolTipOff:
ToolTip
return
I see some very fundamental problems in the first few lines. Let me explain...
There are two types of if-statements in AutoHotkey If and #If.
You usually always use the normal If-statements unless you are doing something with hotkeys and you want specific hotkeys to be context-sensitive.
Here are some important rules:
Normal If-statements have to use curly braces {} to mark the area of code that should be executed if the expression is true. If you don't use curly braces, the If-statement will work as if you had put curly braces around the first command directly under the If-statement.
Example:
If WinActive("Firefox") {
Send, Test
MsgBox, The script just typed "Test.
}
Another example:
If WinActive("Firefox")
MsgBox, Firefox is the active window.
Normal If-statements cannot be used around a hotkey definition, but only within it.
This is allowed:
F1::
If (A_OSVersion = "WIN_7") {
MsgBox, Your operating system is Windows 7 and you just pressed F1.
}
Return
This is NOT:
If (A_OSVersion = "WIN_7") {
F1::
MsgBox, Your operating system is Windows 7 and you just pressed F1.
Return
}
But there is a way around that and that is #If-statements.
#If-statements don't use curly braces ever.
They can only be used on hotkey definitions.
And they can only be closed by another #If-statement.
(It's very common to simply use an empty #If to close it.)
Examples:
#If (A_OSVersion = "WIN_7")
F1::
MsgBox, Your operating system is Windows 7 and you just pressed F1.
Return
#If
A more complex example:
#If (A_ScreenWidth >= 1920)
F1::
MsgBox, Your your screen is at least 1920 pixels wide.
Return
F2::
MsgBox, Your operating system is %A_OSVersion%.
Return
#If (A_ScreenWidth < 1920)
F1::
MsgBox, Your your screen width is smaller than 1920 pixels.
Return
#If
As you might have guessed by now, hotkey definitions are always started by a pattern like this hotkey:: and closed by a Return. Although you can define hotkeys on a single line.
Examples:
F1::MsgBox, Hello!
F2::a ;This will remap the F2 key to an a-key.
Hotkeys by themselves do never use curly braces! Though an If-statement within a hotkey still has to use them according to the before mentioned rules.

How to toggle a set of keybinds on and off?

I am trying to set up a group of keybinds that I can toggle on and off with a single button press but haven't been able to find any examples anywhere.
I want ^NumpadSub to toggle these different keybinds to turn them on and off when I press ^NumpadSub.
q::w
z::s
w::up
s::down
Can anyone help on how I would set up the code to do so?
When these are the ONLY ones, you could add one more hotkey:
^NumpadSub::Suspend
This will suspend ALL hotkeys (except the one that is used for toggling suspend on/off)
Otherwise you would have to use the actual hotkey function (http://www.autohotkey.com/docs/commands/Hotkey.htm) which allows you to turn hotkeys on/off, but the hotkey function refers to labels: (go to addresses).
If you want to ONLY have these keys act a certain way when you use ONE particular application (Game), you can use the #IfWinActive command.
e.g.
SetTitleMatchMode, 2
#IfWinActive, Notepad ; Start of Notepad specific keys.
a::Send, Haha
b::SoundBeep, 500, 500
#IfWinActive ; End of Notepad specific keys.
In that situation, Check out if this works for you! I added $ signs in front of w and s because hitting q and z would trigger the execution of w and s
Hotkey, q , MyQ, On
Hotkey, z , MyZ, On
Hotkey, $w , MyW, On
Hotkey, $s , MyS, On
Return
^NumpadSub::
KeyToggle:=!KeyToggle
Hotkey, q , % (KeyToggle ? "Off": "On")
Hotkey, z , % (KeyToggle ? "Off": "On")
Hotkey, $w , % (KeyToggle ? "Off": "On")
Hotkey, $s , % (KeyToggle ? "Off": "On")
Return
MyQ:
SendInput, w
Return
MyZ:
SendInput, s
Return
MyW:
SendInput, {Up}
Return
MyS:
SendInput, {Down}
Return