AutoHotKey で正常に扱えないキーとその対策

AutoHotKey で正常に扱えないキーは (おそらく) 以下の 3 つです。

- 半角/全角
- CapsLock・英数
- カタカナ・ひらがな

共通点は以下の通りです。

- IME の機能が割り当てられている
- トグル系の機能を持つ

NumLock・ScrollLock・無変換・変換は通常のキーと同じ挙動をします。

# 1. キーの挙動

AutoHotKey の Key history でキーイベントを確認します。

## 1.1. 一般的なキーの挙動

一般的なキーでは、ある仮想キーコード VK とスキャンコード SC に関して、押し下げ・押し上げのキーイベントが発生します。

```text:k&nbsp;と&nbsp;LControl
VK    SC   Up/Dn  Key

4B    025    d    k
4B    025    u    k

A2    01D    d    LControl
A2    01D    u    LControl
```

## 1.2. 半角/全角キーの挙動

スキャンコード SC は `029` で共通ですが、異なる仮想キーコード VK (`F3` / `F4`) に対してずっと長押しされているように扱われ、半角/全角キーを「押し**下げ**」たときにキーイベント「押し**上げ**」「押し**下げ**」の両方が発生します。

AutoHotKey においてキー名 `sc029` でイベントを拾えますが、上記の挙動から、単純にキーをリマップすると常にそのキーが長押しされているような動作をします。

```text:英数&nbsp;->&nbsp;ひらがな
VK    SC   Up/Dn  Key

F3    029    u    not found
F4    029    d    not found
```

```text:ひらがな&nbsp;->&nbsp;英数
VK    SC   Up/Dn  Key

F4    029    u    not found
F3    029    d    not found
```

## 1.3. 英数キーの挙動

"CapsLock" の方が目につきやすいですが、それは「Shift キーを押していたら CapsLocck として機能する」という意味で、Shift キーが押されていないときは「英数キー」として動作します。

半角/全角キーと同様に、単純にキーをリマップすると常にそのキーが長押し状態になってしまうのと、こちらはそもそも押し下げと押し上げの対応もとられていません。

```text:英数&nbsp;->&nbsp;ひらがな
VK    SC   Up/Dn  Key

F0    03A    d    not found
```

```text:ひらがな&nbsp;->&nbsp;英数
VK    SC   Up/Dn  Key

F2    03A    u    not found
F0    03A    d    not found
```

Shift キーと同時に押すと「CapsLock キー」として動作します (※後述) 。

Ctrl や Alt と同時に押した場合は単に英数キーと修飾キーの同時押しとして認識されます。
その場合、英数とひらがなは切り替えられません (IME による？) 。

```text:英数&nbsp;->&nbsp;英数
VK    SC   Up/Dn  Key

A2    01D    d    LControl
F0    03A    d    not found
A2    01D    u    LControl

A4    038    d    LAlt
F0    03A    d    not found
A4    038    u    LAlt
```

```text:ひらがな&nbsp;->&nbsp;ひらがな
VK    SC   Up/Dn  Key

A2    01D    d    LControl
F2    03A    u    not found
F0    03A    d    not found
A2    01D    u    LControl

A4    038    d    LAlt
F2    03A    u    not found
F0    03A    d    not found
A4    038    u    LAlt
```

## 1.4. CapsLock (Shift+英数) キーの挙動

手持ちのキーボードでは、Shift キーを押して英数キーを CapsLock キーとして機能させるときは通常のキーと同じように動作しました (キーボードや IME による？) 。

```text:on/off&nbsp;共通
VK    SC   Up/Dn  Key

A0    02A    d    LShift
14    03A    d    CapsLock
14    03A    u    CapsLock
A0    02A    u    LShift
```

## 1.5. カタカナ・ひらがなキーの挙動

半角/全角キーや英数キーと似た挙動で、単にキーをリマップすると常にそのキーが長押し状態になります。

```text:英数&nbsp;->&nbsp;ひらがな
VK    SC   Up/Dn  Key

F0    070    u    not found
F2    070    d    not found
```

```text:ひらがな&nbsp;->&nbsp;ひらがな
VK    SC   Up/Dn  Key

F2    070    d    not found
```

```text:英数&nbsp;->&nbsp;カタカナ
VK    SC   Up/Dn  Key

A0    02A    d    LShift
F2    070    u    not found
F1    070    d    not found
A0    02A    u    LShift
```

```text:カタカナ&nbsp;->&nbsp;カタカナ
VK    SC   Up/Dn  Key

A0    02A    d    LShift
F1    070    d    not found
A0    02A    u    LShift
```

# 2. AutoHotKey で正常に扱えないキーの対策

AutoHotKey でキーイベントを補足するより前に、正常に扱えないキー (「半角/全角」「CapsLock・英数」「カタカナ・ひらがな」) を正常に使えるキーに一旦置き換えます。

そのための一般的な方法として、Windows レジストリ内の「Keyboard Layout」「Scancode Map」の値を変更 (※要管理者権限・要再起動) し、OS レベルでキーを置き換える方法が使われます。
ただし、値がバイナリで扱われていて手動で編集するのは少しむずかしいため、「[Change Key](https://forest.watch.impress.co.jp/library/software/changekey/)」(フリーソフト) 等のソフトウェアが使われることが多いです (※その場合も要管理者権限・要再起動) 。

参考「[Scancode Mapによるキー割り当ての変更 - Tepp's note](https://tepp91.github.io/contents/misc/remap-keyboard-with-scancode-map.html)」
参考「[「Change Key」非常駐型でフリーのキー配置変更ソフト - 窓の杜](https://forest.watch.impress.co.jp/library/software/changekey/)」

レジストリ変更や Change Key では OS レベルでマップできますが単純な置換しかできず、AutoHotKey は高度な機能割り当てができますがアプリケーションレベルでしか置換できないため、併用することでかなり広い範囲のキーと機能を割り当てることができます。

Windows 上で扱えるキーかつ一般的なキーボードであまり使用されないキーとして、「ファンクションキー F13 ～ F24」に割り当てられることが多いです。
(キーボードやアプリケーションによってはファンクションキー F13 ～ F24 を必要とする場合もなくはないため、臨機応変に対応してください。)

参考「[Virtual-Key コード (Winuser. h) - Win32 apps | Microsoft Docs](https://docs.microsoft.com/ja-jp/windows/win32/inputdev/virtual-key-codes)」