1
votes

How do I:

  1. Read (wait for and record) a single press (i.e. Shift-Alt-F5 )
  2. Pass this recorded key combo to the program (i.e. Photoshop), without it running as a hotkey.

I tried this but it didn't work for my non ASCII hotkeys. It works for the t hotkey.

F6::
Suspend, On
Input, OutputVar, L1 M
Send, %OutputVar% 
Suspend, Off
return


F5::Run explorer
t::Run notepad
!+5::Run cmd
  • F5 is a hot key that runs the program Explorer.
  • F6 is a hot key that suspends all hotkeys for one press. And passes through the key combo as a non hot key
  • When I am in firefox if I press F6 F5 it will fall through to firefox's refresh page action.
  • When I press F5, without a preceding F6, it will open Explorer
6
Instead of capturing the keys (of undetermined length due to the various possible modifiers) with the input command, maybe you can trigger on something like WM_KEYUP. For every key that is pressed DOWN, track each pressed key (the modifier keys). Constantly monitor the last pressed key to see if it is released. This lifting up of the last pressed key would be your trigger that the hotkey was pressed and a trigger to to continue the script.Robert Ilbrink
B.t.w. Can you show what have you done in the mean time to try to solve this issue?Robert Ilbrink
I have been searching help, the web, and looking at key logger scripts... I can not see a clean solution... I am going to stick with having a hotkey that toggles the suspension of all hotkeys (except the toggle hotkeys hotkey), then toggle back on when I have passed the over shadowed keys to the underlying program.... I was hoping to save myself the extra button press of turning back on the hotkeys. I had this functionality in the linux window manager called sawfish using the function quote-event... Thanks for all your help Robertdericbytes

6 Answers

1
votes

Based on your notes, I think that you want to do the following. Use #r to block any input and start your script, then when you press #r again, the script stops and input is restored. When that is the case, you could try this:

#Singleinstance force
$#r::
If (MyToggle := !MyToggle) ; Toggle the value MyToggle True/False
    {
        ToolTip,Input  blocked [Win]+r,A_ScreenWidth/2-50,0
        BlockInput, on ; In Vista and above, you need to run AHK as admin or run AHK in compatility mode with Windows XP SP 3
        SetTimer RunMyScript, 500 ; Start the actual script in 500 ms outside of this script, so you can toggle
        Return
    }
Else
    {
        Tooltip
        BlockInput, off
        ;Reload ; This will KILL the "RunMyScript" IMMEDIATELY at an unpredictable location.
        Return
    }
return

RunMyScript: ; This script runs independently from the script above. The script stops after 10 loops and resets the input. [Ctrl]+[Alt]+[Del] still kills any script.
SetTimer RunMyScript, Off ; Turn the 500 ms timer off
loop, 10
{
    if (!MyToggle) ; Check the MyToggle variable to see if you need to stop the script. This will Exit the script at a predictable location.
        Exit

    SoundBeep, 600,600
    Sleep, 1000
}
BlockInput, off ; Allow keyboard & mouse input again. Warning the [Win] key key may be left activated, causing keyboard actions to start applications
Tooltip
Return

Let me know if this is what you were looking for.

1
votes

Two solutions.

  1. Add the hotkeys you want to capture to your input like this:

    Input, OutputVar, L1, {LControl}{RControl}{LAlt}{RAlt}{LShift}{RShift}{LWin}{RWin}{AppsKey}{F1}{F2}{F3}{F4}{F5}{F6}{F7}{F8}{F9}{F10}{F11}{F12}{Left}{Right}{Up}{Down}{Home}{End}{PgUp}{PgDn}{Del}{Ins}{BS}{Capslock}{Numlock}{PrintScreen}{Pause}
    

Otherwise these non-ascii keys are ignored by input.

Alternatively, make the behaviour of F5 key application specific.

SetTitleMatchMode, 2
#IfWinNotActive, Firefox
    F5::Run explorer
#IfWinNotActive

This way, your F5 key will always launch IE, except when you work inside Firefox, then F5 will be F5 and reload your page.

0
votes

Writing something to a log file can be done this way. Here I create a new logfile every day and for every entry you have to rpeat the last two lines (to get the actual time).

FormatTime, DateRef, %TimeNow%, yyyyMMdd ; Store current date in variable DateRef
MyLogFile = %A_ScriptDir%\LogFiles\LogFile-%DateRef%.txt ; Define the name of the log file.
FormatTime, TimeAbsolute, %TimeNow%, HH:mm:ss ; Use the current time to set the timestamp variable called TimeAbsolute used inside the Log File
FileAppend, `n`r| %TimeAbsolute% | Your hotkey and possibly in which application`n`r,%MyLogFile% ; Write logfile
0
votes

I have not yet checked this, but I think this is what you are looking for...

FormatTime, DateRef, %TimeNow%, yyyyMMdd ; Store current date in variable DateRef
MyLogFile = %A_ScriptDir%\LogFiles\LogFile-%DateRef%.txt ; Define the name of the log file.
FileAppend, `n`r| %TimeAbsolute% | Your hotkey and possibly in which application`n`r,%MyLogFile% ; Write logfile
Suspend, on ; Start with hotkeys disabled
Return

Pause:: ; Use pause key to 'activate' the hotkeys
Suspend, Off ; Activate the hotkeys
SetTimer, Stop, 10000 ; If no hotkey is pressed within 10 seconds, deactivate the hotkeys aagain
Return

Stop: ; Deactivate the hotkeys
Suspend, on ; Deactivate the hotkeys
SetTimer, Stop, Off ; turn the stop timer off
Return

q:: ; use a key (q) as a hotkey
Soundbeep, 600,600 ; sound a short beep to show that it works
HotKeyType = "q key"
WinGet, ApplicationType, ProcessName, A
GoSub, Write
Return

Write:
SetTimer, Stop, Off ; Make sure that the stop timer is turned off
FormatTime, TimeAbsolute, %TimeNow%, HH:mm:ss ; Use the current time to set  the timestamp variable called TimeAbsolute used inside the Log File
FileAppend, `n`r| %TimeAbsolute% | %HotKeyType% used in %ApplicationType%`n`r,%MyLogFile% ; Write logfile
Suspend, On ; Disable the hotkeys again
Exit
0
votes

With regard to logging the keys, I specifically defined the keytype to be printed in the log-file as a text string, this way you can define your own text for each non-printable key.

I re-wrote the script in the following way: When you press F6 once, and then another key (in this case F5), it will perform a beep (acts as a hotkey). If you press F6 twice, if will send F6 as if no hotkey was set. If you press F5 without first pressing F6, it will just send F5 as if no hotkey was active. Hope that this is what you wanted....

$F6::
If (MySuspend := !MySuspend) ; Toggle the value MySuspend True/False
{
        ToolTip Hotkeys On (F6),A_ScreenWidth/2-50,0
}
Else
{
    Tooltip
    Send, {F6}
}
return

$F5::
If MySuspend
{
    SoundBeep, 600, 600
    MySuspend := 0
    ToolTip
}
else
{
    Send, {F5}
}
Return
0
votes

Alright I think this is the final script....

Normally all keys behave as usual unless you press F6, then during 3 seconds you can use the hotkeys. As soon as you used a hotkey the behaviour falls back to normal again (the 3 seconds are only in case you do not press a hotkey). When you press F6 twice it will send F6. Let me know if you found an easier solution as this is relativey complex.

FormatTime, DateRef, %TimeNow%, yyyyMMdd ; Store current date in variable DateRef
MyLogFile = %A_ScriptDir%\LogFile-%DateRef%.txt ; Define the name of the log file for today.
FormatTime, TimeAbsolute, %TimeNow%, HH:mm:ss
FileAppend, | %TimeAbsolute% | Your hotkey and possibly in which application`n`r,%MyLogFile% ; Write logfile
SpecialF6:=1
Suspend, On
Return

$F6::
Suspend, Permit
If SpecialF6
{
Suspend, Off
ToolTip Hotkeys On for 3 seconds,A_ScreenWidth/2-50,0
SpecialF6:=0
SetTimer, SuspendOn, 3000
Return
}
else
{
    Send, {F6}
    MyText = F6
    Gosub, WriteClose
}
Return

SuspendOn:
Suspend, On
SetTimer, SuspendOn, Off
ToolTip
SpecialF6:=1
return

F5::
Run explorer
MyText = F5 Run Explorer
Gosub, WriteClose
Return

t::
Run notepad
MyText = t Run Notepad
Gosub, WriteClose
Return

!+5::
Run cmd
MyText = Alt Shift 5 Run Command
Gosub, WriteClose
return

WriteClose:
Suspend, On
SetTimer, SuspendOn, Off
FormatTime, TimeAbsolute, %TimeNow%, HH:mm:ss
ToolTip
SpecialF6:=1
FileAppend, | %TimeAbsolute% | %MyText%`n`r,%MyLogFile% ; Write logfile
Exit