2014年8月13日 星期三

Autohotkey: Hotkey

前言

  • 從名稱可以知道Autohotkey的強項就是hot key,所謂熱鍵、快速鍵。控制滑鼠、視窗也是autohotkey的常用功能,用簡單的語法就能組合完成複雜的動作。
  • 百般task皆可由一個hot key引發,hot key可以是一個按鍵、多個按鍵、一串特定按鍵,可以是某個滑鼠鍵、多個滑鼠鍵,或是鍵盤搭配滑鼠鍵。可以指定在某些視窗才有快速鍵,或是某些視窗沒有快速鍵。

Hotkey

  • 之前的post提過Send可以模擬按出某個鍵(鍵盤、滑鼠),hotkey就是以這些鍵當作trigger。
  • Hotkey的第一行定義trigger的按鍵,send指令需要的大括號 { } 在hotkey要省略,然後後面加兩個冒號 :: 
  • 如果指令只有一行(包括以小括號包圍的段落文字),則可以寫在冒號右邊;如果是多行則最後要用return表示hotkey的結尾,開頭到結尾間可以有其他return,只要一遇到return這個hotkey就會結束。
  • Hotkey定義之後原本的功能會被覆蓋,例如LButton::,會讓autohotkey抓住滑鼠左鍵,但不做任何事,原本的滑鼠左鍵功能就消失了(請勿輕易嘗試XD)。
  • Hotkey之前可以有修飾符,調整hotkey的行為
    • *:例如^c::的hotkey只有ctrl + c才會trigger,多按一個鍵shift + ctrl + c則不會,但*^c::則只要ctrl + c有按到,多按shift或其他按鍵都還能trigger。
    • ~:原本hotkey的功能保留,不會被覆蓋
    • $:如果是^c::send ^c會出現無限迴圈,因為send出去的按鍵又trigger自己,$則避免出現迴圈。
    • UP:一般hotkey的trigger是在「按下」的階段發生(某些功能鍵除外),如果希望hotkey是在按鍵「放開」時發生,則在後面加一個up (不分大小寫)
      • ^c up::會在c放開時才執行。
      • 雖然只指定了^c up::,原本的^c還是會被覆蓋,所以如果要保留原本功能則用~^c up::或是另外再設定^c::send ^c(這時不需要加$)。
  • 組合鍵:只能組合兩個,舉例如下
    • a & b:::先按住a不要放掉,再按b可以觸發,有點像是按ctrl + c之類快速鍵的順序
    • 前面的按鍵a功能會被覆蓋,只按a不會做任何事,彌補的方法一樣是加一個~或是設定a::send a(兩者的行為不一樣,比較建議後者)
  • Suspend指令可以暫時停止所有的hotkey及hotstring(除了造成suspend的那個hotkey或hotstring),再一次suspend指令則會回復
  • Context-sensitive hotkey:以#IfWinActive包圍的hotkey,只有在指定的視窗會有作用
  • Hotkey本身就是一個label(不含兩個冒號::),可以用gosubgosub直接執行一個hotkey。例如$^c::可以用gosub $^c來執行,不用去按ctrl + c。

KeyWait

  • KeyWait可以設定微調hotkey,功能是等待某個按鍵放開或按下。
  • KeyWait, a 會等待按鍵a被放開
  • KeyWait, LButton, D 會等待滑鼠左鍵按下
  • KeyWait, Ctrl, T3 會等待Ctrl鍵放開,但只會等待3秒鐘,如果超過時間沒放開,ErrorLevel這個變數會是1;如果時間內放開,ErrorLevel會是0而且繼續執行script,不會等到3秒鐘。

GetKeyState

  • KeyWait一樣,GetKeyState也是輔助hotkey的小函數。有兩種形式的用法。
GetKeyState, OutputVar, KeyName [, Mode] 
  • 針對KeyName是按下還是放開,將OutputVar設定成 D U Mode中可以設定用哪一種方式判斷按鍵的狀態
    • Logical state:預設值,windows所認為的這個按鍵的狀態
    • Physical state:使用者是否按著這個按鍵,可能會和logical state不相同。如果script有mouse hook或keyboard hook,就能完全監測滑鼠/鍵盤,physical state可以當成等於logical state。
    • Toggle state:像是Caps Lock或Num Lock,如果用toggle state則是傳回目前的燈號,燈號亮的時候傳回 D ,反之傳回 U 。
KeyIsDown := GetKeyState("KeyName" [, "Mode"])
  • 用法類似,唯一的不同是剛才傳回 D 的地方現在會傳回 1 ,傳回 U 變成傳回 0

Double Click/Keyboard Event

  • 前面的hotkey都是按一下就會trigger,如果想要的hotkey是滑鼠左鍵「按兩下」,或是Esc鍵「按兩下」,可以加一行判斷式:
if (A_PriorHotkey = A_ThisHotkeky && A_TimeSincePriorHotkey < 500)
  • 白話翻譯就是「上一個trigger的hotkey和現在trigger的hotkey是同一個」而且「從上次trigger到現在的時間差小於500毫秒」,所以只要同一個鍵按兩下,時間差小於500毫秒,就會通過判斷式,如果不成立,就return回去。當然,500毫秒可以改成其他時間。
  • 如果hotkey需要按三次以上,建議可以用RapidHotkey()

Dynamic Hotkey

  • 之前的hotkey都是直接寫好在code裡,程式執行後就一直存在,如果要在程式執行時改變hotkey,就要用Hotkey指令。
Hotkey, KeyName [, Label, Options]
Hotkey, IfWinActive/Exist [, WinTitle, WinText]
  • KeyName是按鍵組合,就是上面提到的那些,Label則是要執行的區塊名稱(所以這部分還是要先寫在code裡)。
  • 多個hotkey可以共用同一個label,在區塊中可以用A_ThisHotkey變數區分是誰trigger的。
  • 按鍵組合一樣,但修飾符不一樣,或者在不同IfWinActive條件下的同樣按鍵組合,視為不同的hotkey。如果設定了重覆的hotkey,新的功能會覆蓋舊的功能。

1 則留言:

  1. 幽寒,您好:
    想利用Autohotkey製作姓名按鈕[林OO],當按此[林OO按鈕]時,
    即送出一個複合鍵訊習:Ctrl+A
    以銜接我用另一個按鍵精靈程式的腳本
    (已設定按鍵精靈收到 Ctrl+A 複合鍵訊號,即開始執行腳本)
    但試了許久都沒辦法成功
    內容如下:
    ----------------------
    Gui +AlwaysOnTop
    Gui, Show, x600 y400 h234 w369, 我的姓名
    Gui, Add, Button, x6 y43 w30 h30,林OO
    Button林OO:
    Send ;請問此行要如何設定才能送出 Ctrl+A
    return
    ---------------
    謝謝您!~

    回覆刪除