1
votes

I'm trying to achieve a visual-studio-like chaining of hotkeys for something at work.

Basically, when I hit Ctrl+Alt+F, I want to enter a sort of "Format mode" The next key I press will determine what text is injected. I'd like "Format mode" to cease as soon as one of the inner hotkeys is pressed. However I'd also like the option to have to cancel it manually just in case.

I've tried searching for the chaining of hotkeys, as well as attempted the following, rather naive code:

;
;; Format Mode
;
^+f::

    ; Bold
    b::
        Send "<b></b>"
        Send {Left 4}
    return

    ; Italics
    i::
        Send "<i></i>"
        Send {Left 4}
    return

    ; Bulleted List
    u::
        Send "<u></u>"
        Send {Left 4}
    return

    ; Numbered List
    o::
        Send "<o></o>"
        Send {Left 4}
    return

    ; List Item
    l::
        Send "<li></li>"
        Send {Left 4}
    return

    ; Line Break
    r::
        Send "<br/>"
    return

return

I was pretty sure this wasn't going to work, but I figured I'd give it a shot so as to not make y'all think I'm just asking to be spoon fed.

I haven't worked with AHK a whole lot, but I've used it enough to be able to accomplish some stuff both at home and at work, but it's suuuuper messy - just as some background as to my experience with AHK.

2

2 Answers

2
votes

With the #if command you are able to Switch/Toggle between action1/Enable and action2/Disable with the same Hotkeys.

You can test it out in Notepad. if you then type the key t

type Ctrl+Shift+f keys to toggle between two the same hotkeys.

Note: For your Hotkeys You Can Change the Code a Little Bit! you can Place all your hotkeys into #if Mode1 and then use no hotkeys into #if Mode2

Example1.ahk

; [+ = Shift] [! = Alt] [^ = Ctrl] [# = Win] 
#SingleInstance force

a := 1 

#If mode1 ; All hotkeys below this line will only work if mode1 is TRUE or 1
    t::
    send 1
    ; Here you can put your first hotkey code 
    return 

   ; Here you can Place All your Hotkeys       
#If

#If mode2 ; All hotkeys below this line will only work if mode2 is TRUE or 1
    t::
    send 2
    ; And here you can put your second hotkey code 
    return        
#If

; toggle between [t::1] and [t::2]
;a = 1   => t::1
;a = 2   => t::2

;type Ctrl+Shift+f keys to toggle between two the same hotkeys
;you can test it out in notepad - if you then type the key t
^+f::  
if (a=1)
{
mode1 = 1
mode2 = 0
a := 2
}else{
mode1 = 0
mode2 = 1
a := 1
}
return

esc::exitapp 
2
votes

Using #If is a good choice, as stevecody showed. Below is another solution that may work for you. It uses your ^+f hotkey to activate the specialty hotkeys. The specialty hotkeys will also deactivate themselves upon use. f1 is your option to cancel it manually.

^+f::
Hotkey , b , l_Bold , On
Hotkey , i , l_Italics , On
Hotkey , l , l_ListItem , On
Return

f1::
Hotkey , b , l_Bold , Off
Hotkey , i , l_Italics , Off
Hotkey , l , l_ListItem , Off
Return

l_Bold:
Hotkey , b , l_Bold , Off
Send , <b></b>{left 4}
Return
l_Italics:
Hotkey , i , l_Italics , Off
Send , <i></i>{left 4}
Return
l_Italics:
Hotkey , l , l_ListItem , Off
Send , <li></li>{left 5}
Return

Something else I was looking at, but it doesn't quite work right, is below. The problem is that it will still send the specialty key and you end up with something like <i>i</i> instead of <i></i>.

f1::
KeyBdHook := DllCall(   "SetWindowsHookEx" , "int" , 13  , "uint" , RegisterCallback( "KeyBdProc" ) , "uint" , 0 , "uint" , 0 )
input
Return

KeyBdProc( nCode , wParam , lParam )
{
    global KeyBdHook
    Critical
    If ( wParam = 0x100 )
    {
        DllCall( "UnhookWindowsHookEx" , "ptr" , KeyBdHook )
        sKey := GetKeyName( Format( "vk{:x}" , NumGet( lParam + 0 , 0 , "int" ) ) )
        If ( sKey = "i" )
            Send , <i></i>{left 4}
        Else
            MsgBox , You pressed %sKey%
    }
}