リマップ

イントロダクション

キーリマップとはその名の通りキーの置き換えを行うもので、「キーAとキーBを入れ替える」といった用途に利用する。

AutoHotkeyの機能は純然たるリマップではないが、ウィンドウ毎にリマップ定義を行えたりするなどのメリットがある。 純リマップであるレジストリのスキャンコードマップを変更してリマップを行う事との違い、およびメリット・デメリットは後述する。

なおリマップ機能には以下の制限事項がある。あらかじめ注意されたし。

  • Win 9x/Me では利用できない(ホットキーSend コマンドで代用する)。
  • ジョイスティックでの利用は出来ない(同上)。

リマップの定義方法

置換元キー::置換先キーという行を記述すると、置換元キーに置換先キーを割り当てることができる。
例えば、以下のようにすると、 Aキーを押したときに bが入力されるようになる。

a::b

このとき、Shift+AはShift+Bに、Ctrl+AはCtrl+Bにというように、あらゆる状態でキーの変換が有効になる。

以下は、二つのキーを入れ替えになる。

a::b
b::a

以下の例では、Shiftを押しながらAを押したときは、 Bが入力される。

+a::b

置換先キーには1キーで入力が出来ないものも指定できる。
以下はCapsLockの状態に関わらず大文字Bが出力できる。

a::B

上記以外でも、置換元キー、置換先キーには、 ^cのような修飾キーとの組み合わせや、マウスボタン、 vkXXscYYYのようなキーコードも指定可能。

キー名は キーリスト のものが利用できる。

ただし、WheelUp/WheelDownは使用できない。また、 a & bのようなコンビネーションキーも使用できない。
下記の例では、X2ボタンを押すとCtrl+Cが、Shift+X2ボタンではCtrl+Shift+Cが入力されることになる。

XButton2::^c

Remarks

#IfWinActive等を使うことで、ホットキー同様に特定のウィンドウのみにリマップを適応できる。

; メモ帳でのみ 'a' を押すと 'b' が出力する
#IfWinActive ahk_class Notepad
a::b
#IfWinActive

リマップはホットキーに比べて以下の点で優れる

  • CtrlやShiftなど修飾キーが同時に押されているときに、置換元キーを押すと「修飾キー+置換先キー」を発行するようになる。(例) 「a::b」としたとき Ctrl+A を押すと Ctrl+B が発行される)
  • 通常キー同様に、CapsLock状態がリマップ後のキーに反映される。
  • 置換元キーを押し下げている間、置換後のキーが押し下げられていることになる。
  • 置換元がキーの場合、押し下げ中はキーリピートが発生する。(マウスボタンではしない)

リマップによって発行されたキーで通常のホットキーの発動が可能。 しかし、マウスボタンやフックを使ったキーのホットキーを発動させることはできない。 (ホットキーがどの種類であるかは ListHotkeysコマンド、またはAutoHotkeyのメインウィンドウの「メニュー>View>Hotkeys and their methods」で確認できる)

置換先キーの出力方式は、AutoExecuteセクションの終了時点でSendModeで設定されていた方式が使用される。
ただし、Playモードでは一部のキーが正常に動作しないので、なるべくInputモードかEventモード(デフォルト)を使用すること。

リマップはホットキーに変換される

リマップはスクリプトの実行時にはホットキーに変換される。例えば「a::b」は以下のようなものになる。

*a::
SetKeyDelay -1   ; 置換先がマウスの場合は SetMouseDelayになる
Send {Blind}{b DownTemp}  ; "DownTemp"は"Down"に似ているが押下中はキーリピートを送る
return
*a up::
SetKeyDelay -1  ; PressDurationパラメタを指定しない理由は後述
Send {Blind}{b Up}
return

しかし上記のホットキーは以下の状況で変化する

  1. 置換元キーがLCtrlで置換先キーがAltのときは、「Send {Blind}{LAlt DownTemp}」ではなく「Send {Blind}{LCtrl Up}{LAlt DownTemp}」となる。 置換元キーがRCtrlでも同様(ただし{RCtrl Up})となる。
  2. キーボードのキーにマウスボタンを割り当てた時(RCtrl::RButton など)、 SetKeyDelay に変えて SetMouseDelay を利用する。 また Down 時のホットキーは以下のようになる
    *RCtrl::
    SetMouseDelay -1
    if not GetKeyState("RButton")  ; マウスボタンが押されていない場合のみ
        Send {Blind}{RButton DownTemp}
    return
    

備考: このケースでは SetKeyDelay の第2パラメタの PressDuration を省略している。 これは PressDuration は Upのみ、Downのみの場合には適応されないためである。 しかし、Shift,Ctrl,Alt,Winの修飾キーの影響をうけるの。 従って、Auto-executeセクションで設定した PressDuration が全てのリマップに適応されることになる。

コンビネーションキーも直接リマップは出来ない(a & c::bは無効となる)。 この場合は上に述べたリマップをホットキーに変換する例の、 *a::a & c:: に、 *a up::with a & c up:: に 置換することで代替できる。

上述のように、リマップはホットキーになるので、Suspendコマンドによってリマップも通常のホットキーと同様に無効になる。 従って、以下のようにすればリマップを個別に無効化することもできる。

Hotkey, *a, off
Hotkey, *a up, off

Alt+Tab問題

リマップ機能を用いて、あるキー(ここでは仮にXとする)に Alt キーを割り当てたとき、 Alt+Tab の代わりに X+Tab を押してタスク切り替えようとしてもうまくいかない。 解決策としてホットキー定義「Tab::Send {Blind}{Tab}」を加えると動作するようになるが、 本来の Alt+Tab のほうがきちんと動作しなくなる。

リマップにおけるキー指定

置換元キーとして キーリストにあるキーやマウスボタン名だけでなく、 仮想キーコード(VKnn) や スキャンコード(Scnnn) も利用できる。 これは、スキャンコードが後に付く仮想キーコード(VKnnScnnn)を除き、置換先キーでも同様。 例えば、多くのキーボードで c01e::vk42sc030a::b は同じになる。

リマップでなく単にキーを無効化したい場合は、ホットキー機能を用いて何もさせない F1::Return のようにする。

  • マウスホイールを置換元にすることは出来ない(WheelUp, WheelDown, WheelLeft, WheelRight)
  • 同名コマンドがあるキーや、スクリプトの特殊文字はそのままでは置換先キーとして指定できない。
    • Pause, Break, Return は同名コマンドがあり
    • 中括弧{}, パーセント%
    この場合キーコード指定で、x::+sc01Ay::+sc01B のようにする。

レジストリのスキャンコードマップを変更してリマップを行う

レジストリにはキーボードからのキー入力信号を置き換えるスキャンコードマップというエントリがある。 これは実際に入力されたキー入力信号を他のキー信号に置き換える設定を格納している。 キー入力があるとこの設定を用いてキーの置き換えを行い、 OSを含む全てのアプリケーションは置き換え後のキーを実際のキー入力として扱う。 なおデフォルトでこのエントリは空(リマップ無し)になっている。

一方、AutoHotkeyのリマップ機能はフック機能を用いてリマップ実現している。 キー入力を各ウィンドウに通知する直前に捕え、リマップ対象のキーである場合キー入力を捨てて、 新たなキー入力イベントを発生させるという方法を採っている。

レジストリでのリマップを利用するメリットとデメリット:

メリット
  • AutoHotkeyでのリマップ機能に比べてリマップに特化していて効果的である。 多くのゲームに対して有効であり、Alt+Tab問題も生じない。
  • レジストリ値の書き換えだけなのでソフトウェアの常駐を必要としない。 スキャンコードマップの書き換えツールとして KeySwapChangeKey などがあるが、 これらのソフトは書き換え時にだけ起動が必要で常駐しない。
デメリット
  • レジストリによるリマップは半永久的で、変更を適応するには再起動(HKLMの場合)またはログオン/オフ(HKCUの場合)が必要になる。
  • リマップは常にグローバルで、AHKでやるようにウィンドウの種類毎に切り替えるといったことは不可能。
  • 完全なキー置き換えなので、修飾キーの同時押しは出来ない(CapsLockオフ時にaを押したらBを出力する等)。
  • キーボードのみでマウスには使えない
  • NT系のみの機能である

日本語キーボード固有の問題にレジストリを用いたリマップで対応する

通常の日本語キーボードには 単体で CapsLock を行うキーがない。 このため CapsLockCtrl の入れ替えを AutoHotkey 単体で行うことができない。 このような場合、上述のスキャンコードマップを入れ替えることで対応するのが確実である。

なお、OSの機能でリマップしたキーをAutoHotkeyでリマップやホットキーを割り当てることも可能である。

Comments