AutoHotkey Script to send pound (£) on double press of Shift+3 - autohotkey

I'm trying to make a script that sends a pound instead of a dollar when you hold down Shift and press 4 twice quickly.
Has anyone seen any code that does this sort of thing?
EDIT:
Okay I've seen some documentation and managed to get it detecting the double shift+3 press like this:
Shift & 4::
if (A_PriorHotkey <> "Shift & 4" or A_TimeSincePriorHotkey > 400)
{
KeyWait, 4
return
}
Send, £
return
But can't get it to send the $ for some reason. Any ideas?

I got the intended functionality working eventually:
Shift & 4::
if (A_PriorHotkey <> "Shift & 4" or A_TimeSincePriorHotkey > 800)
{
Send, {$}
return
}
Send, {BS}
Send, £
return
Basically, when you press Shift+4 the dollar is printed. If you're still holding shift and you press 4 again, the backspace key is pressed and the £ is printed.

As in http://www.autohotkey.com/docs/KeyList.htm#SpecialKeys, you should put key name into " ".
KeyWait, "3"

Does this work?
Shift & 4::
KeyWait, 4 ; waits for '4' to be released
KeyWait, 4, D T.4 ; waits 400ms for 4 to be pressed again
Send % ErrorLevel ? "{$}" : "{BS}{£}"
; if ErrorLevel=1 (4 not pressed) will send $ else will send {BS}£
return

I used to do this in a complicated way as well until I realized that the solution is very simple:
:*:$$::£
Just press $ sign twice to get a £ (or €)
B.t.w. I did the same for ", just press ' twice to get "
:?*:''::"{Space}
The {space} is required for me because " is only printed after I press space. (Dutch language setting).

Related

Send only if key was pressed alone

I'd like to remap my windows key to something else, but also I'd like to keep all windows key based shortcut.
In pseudo code it would be something like this:
when LWin Down
until LWin Up
if not LWin down
abort
else
execute command
Release the left windows key within 0,3 seconds after pressing it, to do something else (e.g. to send a):
~LWin::
KeyWait, LWin
return
~LWin Up::
Send {LWin Up}
If (A_PriorHotKey = "~LWin" AND A_TimeSincePriorHotkey < 300)
Send, a
; else ; another action after long press (not recommendet)
; Send, b
return
EDIT:
Try also this:
LWin up::
If (A_PriorKey = "LWin")
Send a
return
; In this case its necessary to define a custom combination by using "&" or "<#"
; to avoid that LWin loses its original function as a modifier key:
<#d:: Send #d ; <# means LWin

AHK! Can't get "Ctrl+Q then K" Input to work (Shortcut in Q-Dir tool)

Background:
So I use the Explorer tool Q-Dir (link to homepage).
In Q-Dir you can bookmark folder you want to access regularly.
You can shortcut to those bookmarks by pressing Ctrl + Q. This opens a jumplist of your bookmarked folders.
So I want to open my projects folder which is named "Kundenprojekte" (customer projects).
Pressing "K" while said jumplist is open, opens this folder in the current tab.
So my problem occurs here:
This whole process is what I want to map with AHK to let's say WinKey + B.
This is my code so far:
#b::
qdirId := WinExist("Q-Dir 5.98.9") ; I don't know if this works I got some
; inspiration by another AHK script
if (qdirId = 0) {
MsgBox Q-Dir ist nicht geöffnet. ; Q-Dir is not open.
IfWinExist, "Q-Dir 5.98.9"
{
WinActivate, "Q-Dir 5.98.9" ;I know this doesn't work plz help
SetKeyDelay 10,1000
Send, ^{Q}
SetKeyDelay, 10
Send {K}
return
}
}
return
Yes , so far there is no "else" to IfWinExist. And I don't think there will be because I would need to run Q-Dir as administrator (due to UAC preventing writing operation to my C: drive) But that is of no concern (because I usually start Q-Dir as my first programm after booting).
The main issue I have is getting "send Control + Q" then "K" to work.
I got it to send "K" but not once was "Ctrl + Q" recognized.
Any idea what I do wrong?
Thank you in advance :)
SetTitleMatchMode, 2 ; The window's title should contain "Q-Dir 5.98.9"
#b::
qdirId := WinExist("Q-Dir 5.98.9")
if (qdirId = 0)
{
MsgBox Q-Dir ist nicht geöffnet. ; Q-Dir is not open.
return ; stops code from going any further, to the lines below
}
; otherwise:
WinActivate, Q-Dir 5.98.9
WinWaitActive, Q-Dir 5.98.9 ; important
SetKeyDelay 10,1000
Send, ^{Q}
; Try also:
; Send, {CTRLDOWN}q{CTRLUP}
; SendEvent {CTRL DOWN}{q DOWN}{CTRL UP}{q Up}
SetKeyDelay, 10
Send {K}
return
https://autohotkey.com/docs/commands/SetTitleMatchMode.htm

What is the right way to send Alt + Tab in Ahk?

Ok. I know this is a very stupid question.
But I'm stuck already for an hour.
I got very little experience with ahk, however I made work every script until now with no problems. I explored the ahk tutorials but found no solution up to now.
I'm trying to switch to prev. app with a single numpad off key.
I've tried:
!{Tab}
,
{Alt down}{Tab}{Alt up}
I've tried it with Sleep delays, multiline, multiline inside brackets, with and without commas after commands, etc.
I'm quite sure is very simple but something I've not tried yet.
Any suggestion?
$F1:: AltTab()
$F2:: AltTabMenu()
; AltTab-replacement for Windows 8:
AltTab(){
list := ""
WinGet, id, list
Loop, %id%
{
this_ID := id%A_Index%
IfWinActive, ahk_id %this_ID%
continue
WinGetTitle, title, ahk_id %this_ID%
If (title = "")
continue
If (!IsWindow(WinExist("ahk_id" . this_ID)))
continue
WinActivate, ahk_id %this_ID%
WinWaitActive, ahk_id %this_ID%,,2
break
}
}
; AltTabMenu-replacement for Windows 8:
AltTabMenu(){
list := ""
Menu, windows, Add
Menu, windows, deleteAll
WinGet, id, list
Loop, %id%
{
this_ID := id%A_Index%
WinGetTitle, title, ahk_id %this_ID%
If (title = "")
continue
If (!IsWindow(WinExist("ahk_id" . this_ID)))
continue
Menu, windows, Add, %title%, ActivateTitle
WinGet, Path, ProcessPath, ahk_id %this_ID%
Try
Menu, windows, Icon, %title%, %Path%,, 0
Catch
Menu, windows, Icon, %title%, %A_WinDir%\System32\SHELL32.dll, 3, 0
}
CoordMode, Mouse, Screen
MouseMove, (0.4*A_ScreenWidth), (0.35*A_ScreenHeight)
CoordMode, Menu, Screen
Xm := (0.25*A_ScreenWidth)
Ym := (0.25*A_ScreenHeight)
Menu, windows, Show, %Xm%, %Ym%
}
ActivateTitle:
SetTitleMatchMode 3
WinActivate, %A_ThisMenuItem%
return
;-----------------------------------------------------------------
; Check whether the target window is activation target
;-----------------------------------------------------------------
IsWindow(hWnd){
WinGet, dwStyle, Style, ahk_id %hWnd%
if ((dwStyle&0x08000000) || !(dwStyle&0x10000000)) {
return false
}
WinGet, dwExStyle, ExStyle, ahk_id %hWnd%
if (dwExStyle & 0x00000080) {
return false
}
WinGetClass, szClass, ahk_id %hWnd%
if (szClass = "TApplication") {
return false
}
return true
}
EDIT (suggested by the user Ooker):
The script pops up a menu for you to choose.
This is what it looks like:
If you just want to switch back to the previous application, use Send, !{Esc}
You shouldn't manually send alt+tab as it is a special windows command, rather use the AltTab commands that do that for you.
AltTabMenu opens the tab menu and selects the program, whileAltTab, ShiftAltTab navigate through it.
h::AltTabMenu
n::AltTab
m::ShiftAltTab
There are some issues with Windows 8/10 and keys like ctrl-alt-del and alt-tab. Here is one solution:
F1::
{
Send {Alt Down}{Tab} ;Bring up switcher immediately
KeyWait, F1, T.5 ; Go to next window; wait .5s before looping
if (Errorlevel)
{
While ( GetKeyState( "F1","P" ) ) {
Send {Tab}
Sleep, 400 ; wait 400ms before going to next window
}
}
Send {Alt Up} ;Close switcher on hotkey release
}
return
My personal goal was to remap Alt-Tab to Win-Tab (because I'm using a Mac keyboard on a Windows 10) so I took what Stepan wrote above plus some documentation and here is is, working fine for me :
#Tab::
{
Send {LAlt Down}{Tab}
KeyWait, LWin ; Wait to release left Win key
Send {LAlt Up} ; Close switcher on hotkey release
}
return
Worked for me:
F1::
Send, {ALT DOWN}{TAB}{ALT UP}
return
It simulates the Alt + Tab behavior for F1 key.
Well, finally I found the reason and some "solutions" here and here.
It seems that Windows 8 blocks Ahk {Alt Down}{Tab} and AltTabMenu and some other keys.
For now I'm using this to scroll windows forward:
Send !{ESC}
This to display the AltTabMenu:
Run, "C:\Users\Default\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\Window Switcher.lnk"
And this to switch to the previous app as suggested in one of the topics:
LCtrl & z:: ; AltTabMenu
state := GetKeyState("Capslock", "T")
if state = 1
SetCapsLockState, Off ; CapsLock On blocks Task Switching metro window
Send, !{Tab} ; prevents displaying inactive Task Switching metro window
run, Window Switcher.lnk ; must be in script directory otherwise include path
WinWait, Task Switching,, 2
KeyWait, Ctrl
Send, {Enter}
if state = 1
SetCapsLockState, On ; restores CapsLock State
state =
return
#IfWinActive, Task Switching
LCtrl & q::Send, {Right}
LCtrl & a::Send, {Left}
It would be great to get to the previous app with no AltTabMenu splashing.
In case you want to do multiple "tabs", then the below function should help doing that. This was at least own solution on my Windows 8.1 machine.
The approach is:
1) Get a list of all the windows
2) Loop 1:
find the index of the current window
set the index to switch to ("current" + "offset")
3) Loop 2:
loop until you hit the index to switch to, then switch window
AutoHotKey code sample below:
; Test switch of 1 window
F1::AltTabFunction(offset:=1)
; Test switch of 2 windows
F2::AltTabFunction(offset:=2)
AltTabFunction(offset:=1)
{
; ****************************
; Function for switching windows by ALT-TAB (offset = number of windows to "tab")
; ****************************
; Get list of all windows.
WinGet, AllWinsHwnd, List
WinGetTitle, active_title, A ; Get title of active window.
; Find index of the current window.
counter_of_none_hidden_windows := 0 ; Initiate counter for counting only the none-hidden windows.
Loop, % AllWinsHwnd
{
; Find title for window in this loop.
WinGetTitle, CurrentWinTitle, % "ahk_id " AllWinsHwnd%A_Index%
; From [1]: "Retrieves an 8-digit hexadecimal number representing the extended style of a window.".
; [1] : https://autohotkey.com/docs/commands/WinGet.htm
WinGet, exStyle, exStyle, % "ahk_id" AllWinsHwnd%A_Index%
; Skip hidden windows by checking exStyle.
If !(exStyle & 0x100){
Continue
}
; Window is not hidden. Increase counter.
counter_of_none_hidden_windows := counter_of_none_hidden_windows+1
; Set flag.
titles_match := CurrentWinTitle = active_title
If (titles_match) {
window_index_to_switch_to := counter_of_none_hidden_windows+offset
break
}
}
; Find index of the window to switch to and do the actual switch
counter_of_none_hidden_windows := 0 ; Initiate counter for counting only the none-hidden windows.
Loop, % AllWinsHwnd
{
; From [1]: "Retrieves an 8-digit hexadecimal number representing the extended style of a window.".
; [1] : https://autohotkey.com/docs/commands/WinGet.htm
WinGet, exStyle, exStyle, % "ahk_id" AllWinsHwnd%A_Index%
; Skip hidden windows by checking exStyle.
If !(exStyle & 0x100){
Continue
}
; Window is not hidden. Increase counter.
counter_of_none_hidden_windows := counter_of_none_hidden_windows+1
; Set flag.
found_window_to_switch_to := counter_of_none_hidden_windows = window_index_to_switch_to
; Switch window.
If (found_window_to_switch_to) {
; Get title.
WinGetTitle, CurrentWinTitle, % "ahk_id " AllWinsHwnd%A_Index%
; Activate by title.
WinActivate, %CurrentWinTitle%
; Stop loop.
break
}
}
return ; Nothing to return
}
send {Alt down}{tab}
send {Alt up}
!{Tab} works to switch between windows if you add sleep before and after it.
Sleep 100
Send !{Tab}
Sleep 100
Please refer to this link: https://www.autohotkey.com/docs/Hotkeys.htm#alttab
To cancel the Alt-Tab menu without activating the selected window, press or send Esc. In the following example, you would hold the left Ctrl and press CapsLock to display the menu and advance forward in it. Then you would release the left Ctrl to activate the selected window, or press the mouse wheel to cancel. Define the AltTabWindow window group as shown below before running this example.
LCtrl & CapsLock::AltTab
#IfWinExist ahk_group AltTabWindow ; Indicates that the alt-tab menu is present on the screen.
MButton::Send {Blind}{Escape} ; The * prefix allows it to fire whether or not Alt is held down.
#If
I've modified the example from the help page on this found here: https://www.autohotkey.com/docs/Hotkeys.htm#AltTabDetail
This was mainly to remap the Windows+Tab key to the Alt+Tab key in this example.
It opens the task view and waits for the user to click, escape or enter. The example from the help page has the alt key getting stuck for me so I changed it to work a little better.
Please let me know if this works for you all.
; Override the Left Win key and tab to Alt + Tab
; Help found here:
; https://www.autohotkey.com/docs/Hotkeys.htm#AltTabDetail
; #IfWinExist ahk_group AltTabWindow
#NoEnv
#SingleInstance force
SendMode Input
LWin & Tab::Send {Alt down}{tab} ; Asterisk is required in this case.
!LButton::
{
Click
Send {Alt up} ; Release the Alt key, which activates the selected window.
}
!Enter::
{
Send {Alt up} ; Release the Alt key, which activates the selected window.
}
~*Esc::
{
Send {Alt up} ; When the menu is cancelled, release the Alt key automatically.
;*Esc::Send {Esc}{Alt up} ; Without tilde (~), Escape would need to be sent.
}
I got ALT TAB to work with F1
By pressing F1 you can switch to the last window
While F1 is kept pressed you can move around with arrow keys or tab to select the window you need.
Code:
`F1::
Send, {ALT DOWN}{TAB}{TAB UP} ; If F1 is down it invokes the menu for switching windows.
KeyWait, F1 ; Show menu for switching windows by keeping ALT down until user physically releases F1.
Send, {ALT UP} ; If F1 is released release ALT key
return`
Documentation links
KeyWait
KeyList
I think this question was meant to be a simple request of: how to alt tab in Win10 using AHK, since win10 changed things up? -> I found the most simple solution as shown below... the code makes it necessary to keep the alt key down while the Win10 emu is open - then use the arrow keys an additional number of tabs (if you need three alt tabs, then it's "alt tab, then right 2", see?
macro key name::
{
Sleep 100
Send, ^c
Sleep 1000
Send, {alt down}{tab}
Sleep 400
Send, {right 2}{alt up}
Sleep 400
Send, ^v
Sleep 400
}
So just play with this snip in your code and you can jump passed the 'next' window(s) open.
Rossman

SendEvent ^{ins} isn't copying content to the clipboard

!c::
file_name = footnote.ini
restore_original_clipBoard := clipboard
clipboard =
KeyWait, Alt
KeyWait, c ;small c
BlockInput, on
SendEvent, ^{ins} ;^c doesn't work
ClipWait, 2 ; Wait for the clipboard to contain text.
if ErrorLevel
{
MsgBox Failed to save the selection: %clipboard%
exit
}
BlockInput, off
save_selection := clipboard
Problem: Despite a selection being made, Sendevent ^{ins} does not save it to the clipboard. Sometimes I have to repeat my hotkey, alt + c several times before the selection is being copied to the clipboard. The KeyWait should ensure me that only ^{ins} is being processed without any additional keys. What am I doing wrong here?
UPDATE
One of the ways I tried to force copy a selection to the clipboard was by using a while loop. I got it to work through the post: Looping clipboard and errorlevel evaluation not working as expected
PROBLEM
When I make a selection and press alt + c it sometimes gets stuck in the infinite loop that I implemented. But as you can see from that code:
clipboard := ""
while( StrLen(clipboard) < 1 )
{
Send, ^{ins}
Sleep, 50
}
MsgBox % ClipBoard
The infinite loop incorporates within itself a continues resending of ^{ins}. For some reason, my selection is not being recognized as a selection. Whilst it is in that infinite loop, I try to reselect the text. It then recognizes it instantly and copies my selection to the clipboard. But alas! The selection is incomplete because it goes so quick.
This problem is not always like that. Sometimes it recognizes the selection first spot on! So sometimes it copies my selection to my clipboard sometimes not. When it does not, then a resending of a ^{ins} does not seem to work. I do not want to the user to reselect his selection. Is that possible to do?
Send {Ctrl Down}{c}{Ctrl Up}
That presses Ctrl+C, you must do it instantly as one command apposed to pressing Ctrl waiting then pressing C.
Never seen Insert key used for copying text.
Also found this sends Ctrl+C as well.
Send, ^c
To send insert key use
{Insert}
This way works for me:
!vk43:: ; alt+c
clipContent:=ClipboardAll
Clipboard:=""
SendEvent, ^{Ins}
ClipWait, .75
MsgBox, % 262 . (ErrorLevel ? 160:208)
, % ErrorLevel ? "Period expired:":"Result:"
, % ErrorLevel ? "Failed to save the selection.":Clipboard
, % (ErrorLevel ? 0:2) . .5
Clipboard:=clipContent
KeyWait, vk43
Return
!vk43:: ; alt+c
clipContent:=ClipboardAll ; backup clipboard content (if needed)
Clipboard:="" ; no comment :)
Loop
{
SendEvent, ^{Ins}
ClipWait, .75 ; means 750ms, same if write 0.75
; assign value of "ErrorLevel" an variable for further usage
errLvl:=ErrorLevel
; monitoring current action (for debugging purpose only)
TrayTip, % "attempt: #"A_Index
, % """ErrorLevel"" of ""ClipWait"" command is: "errLvl
}
; here you can set the condition of ending the cycle: either...
; ...variable errLvl has not a true value,...
; ...or the number of attempts is equal 5
Until, Not errLvl Or A_Index=5
; value of each field of the command "MsgBox"...
; ...are set depending on the value of errLvl variable...
; ...using a ternary expression
; means if errLvl is a true, "options" field is 262160
MsgBox, % 262 . (errLvl ? 160:208)
; means that "title" has a couple variants
, % errLvl ? "Period expired:":"Result:"
; means that "text" has a couple variants
, % errLvl ? "Failed to save the selection.":Clipboard
; means if errLvl is a true, "timeout" field is 0.5 (500ms)
, % (errLvl ? 0:2) . .5
/* same that and above:
IfEqual, errLvl, % True, MsgBox, 262160
, % "Period expired:"
, % "Failed to save the selection."
, 0.5
Else MsgBox, 262208, % "Result:", % Clipboard, 2.5
*/
TrayTip ; remove "TrayTip" (for debugging purpose only)
; save an positive result (if needed)
IfEqual, errLvl, 0, Sleep, -1, someVar:=Clipboard
; return a temporarily saved data into clipboard (if needed)
Clipboard:=clipContent
KeyWait, % "vk43"
Return
From my experience whenever keystrokes are not recognized reliably it's due to either the system or the targeted program not keeping up with the speed at which those keys are sent.
For SendEvent you could try something like SetKeyDelay, 1000, 1000 and see if this improves things. The other option would be to send explicit down and up keys with intermittent sleep calls as outlined in this answer.

Shift Key Training Wheels and Shift Parenthesis Remap

I'm looking to use AutoHotKey to modify the functionality of my shift keys. The functionality is described in Steve Losh's Blog entry here. Specifically, I'd like my shift keys to do the following:
If LShift or RShift is pressed and released in under 300 ms with no other keys being pressed in between, send ( or ), respectively.
If LShift and RShift are "rolled" together (press LShift, press RShift, release LShift, release RShift, etc.) in under 300ms, send () or )(.
If a shift key is used improperly (LShift and S, RShift and K, etc.) then nothing happens.
I've been having issues with the 300ms requirement and the "rolling" functionality. Specifically, I'm having issues with only being able to detect when the key is released due to the hotkey combos such as:
LShift & 0:: return
This is where I'm at so far:
LShift::
Send {LShift Down}
KeyWait, LShift
Send {LShift Up}
if (A_TimeSinceThisHotkey < 300){
if (A_PriorKey = "LShift")
{
Send {)}
}
}
return
I don't see a reason to use a 300 ms timeout anyway, it seems unreliable and unnecessary.
Have a look at this commented code, it is short and efficient, and seems to meet all of your requirements:
LShift::Send, (
RShift::Send, )
LShift & RShift:: Send, ()
RShift & LShift:: Send, )(
/* Put your unwanted combinations here
* and let them do nothing
*/
LShift & q::return
RShift & y::return
Edit:
Since LShift and RShift already are prefix hotkeys, I left out the trick described here.
MCL's answer is close but when I tested it I found that shift-clicking didn't select text. Here's a version with a passthrough to allow shift-clicking to work.
;shift to parens
LShift::Send, (
RShift::Send, )
LShift & RShift:: Send, ()
RShift & LShift:: Send, )(
;passthrough for shift-click
LShift & LButton::
Send, {LShift Down}{LButton}
Send, {LShift Up}
RShift & LButton::
Send, {RShift Down}{LButton}
Send, {RShift Up}
I don't think the 300ms timeout is possible without either very deep understanding of autohotkey's implementation or actual modification to autohotkey. When I tried to get it to work (using http://www.autohotkey.com/board/topic/98742-remapping-shift-key/) I found that A_PriorHotkey was not consistently populated. I don't think that variable was meant to work with modifier keys this way.
I felt compelled to figure this one out. Here you go!
I basically created a hotkey for every Shift + Letter key combination in order to send the correct key case and also set the Abort value. The Abort value is then referenced whenever one of the Shift keys is pressed in order to determine whether or not to send the corresponding ( or ).
The "Rolling" was accomplished by creating a Hotkey for LShift + RShift (and the opposite). It then looks to see which key is released first to determine () or )(.
Accept if this was what you were looking for!
Loop 26
{
Hotkey, % "~LShift & " Chr(A_Index+96), LetterKey ; Hotkeys for A-Z
Hotkey, % "~RShift & " Chr(A_Index+96), LetterKey ; Hotkeys for A-Z
}
Return
RShift::
LShift::
Abort := 0
keyDown := A_TickCount
Keywait, % A_ThisHotkey
duration := A_TickCount - keyDown
If (duration < 200) and (Abort = 0)
SendInput % (A_ThisHotkey = "LShift") ? "(" : ")"
Send {LShift Up}
Return
RShift & LShift::
LShift & RShift::
Keywait, LShift
If GetKeyState("RShift", "P")
{
Keywait, RShift
Send ()
}
Else
Send )(
Return
LetterKey:
SendInput, % "+" SubStr(A_ThisHotKey, 0, 1)
Abort := 1
Return
EDIT:
Hmm, I seem to be having the same problem as you. I always get a duration of 0 due to the hotkeys.
I found and modified this script on the AutoHotKey Forums. (The original script was prone to type "K(" when you meant to type "K" if you type too quickly, so I've modified it so that shouldn't happen any more)
$LShift Up::send, % getkeystate("LShift") ? "{LShift Up}" : ""
$RShift Up::send, % getkeystate("RShift") ? "{RShift Up}" : ""
~$LShift::
KeyWait, LShift, T0.1 ; wait 100ms to check shift state
if (A_PriorKey = "LShift")
{
send, % getkeystate("LShift") ? "{LShift Down}" : "("
}
KeyWait, LShift
return
~$RShift::
KeyWait, RShift, T0.1 ; wait 100ms to check shift state
if (A_PriorKey = "RShift")
{
send, % getkeystate("RShift") ? "{RShift Down}" : ")"
}
KeyWait, RShift
return