このページを見ているあなたは貪欲です。何しろ「キーの長押しや2度押しにまで機能を割り当てたい」って言うんだもん。
マジで言ってんの? むしろ何個ショートカットキーあれば満足なの?
…分かりましたやん。やりますやん!
ということで今回はKeyWait
とErrorLevel
を使って、キーの長押しや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キーって何やねんという方は一度読んでみてください)
ここで使用しているのは「KeyWait」と「ErrorLevel」です。詳しく見ていきましょう。
KeyWaitの仕様
KeyWait, KeyName [, Options]
;「KeyName」で指定したキーが離されるのを待つ(Option未設定時)
引数
KeyWait
の引数は最低1つ、最大で4つ。
仮引数名 | 値 | 意味 |
---|---|---|
KeyName (必須) | 指定キー名 | |
Options | D | 離されるのではなく、押されるのを待つ |
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行目)だけ変更すれば、様々なキーに対応可能です。試してみてください。
#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
}