レジストリによるキー割り当ての変更
レジストリによるキー割り当ての変更は、キーボードドライバー側でなされるため、アプリケーションのキーボードの扱い方などに依存せず、確実に割り当てを変更できる。レジストリを触る自信がないユーザーは、設定をGUIでできるツールもあるので、それを探すといいだろう。ここでは、レジストリを操作する方法を解説する。なお、正式なMicrosoftの情報は以下のURLにある
●Keyboard and mouse class drivers(英語)
https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/keyboard-and-mouse-class-drivers#scan-code-mapper-for-keyboards
変更には、レジストリの以下のキーに、「Scancode Map」という「バイナリ値」の項目を作る。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout
そのときに設定するデータは、以下の表のようなものになる。論理的には、32bit(4バイト)ワードの組み合わせになっていて、最初の2ワード分(8バイト)は、すべてゼロになる。次に、マッピングデータと最後のヌルターミネーターの「マッピング数」が1ワード(4バイト)ある。その後ろにマッピングデータが入る。
マッピングデータ32bitは、上位16bitが置き換え元キー、下位16bitが置き換え先キーを示すWindowsスキャンコードだ。マッピングデータの例を以下の表に示す。
これを繰り返したあと、最後に32bitのヌルターミネータを置く。よく使われるコントロールキーとCaps Lockキーの入れ替えは以下の表のようになる。
この32bitデータの組み合わせをレジストリには、1バイト単位で16進数表現としてカンマで区切って並べていく。注意するのは、リトルエンディアンであるため、32bitの値の並びが下の桁からになる点だ。たとえば、16進数表現で「0x00000003」という値は、「03,00,00,00」とレジストリのデータ内で表現される。
これをScancode Mapに設定するには、前記レジストリキーをレジストリエディタで開き、右側の領域で右クリックメニューの「新規」→「バイナリ値」を選択する。

レジストリエディタでHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layoutを開き、右側の領域で右クリックメニューから「新規」→「バイナリ値」を選ぶ
すぐに名前が作られるので、これを「Scancode Map」とする。右側の領域にできた「Scancode Map」を右クリックして、メニューから「修正」を選ぶ。
バイナリ値の編集ダイアログで値のデータ欄にある先頭の00を選んで、前記のサンプルなら、最下行にあるように「000000000000030000003A001D001D003A0000000000」と入れていく。ダイアログを閉じたら、マシンを再起動すれば、キーが入れ替わっているはずだ。
このとき使うWindowsスキャンコードを以下の表に示す。すべてを表にすると大きくなってしまうため、おそらく入れ替えをしないだろう文字キーや数字キー、ファンクションキーに関しては一部を省略してある。数字キーとファンクションキーのスキャンコードは連続した値なので、適当に補完していただきたい。
このWindowsスキャンコードは、IBM PC ATの102キーのScan Code Set 1をベースにMicrosoftが作ったものだ。Scan Code Set 1は、初代IBM PCの86キーボードのときに作られたScan Codeが元になっているが、PC ATの101/102用に改良された。ただし、86と102の違いから、ハードウェア的にはややこしいコードが出る。
Windowsスキャンコードは、Scan Code Set 1のMakeコードからややこしいところを全部飛ばして、0x0001~0x007F、0xE001~0xE07Fの範囲で物理的なキーを表現する。USBキーボードのみにあるメディアキーなどもこの範囲内に割り当ててある。ただし、このWindowsキーはあくまでも内部的なキーコードで、ユーザーが表だって使うのは、レジストリによるキーボードマッピングぐらいだ。前述のキーボードHookでもWindowsスキャンコード取得することは可能だが、アプリケーションにはキーボードイベントとして決して渡ることがないスキャンキーコードもある。
なお、冒頭に紹介したMicrosoftの文書では、「Example 2」として右Altキーをミュートキーにするという設定がある。ざっと実験した感じ、USBキーボードが元々持っているメディアキー(再生や音量など)やアプリケーションキーなどは、レジストリ設定では置き換えることができないようだ。“ようだ”というのは、全部の組み合わせを試したわけではないからだ。しかし、PS/2側にもあるキーに、メディアキーの機能を割り当てることは可能だった。このため、上の表にも、こうしたUSBキーボード固有のキーのWindowsスキャンコードを含めているが、置き換え元として使えない。
いろいろと試したが、言語を英語だけに限れば、Hookを使うPowerToysのKeyboard Managerでもキーマッピングはやりたい放題なのだが、日本語だと前述のCaps Lockの挙動などにより、キー処理がおかしくなってしまうことがある。要望の多い、Caps LockとCtrlの入れ替えができないのはツライ。この点、レジストリを使う方法は確実である。

この連載の記事
- 第372回 Windowsにおけるアプリ実行エイリアスとは?
- 第371回 Windowsで利用可能なホットキーを探す
- 第370回 「Windows Terminal」「PowerTpys」「Winget」 Microsoft系OSSのアップデート情報
- 第369回 Windows 11の3月アップデートでの新機能をプレビュー システムトレイが改良
- 第368回 PowerShellのコマンドの並びにある典型的なパターン
- 第367回 AndroidアプリがWindowsで動く、「Windows Subsystem for Android」は今どうなってる?
- 第366回 ストア版WSLをアップデートまたはダウングレードする
- 第365回 Windowsで作成した仮想ハードディスクを容量を拡大する
- 第364回 Windowsで仮想ハードディスクを作る&使う
- 第363回 Windowsのタスクスケジューラーをもっと使いこなす
- 第362回 WSL(Windows Subsystem for Linux)がMicrosoftストア版に一本化される
- この連載の一覧へ