Autohotkey: How to implement an exit sequence - sequence

In order to end my custom keyboard mapping for coding, I have placed the following line at the bottom of my script:
Esc::ExitApp
However, a single keystroke (especially the Esc) happens too much for other reasons. Therefore, I would prefer a sequence of single keystrokes (not holding down any key) to exit the Autohotkey mapping, such as "Esc and then LCtrl" or "Esc, LCtrl and then again Esc"
I have tried the idea from AutoHotKey key SEQUENCE, not just single-key hotkey :
Esc::
Input Key, L1
if Key=LCtrl
ExitApp
return
But it doesn't seem to do the trick: on pressing Esc and then LCtrl, the mapping doesn't stop. (Also, if I press Esc and then another key (not LCtrl) that next keystroke is ignored, something I would preferably not have.

Version 1a:
LCtrl & Esc::
ExitApp
return
You can add this code anywhere in your script. Press LCtrl and after Esc for script to exit.
Version 1b:
Esc & LCtrl::
ExitApp
return
You can add this code anywhere in your script. Press Esc and after LCtrl for script to exit.
You can add both Version 1a and Version 1b. In that case, when you press LCtrl and after Esc OR Esc and after LCtrl script will exit.
Version 2 (it uses different method, use it if for some reason you don't like Version 1a or/and Version 1b):
Loop
{
a := GetKeyState("Esc")
if (a=1)
{
b := GetKeyState("LCtrl")
if (b=1)
{
ExitApp
}
}
}
That code should be launch after your other code will remap all keys you need. Press LCtrl and after Esc OR Esc and after LCtrl for script to exit.
EDIT:
Version 3:
Loop
{
a := GetKeyState("Esc")
if (a=1)
{
Loop,60 ;number of 50 milliseconds script will wait to CTRL press. Example 60 means 60*50=3000, so script will wait 3000 milliseconds (1sec=1000 milliseconds) for CTRL press. After that time you have to press Esc again.
{
b := GetKeyState("LCtrl")
if (b=1)
{
ExitApp
}
Sleep, 50
}
}
}
That code should be launch after your other code will remap all keys you need. Press Esc (now you can release Esc ) and within 3000 milliseconds (1sec=1000 milliseconds) press LCtrl. After that time you have to press Esc again for script to exit. If you want to modify time after which you need to press Esc again read the comment in the code.
Also, always use AutoHotkey and its documenatation from http://ahkscript.org/ (current uptodate version, new official website)! AutoHotkey and its documentation from autohotkey.com is outdated and you may have some problems using them!

Related

Toggle Comments Keyboard Shortcut (CTRL + /) Does Not Work

I use SAS Enterprise Guide and Teradata Studio Express to code for my day job. WindowsOS.
I use CTRL + / shortcut to comment lines of code out in both apps. Suddenly, this shortcut has stopped working. I've checked all my keyboard and Code Shortcut Key settings in both apps and nothing seems out of place!
All other shortcuts seem to work in both apps, common ones I use like CTRL+C (copy), CTRL+X (cut), CTRL+V (paste) etc
I've got no idea why the 'comment out' shortcut is unable to register. Anyone else encounter this same annoying issue?
CTRL + : will pack your line in /* and */
If you have selected a range, Enterprise Guide will do that with every line from which you selected any character.
CTRL + Shift + : will unpack them
You just have to define it again.
Go to Tools-->options-->Enhanced Editor Keys
Select the Command "Comment the selection...." and press Assign keys
within "Press new shortcut key:" enter the ctrl + : key and press assign

Autohotkey - Hotstring not working after Tab Trigger

I've written a Autohotkey script to auto-complete print statement in java
System.out.println("");
by clicking s and then Tab and jump to next line when cursor is between quotation marks by clicking Shift + Enter as follows
:*:s`t::System.out.println("");{left}{left}{left}
+Enter::
ClipSaved := ClipboardAll
Loop
{
clipboard =
Send, +{Right}
Send, ^c
ClipWait , 0.2
StringRight := InStr(Clipboard,OutputVar, 1)
If OutputVar = {;}
Send ^v
Send {Right}
Send {Right}
Send {Right}
Send {Enter}
break
}
clipboard := ClipSaved
Return
The problem here is it works good when I type s and then Tab and when clicking Shift + Enter jumps to new line. But if I type anything between quotations and then hit Shift + Enter it jumps to new line but then onwards the auto-complete is not working i.e., I'm not getting print statement when typing s and then Tab.
The image of error is attached for illustration. You can copy/paste the code and tell me where the error is, as I'm unable to figure it out.
If you want to trigger a hotstring after you typed something, you need to use the question mark option. Try this:
:*?:s`t::System.out.println("");{left}{left}{left}

Disable Fn+F4 with AutoHotKey using time

I want to use AutoHotKey to disable Alt+F4 when they are pressed within 0.05 seconds of each other. Otherwise, I'd like it to work as normal.
Explanation:
My Lenovo Yoga 2 Pro has alternate functions for the function keys.
For example: "F3" is mapped to volume+, "F4" is mapped to "close active window"
There are two modes:
Old-school mode: F3 just acts as F3, and you must hold Fn+F3 key to activate volume+
New-school mode: Pressing F3 activates volume+, and Fn+F3 will do the normal F3.
In either mode, I run the risk of closing my active window when I go to use volume+ because they are too close, which is very problematic. Note that AutoHotKey cannot detect the Fn key, thus I cannot use that to solve my issue.
The image below shows the AutoHotKey Key History tool. In New-school mode, I typed "asdf" and then pressed "F4" which is "close active window". You can see this actually simulates ALT+F4, and there is a very short duration between ALT and F4...
I'm thinking that I could disable this "close active window" function by having AutoHotKey interrupt an ALT+F4 combo when there is less than 0.05 seconds between the two keys. Can this be done?
Edit:
In response to Blauhirn's code, here is the original, edited for a shorter wait duration, (from 50 to 10). It works most of the time, though 1/10 times the window is still cosed:
~alt::
hotkey, alt, off
hotkey, !F4, doNothing, on
sleep, 10
hotkey, !F4, doNothing, off
while(getKeyState("alt"))
sleep, 1
hotkey, alt, on
return
doNothing:
return
Here is a change I thought would fix my focus issue by sending a 2nd Alt when the "close active window" was detected:
doNothing:
send {LAlt}
return
However, the 2nd Alt is not sent. It IS sent when the delay is above 40ish, however I find that is way too long, and in turn it interferes with my manual use of Alt+F4.
Have you tried using simply
F4::return
? Maybe this will override the Lenovo action for F4
Other than that, here are the two approaches I can think of:
Disabling the ALT+F4 standard win hotkey by default. Adding a custom hotkey for a delayed F4
!F4:: ; by default:
doNothing: ; this is a label (see GoSub)
return ; == do nothing
~alt:: ; alt was pressed
sleep, 50 ; wait 50 milliseconds
if(!getKeyState("alt")) ; if alt is NOT pressed down anymore, exit
return
else ; (else is actually unnecessary here)
hotkey, !F4, close ; Add new AltF4-hotkey
return
close:
winclose, A ; close the Active window
return
~alt up:: ; alt is being released
hotkey, !F4, doNothing ; remove the new AltF4 hotkey and go back to custom standard behaviour: do nothing.
return
it still triggers Alt, which usually leaves me in the menu of the active window (File, Edit, View, etc), or if typing within a textarea (such is this), it will remove typing focus.
well yes. If you decide to keep the lenovo keys, I don't think there is a way to prevent it. As you suggested, sending ALT again should solve the problem
using Input, after ALT has been pressed. Input blocks user input for a configurable time, as long as the V option is used.
(3. disabling your Lenovo Yoga 2 Pro special keys. If you need the F3 function, you can do that in AutoHotkey e.g. using send {volume_up}

Shortcut Key to Move From VBA Immediate Window to Code Window

I know I can use Ctrl + G to move the cursor to the immediate window. Is there a different shortcut key to move the cursor back to the code?
Assuming VBA in Office; F7.
Alt+W, 1
For anyone out there using AutoHotKey, I incorporated Alex K's solution into the Autohotkey script I run whenever I log on:
SendMode Input ; Recommended for new scripts due to its superior speed and reliability
;*** ;VBA IDE
#IfWinActive ahk_class wndclass_desked_gsk ;only execute if VBA IDE is active win
^g:: ; Ctl + g: Toggle immediate window
WinGet, WindowUniqueID, ID, A
ControlGetFocus, ControlID, ahk_id %WindowUniqueID%
ControlGet, ControlHwnd, Hwnd,, %ControlID%, ahk_id %WindowUniqueID%
ControlTextSize = 16
VarSetCapacity(ControlText, ControlTextSize)
SendMessage, 0xD, ControlTextSize, &ControlText,, ahk_id %ControlHWND% ; 0xD is WM_GETTEXT.
If (ControlText="Immediate")
Send {F7}
Else
Send ^g
Return
#IfWinActive
First, the script creates a context-sensitive Ctl + G hotkey that requires the VBA IDE to be the active window (#IfWinActive ahk_class wndclass_desked_gsk).
When you press Ctl + G, the script checks to see if the title of the current control is "Immediate". If it is, then it sends an F7 which sends the focus back to the code. Otherwise it reissues the Ctl + G.

Autohotkey Win XP automating small task

I have a small task I would like to automate with Autohotkey and it looks like it is more or less directly transferable to autohotkey syntax:
1. Ctrl+v
2. Alt+tab
3. Click certain link in a window (no combo-key for this but it's always in the same place)
4. Enter (carriage return)
5. Alt+s
6. Ctrl+v
7. Enter
Now it would be nice to map this combo to something else e.g. Windows Key+Space.
What I have got so far is:
0. SetWinDelay 100 (using a connection to an remote computer)
0. SetKeyDelay 0
1. Send, ^c
1. ClipWait, 0.1
2. Send, {Alt down}{tab}
2. Send, {Alt up}
3. ?????
4. Send, {enter}
5. Send, !s
6. Send, ^v
7. Send, {enter}
Is this approximately right? Anyone up for helping me fix it or filling in the holes, so to speak :)
Another alternative to step 3, 4 and 6 would be to simply loop though the contents of the clipboard (a number string) and sending each letter of the string to keypresses? Maybe this would be the easier way
If you want to "click" on a certain position, to open a menu, you can first right click on your AutoHotKey icon and open the "window spy". This window spy will show you the mouse position. Yo can use the mouse positions to perform your actions in the active application.
Example:
SoundBeep 1000, 300 ; Wake up user
SplashTextOn, 200, 100, Script Preparations, Please Click on the person icon link. ; Show new Instructions text
WinMove, Script Preparations,, (A_ScreenWidth/2)+150, (A_ScreenHeight/2)+200 ; Move the window with the name "Script Preparations" Down and Right on the main screen
KeyWait, LButton, D ; Wait for LeftMouseButton click Down
MouseGetPos, xposE ,yposE ; Store the position where the mouse was clicked (Employee)
MouseClick, left, %xposE% ,%yposE%, 2 ; Perform a double mouse click on the captured mouse location
SplashTextOff ; Remove Text box
In this case, I first ask the user to manually click on the right location. This is only required when the position to click changes WITHIN the active window (variable tiles within the active window). Once you have the position stored, you can re-use it all throughout your script.
b.t.w. instead of using Alt+Tab, I suggest using this:
settitlematchmode, 1 ; Set search in title to start with....
settitlematchmode, Fast ; Slow is not required here. Slow is only required when hidden text needs to be found.
SwitchWindow("Microsoft Excel - 1 QRM Upload and Change Template") ; Activate the
window with the title: Microsoft Excel - 1 QRM Upload and Change Template
You could even use someting like this:
SetTitleMatchMode, 2 ; Ensure that the Title Match mode is set to 2: Find anywhere in the title
SetTitleMatchMode, Fast ; Ensure that the Title Match mode is set to FAST
winactivate, %WindowName% ; Activate the window with the title stored in the variable WindowName
WinWaitActive, %WindowName%, , 5 ; Wait up to five seconds for the screen
if ErrorLevel ; Execute this when the window is not activated within 5 seconds
{ ; Start-If Wait failed
SoundBeep 1000 , 1000 ; Warn the user
MsgBox,4097,Time Out, Script timed out while waiting for %WindowName%.`n`rYou Must manually activate %WindowName% and then continue the script by pressing OK. ; Message to user
IfMsgBox, Cancel ; Do when the user clicked on Cancel
{ ; Start-If User clicked Cancel
ExitApp ; Exit this program when the user clicked on Cancel
} ; End-If User clicked Cancel
WinWaitActive, %WindowName%, , 5 ; Try to activate the window AGAIN
if ErrorLevel ; If window can't be found
{ ; Start-If window can't be found
MsgBox,4096,Exit, %WindowName% still NOT Active. ; Warn user
ExitApp ; Exit this program when the expected window is still not found
} ; End-If window can't be found
} ; End-If Wait failed
Regards,
Robert Ilbrink