how to use an illegal character in AHK if InStr - autohotkey

I am capturing a user hotkey choice using GuiControl, hotkey then save to an ini. I then retrieve from the ini file the hotkey and use it in code. The only problem is the hotkeys with modifiers are saving as AHK shorthand, such as ^ for control, and when I try to use this in a script like so:
key = ^2
controlSend, ,%key%, ahk_id %id%
The game will only actually receive the "2". So I wrote a function to remove the ^ and replace with {LControl Down} and {LControl Up} respectively. However it will not work as the follow code throws and illegal character error in the 2nd line "IfInString, ^, input" but I also assume it will in the 4th line.
convertModifier(input) {
IfInString, ^, input
{
output := {LControl Down} . SubStr(input, InStr(input, ^)+1) . {LControl Up}
return output
}
}
I have tried using both ` and \ to escape the ^ but to no luck. Anyone have any ideas?
Thanks alot in advance I appreciate your time.

So Sidola was correct, I had the needle and stack the wrong way around in my IfInString. With a few other bugs worked out, this solution began to work like a dream.
Thanks Sidola.

Related

Autohotkey send {control}`

I have a very similar issue that I have been struggling with: I am trying to create a hotkey that will send this:
{control}or more specifically {left control down} {left control up}
(It is the backwards apostrophe symbol that usually sits on the same key as the ~ on most keyboards.)
Sending ^` doesn't seem to work.
any suggestions?

AHK Remapping Middle Mouse button to something else

After a month of trial and error, I've finally found a solution!
How to remap Middle mouse button something else?
If you don't have a three-button mouse, this is a must-have for blender (esp. Laptop)
I'm aware of "emulate 3 button mouse" in Preference>>Input.
But if you check that option then you won't be able to 'Select loop'
which uses ALT leftClick.
What if you could remap Mbutton to any other key you rarely use?
Yes you can!
Nice to see that you tried it yourself.
But here's how a context sensitive remap is actually done:
#IfWinActive ahk_class GHOST_WindowClass
LWin::MButton
#IfWinActive
This script will allow you to remap Mbutton with other key, such as LeftWin.
;~--------------------------------------------------------------------------------------
#IfWinActive ahk_class GHOST_WindowClass ; Blender's class
$LWin:: ; "$" this allows to send the trigger key in a working script***
loop
{
if getkeystate("LWin", "p") ; if a button is Physically held down by the user.
{
send, {MButton DOWN}
}
else
{
send, {MButton UP}
;~ MsgBox, Blender is active ; You dont need this.
return
}
}
#IfWinNotActive ahk_class GHOST_WindowClass ; Other than blender (I'm aware of other methods, but this works for me!)
Send, {LWin} ; *** like here I'm able to use Left Win again without triggering the script.
;~ MsgBox,Blender isnt active ;; You dont need this.
return
;~ --------------------------------------------------------------------------------------

How to make script to paste something in with AutoHotKey

I'm trying to make a script in AutoHotkey where, when I press Numpad 1, it presses the slash button, then pastes in some text, let's say "hello world", and then presses enter, but I can't figure out how. Can someone help?
Welcome to Stack Overflow.
In the future, try to at least show what you tried. All of this should be accomplished pretty easily by e.g. looking at the beginner tutorial combined with a quick Google search.
But well, here it is:
Numpad1::
Clipboard := "/hello word"
SendInput, ^v{Enter}
return
Numpad1:: creates the hotkey label.
Clipboard:= ... puts something into the clipboard.
SendInput sends input.
^v means Ctrl+v.
{Enter} means the enter key (could've possibly appended `n (line feed) into the string as well).
Return stops the hotkey label's code execution (in other words, ends the hotkey's code).
Assuming that you already have some text copied inside your clipboard before pressing the numpad1, the following code will work.
Numpad1::
Send, /^v ; ^ means ctrl key,
Send, {Enter}
return

How do I delete the current line using AutoHotkey?

Using an AutoHotkey script I'd like to set the keyboard command Ctrl+D to delete the current line in any active Windows app.
How?
^d::Send {Home}{ShiftDown}{End}{Right}{ShiftUp}{Del}
Might not work in all edge cases, but passes some very basic testing in Notepad. =~)
HaveSpacesuit's answer works but after using it for a while I realized it deletes the active line and sometimes re-positions the spacing of the line below.
This led me to rethink his solution. Instead of going from the front of the line to the back, I tried going from back to front. This solved the re-positioning issue.
SendInput {End}
SendInput +{Home}
SendInput ^+{Left}
SendInput {Delete}
There is still a small problem though. If the cursor is on an empty line, with more empty lines above, then all empty lines get deleted.
I don't know a key combo to replace ^+{Left} that doesn't have this behavior so I had to write a more comprehensive solution.
^d:: DeleteCurrentLine()
DeleteCurrentLine() {
SendInput {End}
SendInput +{Home}
If get_SelectedText() = "" {
; On an empty line.
SendInput {Delete}
} Else {
SendInput ^+{Left}
SendInput {Delete}
}
}
get_SelectedText() {
; See if selection can be captured without using the clipboard.
WinActive("A")
ControlGetFocus ctrl
ControlGet selectedText, Selected,, %ctrl%
;If not, use the clipboard as a fallback.
If (selectedText = "") {
originalClipboard := ClipboardAll ; Store current clipboard.
Clipboard := ""
SendInput ^c
ClipWait .2
selectedText := ClipBoard
ClipBoard := originalClipboard
}
Return selectedText
}
As far as I can tell this produces no unexpected behaviour.
However, be careful if you're using a clipboard manager as this script uses the clipboard, if necessary, as an intermediary to get the selected text. This will impact clipboard manager history.
In case you run into problems where you need different behaviours for different programs, you can "duplicate" your ^d command for specific programs like this:
SetTitleMatchMode, 2 ; Makes the #IfWinActive name searching flexible
^d::Send {Home}{ShiftDown}{End}{Right}{ShiftUp}{Del} ; Generic response to ^d.
#IfWinActive, Gmail ; Gmail specific response
^d::Send {Home}{ShiftDown}{End}{Right}{ShiftUp}{Del} ; adapt this line for gmail
#IfWinActive ; End of Gmail's specific response to ^d
#IfWinActive, Excel ; Excel specific response.
^d::Send {Home}{ShiftDown}{End}{Right}{ShiftUp}{Del} ; adapt this line for Excel
#IfWinActive ; End of Excel's specific response to ^d
This way your ^d command will work differently in Excel and Gmail.
I have a simple way to solve the repositioning issue. Without using the clipboard.
The repositioning issue is due to the need to handle 2 separate cases.
if there's existing text in a line,
we want to select them all, and delete the text (backspace 1)
and backspace one more time to delete the empty line (backspace 2)
if it's a blank line,
we want to delete the empty line (backspace 1)
To cater for both of above cases, I introduced a dummy character.
This will make sure BOTH cases will act the same way.
So doing backspace 2 times, will result in the same transformation each time.
Simply,
; enable delete line shortcut
^d::
Send {Home}
Send {Shift Down}{End}{Shift Up}
Send d
Send {Backspace 2}
Send {down}
return
Disadvantage with this approach,
the dummy character "d" will appear when you undo. Not a bad tradeoff since I don't undo delete lines very often.

Autohotkey - multiple scripts and different language issues

I use autohotkey to simplify copying, using Alt+W instead of Ctrl+C. However, I often switch my keyboard to a Hebrew layout, so the w key is now the ' key. Then the autohotkey script for w doesn't work.
I tried to write a second script into the same file but it doesn't get activated when I press Alt+' when I'm in the Hebrew layout. I'm not sure whether it's my syntax or something else, any ideas?
This is my code:
!w::
Send, {ctrl down}{a down}{a up}{c down}{c up}{ctrl up}
return
!'::
Send, {ctrl down}{a down}{a up}{c down}{c up}{ctrl up}
return
Thanks!
Catching Alt-' with the code you used works in other keyboard layouts (like the German layout) so your syntax looks OK to me.
To solve your problem I'd start the autohotkey help file.
Read "List of Keys, Mouse Buttons, and Joystick Controls"
where the section on "Special Keys" explains how to attempt
to catch inrecognized keys via the "keyboard hook".
Basically it describes how to find out the !' scancode which
you then can use as a hotkey alternative.
It is worth to try to use the virtual/scan codes of keys, instead names, This example uses the virtual code (vkXX):
;~ SetKeyDelay, keyDelay:=25, pressDuration:=25 ; details for SendEvent mode.
!vk57:: ; w/'/я... (en/he/ru...)
Send, {CtrlDown}{vk41}{vk43}{CtrlUp}
KeyWait, vk57
;~ Do something by release this key, if necessary...
Return