[AutoHotKey]1つのキーで3つの機能!長押しや2度押しに機能を割り当てる

このページを見ているあなたは貪欲です。何しろ「キーの長押しや2度押しにまで機能を割り当てたい」って言うんだもん。

マジで言ってんの? むしろ何個ショートカットキーあれば満足なの?

…分かりましたやん。やりますやん!

ということで今回はKeyWaitErrorLevelを使って、キーの長押しや2度押しに機能を割り当てる方法をご紹介します。

作ってみる

まずは長押し対応のコード。

F15::                             ;F15キーを押した時
KeyWait, F15, T0.3                ;F15キーが離されるのを0.3秒待つ
If (ErrorLevel){                  ;ErrorLevelが1であれば、
    Send,おっす。オラ悟空             ;文字列1を出力
    KeyWait, F15                  ;F15が離されるのを待つ
    return
}else{                            ;そうでなければ、
    Send,はじめまして。私の名前は悟空です。    ;文字列2を出力
    KeyWait, F15                  ;F15が離されるのを待つ
    return
}

トリガーにするキーは何でもかまいません。僕はカタカナ/ひらがなF15に設定しているので、このキーを押したときの動作です。

コードを実行すると、キーを長押しした場合「おっす。オラ悟空」が出力され、普通に短押しした場合は「はじめまして…」が出力されます。

(CapsLock半角/全角などへの機能割り当てが上手く行かないという方や、F15キーって何やねんという方は一度読んでみてください)

[Autohotkey]半角/全角キーやCapsLockが正常に扱えない理由と対策
AutoHotKeyで半角/全角キーやCapsLockは正常に扱えません。その理由と対策とは?

ここで使用しているのは「KeyWait」と「ErrorLevel」です。詳しく見ていきましょう。

KeyWaitの仕様

KeyWait, KeyName [, Options]
;「KeyName」で指定したキーが離されるのを待つ(Option未設定時)

引数

KeyWaitの引数は最低1つ、最大で4つ。

仮引数名意味
KeyName (必須)指定キー名
OptionsD離されるのではなく、押されるのを待つ
Tn(秒)待つ秒数をn秒で指定する(ミリ秒は小数)
L論理的判定を使用する

この中の「D」と「L」に関しては、以下で解説していきます。

Dオプション

KeyWaitは基本的にキーが「離される」のを待つコマンドですが、Dオプションはそれを「押される」のを待つコマンドに変更します。

これを指定することで「あるキーの2度押しを検知する」ことや「あるキーを長押しした後、他のキーが押された場合のみ機能を発動する」といったことも可能になります。例を見てみましょう。

F15::
KeyWait, F15, T0.3
If (ErrorLevel){
    KeyWait, F15, D, T0.3     ;もう一度F15が押されるのを0.3秒待つ
    KeyWait, vk1D, D          ;無変換キーが押されるのを待つ
    Send,おっす。オラ悟空
    KeyWait, vk1D
    return
}

4行目ではF15もう一度押されるのを待機しています。これを使うとキーの2度押し、3度押しに対応したホットキーを作成することができます。

その次の行で無変換押されるまで待機しているため、このコードではF15単体を長押ししただけでは何も起こりません。「長押し→無変換キーが押される」というプロセスを経て初めて文字が出力されます。

Lオプション

こちらはかなりややこしいので、動作の違いだけ説明しておきます。最悪読み飛ばしてもらってかまいません。

例えばq::F15と記述します。これは「Qを押すとF15を押したことにする」という命令です。しかし通常の場合、出力の直前(レジストリ)まではあくまで「Qが押された」という認識になります。そのため、下のコードではQを押しても機能は正常に発動しません。

q::F15

F15::
KeyWait, F15, T0.5
If (ErrorLevel){
    Send,おっす。オラ悟空
    KeyWait, F15
    return
}else{
    Send,はじめまして。私の名前は悟空です。
    KeyWait, F15
    return
}

最初のF15::だけは認識されますが、その後は必ずelse側の処理しか実行されません。なぜなら実際にF15キーは押されていないからです。押されていないものは離されようがありません。

そこでこのオプションを追加します。

q::F15

F15::
KeyWait, F15, T0.5, L        ;ここに追加
If (ErrorLevel){
    KeyWait, F15, L          ;ここにも追加
    Send,おっす。オラ悟空
    return
}else{
    KeyWait, F15, L          ;ここにも追加
    Send,はじめまして。私の名前は悟空です。
    return
}

論理的判定を使用することにより、AutoHotKeyで設定されたキーもKeyWaitに認識されるようになります。

動作しない場合:
スクリプトのどこかに「#UseHook」が記載されていると動作しません。確認してみましょう。

ErrorLevel

ErrorLevelは組み込み変数の1つであり、多くの場合、あるコマンドの成功/失敗の結果によって「0」か「1」が代入されます。殆どの場合0が成功、1が失敗です。

KeyWaitの場合、(Dオプションが無効であれば)あるキーが「離される」ことを期待するコマンドです。指定時間内に離す動作が行われた場合、ErrorLevelは0になります。

今回使用しているコードのIf (ErrorLevel)ではErrorLevelが1の場合、()内の式はTrueと判定され、Ifの条件が満たされるため、If文の処理内容が実行されます。

長押し/短押しの動作を逆転させる

もう一度コード全体を見てみましょう。ErrorLevelの部分に注目してください。

F15::                             ;F15キーを押した時
KeyWait, F15, T0.3                ;F15キーが離されるのを0.3秒待つ
If (ErrorLevel){                  ;ErrorLevelが1であれば、
    Send,おっす。オラ悟空             ;文字列1を出力
    KeyWait, F15                  ;F15が離されるのを待つ
    return
}else{                            ;そうでなければ、
    Send,はじめまして。私の名前は悟空です。    ;文字列2を出力
    KeyWait, F15                  ;F15が離されるのを待つ
    return
}

上記のif (ErrorLevel)はこんな記述でも同じ意味です。

If (ErrorLevel == 1)     ;ErrorLevelが1と等しければ…
If (ErrorLevel > 0)      ;ErrorLevelが0超過であれば…
If (ErrorLevel <> 0)     ;ErrorLevelが0でなければ…

このような記述の場合、長押ししたときにIf文内部の「おっす。オラ悟空」が出力されます。それではこれを「長押ししなかったとき」に変更するにはどうすればいいでしょう?

条件式が理解できていれば、動作を逆転させるのは簡単なことです。

If (ErrorLevel == 0)     ;ErrorLevelが0と等しければ…
If (ErrorLevel < 1)      ;ErrorLevelが1未満であれば…
If (!ErrorLevel)         ;ErrorLevelがFalseであれば…

こうすることで今度は長押ししなかったとき、If文内部の処理が実行されます。逆に長押しした場合、()内の結果はFalseとなり、else文に処理が引き継がれます。

まとめ

今回のまとめとして、キーの長押し/2度押し/短押しに対応したフォルダランチャを掲載しておきます。

このコードでは変数を使用しているので、トリガーキーを変更したい場合はキー指定と変数定義部分(2行目と3行目)だけ変更すれば、様々なキーに対応可能です。試してみてください。

[AutoHotKey]変数と関数を使って文字出力スクリプトを改良する
AutoHotKeyはただのキーボードカスタマイズソフトウェアではなく、スクリプ...
#UseHook                 ;UseHookをOnにした状態で使用
F15::
key := "F15"
KeyWait, %key%, T0.3
If(ErrorLevel){          ;長押しした場合
    Run, D:\Documents
    KeyWait, %key%
    return
}
KeyWait, %key%, D, T0.2
If(!ErrorLevel){         ;2度押しした場合
    Run, C:\Windows\System32\control.exe
    KeyWait, %key%
    return
}else{                   ;短押しした場合
    Run, C:\Program Files
    KeyWait, %key%
    return
}
タイトルとURLをコピーしました