white pages

作ったもの、作りたいものについての備忘録

Windowsのキーマップまわり

最近PCを買い替えた. SSD積んで,RAMも8GBあるのでそれなりに快適なのだけど,まだちょっと使いにくい. いろいろいじっている途中.

今回は,資料がなかなか見つからなかったキーマップ周りについてメモを残しておく. なお,ディストロ迷った結果今はWindows10. そのうちSSD拡張とかする時にまた考えればいいやと思っている.

まず

Windows(NT系)でキーボードの割り当てを変えるには,軽く調べたところ2つの方法があるもよう.

  1. KeySwap」「Change Key」など,フリーソフトを使用
  2. ベンダー提供のソフト(Lenovoなら「キーボード・カスタマイズ・ユーティリティー」など)を使用
  3. レジストリをいじる

2が一番安全(ベンダーが提供してるんだからそりゃあそう),1がお手軽,3だとオーバーヘッドがほぼ乗らないといった印象. もちろん1や2でも内部的には3と同じ処理をしてることもあり,一概には言い切れなさそう.

汎用性が見込めそうなのと,中身がよく分からんフリーソフトを使いたくないため,今回は3.について説明.

手順

Windows(NT系)では,キー入力の取得は以下のようなフローになっている.

  1. ユーザーがハードウェアキーボードを打鍵
  2. キーボードが「スキャンコード(ハードウェアの規格に基づく)」をOSに送信
  3. OS側のドライバがスキャンコードを「仮想キーコード(ハードウェア依存なし)」に変換
  4. アプリケーションなどで利用

今回は「スキャンコード」のマッピングをいじる. 直接値をいじるわけではなく,後付けでマッピングを書き足す方法がMSに提供されているので,それを使っていく.

1. キーボードの規格を確認する

同じキー(例えば「A」)を押したときでも,キーボードの規格によって送信されるスキャンコードは異なる. このキーとスキャンコードの対応表を「スキャンコードセット」という.

現在使われているスキャンコードセットは3つ.

  • スキャンコードセット1 (XT系.最古.ただし互換性は保たれている.)
  • スキャンコードセット2 (PS/2系と呼ばれるもの.現在もっともメジャーとされる.)
  • スキャンコードセット3 (PS/2系のオプション.ほぼ使われない.)

といっても,古いPCではコードセット1が使われているし,最近のPCであってもフローの2.と3.の間で変換が行われてCPUに届くころにはコードセット1になっているらしい. なのでよほど特殊な事例でない限り,スキャンコードセット1を使えばよさそう.

スキャンコードの一覧を調べたがなかなかヒットせず. Microsoftが提供してるっぽい「Windows Platform Design Notes」という.docな文書が見つかったので,それと有志の方のものを残しておく.

2. 設定するキーのスキャンコードを調べる

1.で説明したスキャンコードから,入れ替えるキーのスキャンコードを調べていく. 本来スキャンコードは「キーを押したとき(make)」と「キーを離したとき(break)」の二通り発行されるのだが,ここではmakeの値を使って設定する. 理由は知らないけど公式にはそう書いてあるので気になったら読みにいこうと思う.

なので必要なのはこの2つ.

  • 変更前キーのスキャンコード(make)
  • 変更後キーのスキャンコード(make)

それぞれスキャンコードセットから探してメモしておく(16進数). また,「Keymill」というソフトで,実際に叩いたキーのスキャンコードを見れるらしい. .netが要件でなければ私も使っていた. 無念.

ついでに,探すのも面倒なので使いそうな辺りだけでもここにメモしておく. なお値はスキャンコードセット1のもの.

キー スキャンコード
null(無効化) 0x 00 00
ESC 0x 00 01
TAB 0x 00 0F
CapsLock 0x 00 3A
左Shift 0x 00 2A
右Shift 0x 00 36
左Alt 0x 00 38
右Alt 0x E0 38
左Ctrl 0x 00 1D
右Ctrl 0x E0 1D
PrintScreen 0x E0 37
0x E0 48
0x E0 50
0x E0 4D
0x E0 4B
Insert 0x E0 52
Delete 0x E0 53
左Win key 0x E0 5B
application 0x E0 5D

3. マッピングをいじる

ようやく必要なデータがそろって,ようやくマッピング書き換えの作業ができる. Windowsではスキャンコードと仮想キーコードの対応づけにパッチをあてるような方式で,ユーザからいじれるような方法を提供している(多分修正用).

手順はこんな感じ.

  1. Windowsレジストリエディタ「regedit」を開く
  2. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layoutに移動
  3. 新規バイナリファイル「Scancode Map」を作成
  4. バイナリデータで置き換えるキーを記述(後述)
  5. PCを再起動で反映される
    • もしうまくいかなかったり,異常が生じた場合は,作成したバイナリファイルを消して再起動すればよい

設定するバイナリ値については,MS公式曰く下表のような感じ. 例として,「左CapsLocl->Ctrl」「PrtSc->Application」の2つのマッピング設定時のデータを右につけてある. なお,Windowsはリトルエンディアンなので,実際のスキャンコードと入力値は上下バイトが入れ替わっている(0x 00 3A -> 0x 3A 00).

start offset(アドレス) Size(バイト) Data ex
0 4 version header(0x 00 00 00 00) 0x 00 00 00 00
4 4 flag header(0x 00 00 00 00) 0x 00 00 00 00
8 4 マッピングするキー数(+1) 0x 00 00 00 03
12 4 実際のマッピング(変更後,変更前) 0x 1D 00 3A 00
4 (設定したい数だけ繰り返す) 0x 5D E0 37 E0
終端4byte 4 ターミネータ(0x 00 00 00 00) 0x 00 00 00 00

実際の画面だとこんな感じになる. f:id:overslept-dev:20170626144205p:plain

headerとflagに関しては,OS側のversion/flagを指定するものらしく,0指定でよいとのこと. 後はマッピングしたいキーの数+1を指定し,実際に変更するキーマッピングを1組ずつ書いていけばよい.

参考