Autohotkey – Use Space + Alt + Q to Trigger Actions

autohotkeykeyboard shortcuts

I have some actions defined in an Autohotkey script and I want to run it
whenever I press SPACE+Alt+Q.

How can I do it?

I have read that space has some issues, because it is already used by AHK to confirm the abbreviations or something like that, but I really don't use abbreviations.

~Space & j::
   If GetKeyState("Alt") = 0
           Send {Left}
   Else
           Send +{Left}
Return

What suggestions do you have?

now I'm trying this that got from AHK forum, so far, its allow me to run the script continuosly without having to realease the space bar

; THIS IS THE FIRST PART OF MY SCRIPT, ITS FOR THE e, +e, d, +d HOTKEYS...
ARprecColPickerFn(a, b, c)
{
clipboard =  ; Start off empty to allow ClipWait to detect when the text has arrived.
MouseGetPos posX, posY
BlockInput, MouseMove
MouseClick, Left, a, b
Sleep 50
SendInput {Ctrl Down}{c Down}
SendInput {c Up}{Ctrl Up}
ClipWait, 2  ; Waits 3 secs for the clipboard to contain text
clipboard += %c%
SendInput {Ctrl Down}{v Down}
SendInput {v Up}{Ctrl Up}
Send {Enter}
BlockInput, MouseMoveOff
MouseMove %posX%, %posY%
}

e::
ARprecColPickerFn(ARprecColPickerRestX, ARprecColPickerLumY, 2)
return

+e::
ARprecColPickerFn(ARprecColPickerRestX, ARprecColPickerLumY, 1)
return

d::
ARprecColPickerFn(ARprecColPickerRestX, ARprecColPickerLumY, -2)
return

+d::
ARprecColPickerFn(ARprecColPickerRestX, ARprecColPickerLumY, -1)
return


; THIS IS THE SECOND PART OF THE SCRIPT, IS FOR THE Space & e, Space & !e, Space & d, Space & !d...
~$Space::
    KeyWait,Space,T0.2
    If (ErrorLevel)
    {
        HotstringsEnabled:=true
        KeyWait,Space
        HotstringsEnabled:=false
    }
        else
        Send {Space}    
Return
#If HotstringsEnabled
#Hotstring *

e::
ARprecColPickerFn(ARprecColPickerRestX, ARprecColPickerBluY, 4)
return

!e::
ARprecColPickerFn(ARprecColPickerRestX, ARprecColPickerBluY, 2)
return

d:
ARprecColPickerFn(ARprecColPickerRestX, ARprecColPickerBluY, -4)
return

!d::
ARprecColPickerFn(ARprecColPickerRestX, ARprecColPickerBluY, -2)
#If

So far the script works fine, but I have an issue. the first part of the script, the one that use "d" as hotkey, it gets triggered whenever I press "space + d", how can I make both actions coexist together? (the one that is triggered by "d" and the other that its triggered by "space & d" Please any AHK superuser that could check it out, thanks advanced.

Btw, what does mean…

#Hotstring *

EDITED>>>>

In an Autohotkey script I would like Space Alt E to ADD FIVE, and Space Alt D to SUBTRACT FIVE, and Space E to ADD TEN, and Space D to SUBTRACT TEN.

I want to add or subtract consecutively and quickly, so I want to hold down Space Alt and then have distinct events when pressing E or D. e.g. SpaceHoldDown AltHoldDown Edown Eup Edown Eup Edown Eup would ADD FIVE 3 times.

Also sometimes I first press Space and then Alt (in order to hold them down before pressing E or D to ADD or SUBTRACT) and other times I press first Alt then Space, but in either case I would like to get the same result when pressing E or D afterwards. This is something my current script can't do, meaning I always have to take care to press first Space and then Alt before pressing E or D in order for the script to work, cuz if I press first Alt and then Space it wont work. I would like the script to work no matter in what order Space and Alt Key are pressed.

Finally I need the Space Key to keep its native function (not to be blocked) cuz it is used to navigate in the application.

Currently the script is working letting me hold down Space Alt and E or D consecutively in order to ADD or SUBTRACT multiple times, but it has the problems that I have to press first Space then Alt otherwise it won't work, also this whole peace of script must be placed at the very end of my AHK script cuz otherwise it will interfere with other subroutines.

LAST EDIT, THE CODE IM TRYING BASED ON JJHONSTON2 ANSWER…

#If WinActive("ahk_class xxx") || WinActive("ahk_class YYY")

    #If (GetKeyState("Alt", "P")) && (GetKeyState("Space", "P"))
        q::
            msgbox you typed Alt Space Q
    #If
#If    <----- do I need to put a second #If (turn off context sensitivity)?

but it doesn't work.

After testing, I have realized that I have to use #If and not If cuz the latter only will trigger the subroutine if I press Alt and Space AFTER I have pressed Q.

But using #If doesn't allow me to test 2 keys using the && operand.
please would somebody know how to use the #If GetKeyState with 2 keys Space and Alt

Please notice that I do need to be able to hold down space and alt and press and release Q multiple times in order to ADD 10 consecutively, that's very important, that's why a workaround like this below is not usefull cuz it force me to release alt or space between subroutines (run it multiple times)

#If GetKeyState("Space", "P")
!q::    ;   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.
msgbox wttffff
Return
#If

#If GetKeyState("Alt", "P")
Space & q:: ;   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.
msgbox wttffff
Return
#If

thanks advanced.

Best Answer

I am posting further because you continue to try different suggestions and combinations and are not just asking for someone else to write your script.

I am going to copy/paste/modify several key definition examples in hopes of giving you a feel for different ways this can be done (in ways which may or may not have been mentioned already), and hopefully give you a better understanding of the various logic combinations that can be used instead of just solving your particular key combination problem. Hopefully you will be able to figure it out if I do not address it directly.

Example: Trigger only if Space is pressed.

#If GetKeyState("Space", "P")   ; All hotkeys below won't trigger unless space is pressed
q::
    ToolTip % "Space+q pressed..."
    Sleep 500
    ToolTip
Return

!q::
    ToolTip % "Space+Alt+q pressed..."
    Sleep 500
    ToolTip
Return
#If

Example: Inspecific triggers for multiple modifier checks within the hotkey code.

#If WinActive("ahk_class xxx") || WinActive("ahk_class YYY")
*q::        ; * Triggers for all/multiple modifiers.  q keypress is discarded.

    If !(GetKeyState("Alt", "P") && GetKeyState("Space", "P"))
        Return  ; continue no further unless Alt+Space are also pressed.  q keypress is discarded

    ; This code below will execute for Alt+Space-q and also Alt+Space+Control+q (i.e., * modifiers that haven't been excluded via test above)
    ToolTip % A_ThisHotkey " pressed..."
    Sleep 500
    ToolTip
Return

Example: Manually send the keystroke (i.e., in-hotkey modifier filtering)

#If WinActive("ahk_class xxx") || WinActive("ahk_class YYY")
*q::        ; * Triggers for all/multiple modifiers

    If !(GetKeyState("Alt", "P") && GetKeyState("Space", "P")) {
        SendInput {Blind}q      ; send q keystroke and allow any pressed modifiers to stay in tact.  If Control is down, Control+q will get sent
        Return  ; continue no further unless Alt+Space are also pressed.  
    }

    ; This code below will execute for Alt+Space-q and also Alt+Space+Control+q (i.e., * modifiers that haven't been excluded via test above)
    ToolTip % A_ThisHotkey " pressed..."
    Sleep 500
    ToolTip
Return

Example: Keystroke gets sent to program regardless if you act on it or not.

#If WinActive("ahk_class xxx") || WinActive("ahk_class YYY")
~*q::       ; * Triggers for all/multiple modifiers; ~ allow passthrough so keystroke is not discarded

    If !(GetKeyState("Alt", "P") && GetKeyState("Space", "P"))
        Return  ; continue no further unless Alt+Space are also pressed.  q keypress has already passed through to program

    ; This code below will execute for Alt+Space-q and also Alt+Space+Control+q (i.e., * modifiers that haven't been excluded via test above)
    ToolTip % A_ThisHotkey " pressed..."
    Sleep 500
    ToolTip
Return

Example: Multiple definitions/actions in a single hotkey (works but not recommended implementation).

#If WinActive("ahk_class xxx") || WinActive("ahk_class YYY")
*q::        ; * Triggers for all/multiple modifiers; ~ allow passthrough so keystroke is not discarded

    If !GetKeyState("Space", "P")
        Return  ; continue no further unless Alt+Space are also pressed.  q keypress is discarded

    If (GetKeyState("Alt", "P") {
        ToolTip % "Alt+Space+q (and possibly other modifiers) pressed..."
        Sleep 500
        ToolTip
    } Else {
        ToolTip % "Space+q (and possibly other modifiers) pressed..."
        Sleep 500
        ToolTip
    }
Return

You can differentiate what keys are down inside of the hotkey definition and selectively execute distinct sets code, but general best practice is probably to use #If statements to determine when the hotkey code executes.

Don't use two #If's in a row... the hotkey definition is determined by the last sequential #If statement before the hotkey definition statement...

; Do Not Use...
#If WinActive("ahk_class xxx") || WinActive("ahk_class YYY")
#If (GetKeyState("Alt", "P")) && (GetKeyState("Space", "P"))    ; this voids the #If statement above

Should be as follows below.

; If ahk_class xxx or yyy, and if Alt+Space is also pressed...
#If (WinActive("ahk_class xxx") || WinActive("ahk_class YYY"))  && (GetKeyState("Alt", "P") && GetKeyState("Space", "P"))   
; ...
; code goes here
; ...
#IfWinActive ; this sets context for the next hotkeys back to default; only one statement needed; indentation is irrelevant

Note the use of grouping parens as needed for logical OR/AND combinations... you can get away without them in some cases but be careful to combine the statements carefully when mixing ANDs and ORs.

This statement can also be continued automatically on two lines (for style/readability) since the boolean operators are recognized as continuing the last line...

#If (WinActive("ahk_class xxx") || WinActive("ahk_class YYY"))  
&& (GetKeyState("Alt", "P") && GetKeyState("Space", "P"))
;q::    ; q hotkey without modifiers will never trigger here because Alt must be down to get this far
!q::    ; this will trigger
    ToolTip % "Space+Alt+q pressed..."
    Sleep 500
    ToolTip
Return
!d::
    ToolTip % "Space+Alt+d pressed..."
    Sleep 500
    ToolTip
Return
#If

Example: Split processing (inside/outside hotkey definition) (works but not recommended implementation)

#If (WinActive("ahk_class xxx") || WinActive("ahk_class YYY"))
!q::
    If GetKeyState("Space", "P") {
        ToolTip % "Space+Alt+q pressed..."
        Sleep 500
        ToolTip
    } Else {
        ToolTip % "Alt+q pressed..."
        Sleep 500
        ToolTip
    }
Return
#If

Example: All processing inside hotkey definition (works but not recommended implementation)

!q::
    If !(WinActive("ahk_class xxx") || WinActive("ahk_class YYY"))
        Return

    If GetKeyState("Space", "P") {
        ToolTip % "Space+Alt+q pressed..."
        Sleep 500
        ToolTip
    } Else {
        ToolTip % "Alt+q pressed..."
        Sleep 500
        ToolTip
    }
Return
#If

Final example with code split between hotkeys as needed and #If statements down-selecting to always have a certain class window active and Space pressed...

#Persistent
Return


#If (WinActive("ahk_class xxx") || WinActive("ahk_class YYY")) 
 && GetKeyState("Space", "P")   ; All hotkeys below won't trigger unless space is pressed

;!Space::Return     ; Optional. Kill the window system menu if present

q::
    ToolTip % "Space+q pressed..."
    Sleep 500
    ToolTip
Return

!q::
    ToolTip % "Space+Alt+q pressed..."
    Sleep 500
    ToolTip
Return

d::
    ToolTip % "Space+d pressed..."
    Sleep 500
    ToolTip
Return

!d::
    ToolTip % "Space+Alt+d pressed..."
    Sleep 500
    ToolTip
Return
#If

Note that this does not void the use of Space or Alt+Space as standalone keystrokes. For example if you press Space and then Alt and then a hotkey, it will send a Space before it executes the Alt+hotkey code. Similarly, if you press Alt+Space (say in a normal window) it will trigger the system window in the top left (Restore/Move/Size/Minimize/Maximize/Close). The hotkey functionality will still work, but the menu dropping down might be an annoyance (if you're not in a tool window that excludes this menu already), in which case you can also add an !Space::Return function to kill the functionality of Alt+Space while retaining the hotkey. In that case it should be added within the context block (relevant #If statement) so it only applies to that particular window.

There are multiple other ways to get code to execute for these key combinations as well, without using GetKeyState() (as noted in some of the other answers)--I am not going to reduplicate that information. You should be able to get some combination of answers posted to do what you want.

Related Question