Windows7でのキーボードレイアウトの指定

方法としては二通りあるようだ。
一つはシステムで使用するキーボードレイアウトの指定。
一つはキーボード別にレイアウトを指定。

いろいろ調べた結果とりあえずWindows7 64bitでのrealforce 86Uと91UBK用のkeyboard.infができたんで最後にdiffを張っておく。
たぶんVista 64でも使える。

まず、キーボードレイアウトの決め方だが、どうも特定モデル以外はシステムデフォルトにあわせるっていうざっくりしたもののようだ。
とりあえずMicrosoftの技術情報

USB キーボードの “プラグ アンド プレイ ID” が Keyboard.inf ファイルで定義されていないと、Windows Vista ではキーボードのモデルを特定できません。この種類のキーボードを接続すると、Windows Vista のインストール時に構成された既定のキーボード レイアウト設定が Windows Vista で使用されます。たとえば、106/109 日本語キーボードやテンキーの USB キーボードを接続した場合にこの問題が発生することがあります。

ちなみに東プレさんのRealforce86Uは華麗に登録されていないので、普通にさしたら真っ先に日本語配列になった。
たぶんOSが日本語だから。

んで、この技術資料にある解決方法。

101/102 英語 (US) キーボード

101/102 英語 (US) USB キーボードの HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesi8042prtParameters レジストリ エントリを次の表に示します。

値の名前 値の種類 値のデータ
LayerDriver JPN REG_SZ kbd101.dll
OverrideKeyboardIdentifier REG_SZ PCAT_101KEY
OverrideKeyboardSubtype DWORD 0
OverrideKeyboardType DWORD 7

日本語のレイアウトにしたい場合は以下の通り。

この問題を解決するには、HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesi8042prtParameters レジストリ サブキーを構成し、次の表に示すレジストリ エントリを設定します。

値の名前 値の種類 値のデータ
LayerDriver JPN REG_SZ kbd106.dll
OverrideKeyboardIdentifier REG_SZ PCAT_106KEY
OverrideKeyboardSubtype DWORD 2
OverrideKeyboardType DWORD 7

まあ要するにregeditでHKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesi8042prtParametersのレジストリエントリをいじくってくださいっていうことだ。
i8042prtってのはIntel 8042ポートのことで、これはPC/AT互換機用のキーボードコントローラチップらしい(ps2マウスも含むっぽい)。
まあそれが正しいかどうかは別として、とりあえあずここをいじるとシステムデフォルトで適用されるキーボードレイアウトが変更されるっぽい。
ということで、前者の方法での解決方法はこんな感じ。

PS/2接続なら以下のような流れらしい。

PS/2 キーボードの場合の手順

「解決方法」には、USB キーボードを使用する場合にこの問題を解決する方法が記載されています。この問題に類似する現象が発生していて PS/2 キーボードを使用している場合、問題を解決するには、別の手順を使用する必要があります。PS/2 キーボードを使用している場合、この問題を解決するには、次の手順を実行します。

  1. [スタート] ボタン
    [スタート] ボタン

    をクリックし、[検索の開始] ボックスに「デバイス マネージャー」と入力します。次に、[プログラム] の一覧の [デバイス マネージャー] をクリックします。

    ユーザー アカウント制御の許可

    管理者のパスワードを要求するダイアログ ボックスが表示された場合はパスワードを入力して [OK] をクリックし、確認を要求するダイアログ ボックスが表示された場合は [続行] をクリックします。

  2. デバイス マネージャーで [キーボード] を展開し、キーボード デバイスをダブルクリックします。既定では、[101/102 英語キーボードまたは Microsoft Natural PS/2 キーボード] です。
  3. [ドライバー] タブをクリックし、[ドライバーの更新] をクリックします。
  4. [コンピューターを参照してドライバー ソフトウェアを検索します] をクリックし、[コンピューター上のデバイス ドライバーの一覧から選択します] をクリックします。
  5. [互換性のあるハードウェアを表示] チェック ボックスをオフにし、[日本語 PS/2 キーボード (106/109 キー)] をクリックします。
  6. [次へ] をクリックし、ドライバーの更新を警告するメッセージが表示されたら [はい] をクリックします。残りの手順を実行してキーボードを更新します。
  7. コンピューターを再起動します。

: 後で 101/102 英語キーボードをコンピューターに接続する場合は、これらの手順を変更して、Windows Vista で [101/102 英語キーボードまたは Microsoft Natural PS/2 キーボード] デバイスが使用されるように構成してください。

で、後者の方の解決方法について。

そもそも、システムデフォルトのキーボードレイアウトに頼らなければならないのは、キーボードのモデルが特定できていないためだ。
ということで、keyboard.infをいじくって定義してしまおうという話。
この方法だと、キーボードレイアウトがキーボードごとに定義されるため、キーボードレイアウトの異なる複数のキーボードを接続しても、それぞれが正しいレイアウトで動作する。
なおPS/2接続の場合どう書けばいいのかは試すのが面倒なので調べていない。
従ってUSB接続での書き方になる。
まあそれほど大きくは変わらないとは思うんだけど。

まず、キーボードを接続。
すると、特定のキーボードとして認識されず汎用キーボードとして認識された場合、HID キーボード デバイスとして認識されるはず。
デバイスマネージャを開いてキーボードのところを見ればあるはずだ。
で、それのプロパティの詳細のハードウェアIDを選択。

HIDVID_うんたら

みたいなのがあるはず。

これのREV_うんたらがついていないほうが、そのキーボードのプラグアンドプレイIDになる。
従って、この場合はPnP IDは

HIDVID_0853&PID_010E

となる。
PnP IDをめもったら、適当な作業用フォルダを作成して、そこに以下のファイルをコピーする。
C:Windowsは環境によって(ryというお約束を一応書いておく。

C:Windowsinfkeyboard.inf
C:Windowssystem32kbdclass.sys
C:Windowssystem32kbdhid.sys
C:Windowssystem32driversi8042prt.sys

コピーしたkeyboard.infを編集。
今回は東プレのRealforce86U(101英語キーボード配列テンキーレス)とRealforce91UBK(106日本語キーボード配列テンキーレス)の二つの記述を例に挙げる。
ちなみに、86UのPnP IDは

HIDVID_0853&PID_010E

91UBKのPnP IDは

HIDVID_0853&PID_0200

となっている。
このあたりは各自デバイスマネージャから確認して自分のキーボードのPnP IDを調べてもらう。
で、86Uには101キーボードレイアウトを、91UBKには106キーボードレイアウトを適用するように記述する。

なお、NTamd64と記述のある部分はすべて64bit OS用なので、32bit OSを利用している場合はその部分は直前のカンマやピリオド含めて削除するか、NTx86に置き換えること。
詳しい話はinfファイルの書き方をお勉強すればわかるのでぐぐるべし。

まず、[Manufacturer]セクションに以下を記述。

%TOPRE%=TOPRE_KBD,NTamd64

次に、[TOPRE_KBD.NTamd64]セクションを作成して以下のように記述。

[TOPRE_KBD.NTamd64]
%HIDVID_0853&PID_010E.DeviceDesc%=HID_101_Keyboard_Inst,, HIDVID_0853&PID_010E
%HIDVID_0853&PID_0200.DeviceDesc%=HID_106_Keyboard_Inst,, HIDVID_0853&PID_0200

ちなみにManufacturerセクションの方は,(カンマ)でTOPRE_KBDセクションの方は.(ピリオド)なので注意。

; ==============================================
; Japanese 106/109 Keyboard (USB)
; ==============================================

って書いてる上のあたりに以下を挿入。

; ==============================================
; English 101 Keyboard (USB)
; ==============================================
[HID_101_Keyboard_Inst.NT]
Copyfiles = HID_Keyboard_Inst.CopyFiles.NT
;Copyfiles = 101_TYPE_LayerDriverFiles
AddReg = HID_101_Keyboard_Inst.AddReg

[HID_101_Keyboard_Inst.AddReg]

[HID_101_Keyboard_Inst.NT.HW]
AddReg = HID_101_Keyboard_Inst.AddReg.NT.HW
AddReg = HID_Keyboard_Inst.AddReg.NT

[HID_101_Keyboard_Inst.AddReg.NT.HW]
HKR,,"KeyboardTypeOverride",0x00010001,4
HKR,,"KeyboardSubtypeOverride",0x00010001,0

[HID_101_Keyboard_Inst.NT.Services]
AddService = kbdhid,%SPSVCINST_ASSOCSERVICE%,KbdHid_Service_Inst,KbdHid_EventLog_Inst ; Port Driver
AddService = kbdclass,, kbdclass_Service_Inst, kbdclass_EventLog_Inst            ; Class Driver

これはおそらくこれを読むだろう人の大半が日本語OSを使っているだろうことから。
システムのデフォルトが日本語になっている場合に必要になる。
ちなみにHKR,,”KeyboardTypeOverride”,0x00010001,4のところは4じゃなくて7でもいい。(後述)

[Strings]セクションの; Manufacturers以下あたりに以下を追記(まあ実際はStringsセクションであればどこでもいい)

TOPRE                   = "Topre"

同様に; HID device IDsあたりに以下を追記。

HIDVID_0853&PID_010E.DeviceDesc = "Topre Realforce86U USB Keyboard"
HIDVID_0853&PID_0200.DeviceDesc = "Topre Realforce91UBK USB Keyboard"

まあこの辺は表示名の問題なので、自分の好きに書けばいい。

こうして作成したinfファイルを保存したら、以下の流れ。

HID キーボード デバイスのドライバの更新を選択

ドライバを手動で検索、一覧から選択、ディスク使用。

infファイルを指定してやると、対応したキーボードがリストに出てくる。

そいつを指定してやってインストール完了。

デジタル署名されていないって怒られるが無視して更新すると、86UはASCII配列で、91UBKは日本語配列で利用できるようになる。(再起動がいる場合もあるかも)

ポイントはいくつかあるが、まず

HID_106_Keyboard_Inst

やらが第一のポイント。
91UBKの場合、

%HIDVID_0853&PID_0200.DeviceDesc%=HID_106_Keyboard_Inst,, HIDVID_0853&PID_0200

にあたり、そこから

[HID_106_Keyboard_Inst.AddReg.NT.HW]
HKR,,"KeyboardTypeOverride",0x00010001,7
HKR,,"KeyboardSubtypeOverride",0x00010001,2

が呼び出される。
ここが第二のポイントで、ここでキーボードレイアウトのオーバーライドを行っている。
実際には、レジストリの

HKEY_LOCAL_MACHINESYSTEMCurrentControlSetEnumHID{PnP ID}{うんたらかんたら}Device Parameters

に、KeyboardTypeOverrideエントリおよびKeyboardSubtypeOverrideエントリを記述している。

ちなみに、KeyboardTypeの数値は以下のような意味を持つようだ。
参照

Value Meaning

0x00000001

IBM PC/XT or compatible (83-key) keyboard

0x00000002

Olivetti “ICO” (102-key) keyboard

0x00000003

IBM PC/AT (84-key) or similar keyboard

0x00000004

IBM enhanced (101- or 102-key) keyboard

0x00000005

Nokia 1050 and similar keyboards

0x00000006

Nokia 9140 and similar keyboards

0x00000007

Japanese keyboard

ついでに、8は韓国キーボードらしい。
んで、KeyboardSubTypeは日本語と韓国語キーボード専用ぽく、レジストリの

HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlTerminal ServerKeyboardType Mapping

以下にそれっぽい記述があるのだが、どうもいまいち関係ありそうでないようで、まあとりあえず調べたがよくわからない。

[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlTerminal ServerKeyboardType MappingJPN]
“00000000”=”kbd101.dll”
“00000001”=”kbdax2.dll”
“00000002”=”kbd106.dll”
“00000003”=”kbdibm02.dll”
“00010D01″=”kbdnec95.dll”
“000000000017”=”kbdlk41a.dll”
“000000020015”=”kbdnecAT.dll”
“000000020017”=”kbdlk41j.dll”
“00000D01″=”kbdnecNT.dll”
“00000D04″=”kbdnecNT.dll”
“00010002”=”kbd106n.dll”
“00010D04″=”kbdnec95.dll”
“00020002”=”f3ahvoas.dll”
“00020D01″=”kbdnecAT.dll”
“00020D04″=”kbdnecAT.dll”
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlTerminal ServerKeyboardType MappingKOR]
“00000003”=”kbd101a.dll”
“00000004”=”kbd101b.dll”
“00000005”=”kbd101c.dll”
“00000006”=”kbd103.dll”

というのも、keyboard.inf内の定義と必ずしも一致しない。
keyboard.inf内で確認できるのものは以下。

  • KeyboardTypeが8のとき
    • KeyboardSubTypeが4のとき — KeyboardIdentifier PCAT_101BKEY, LayerDriver KOR kbd101b.dll
    • KeyboardSubTypeが6のとき — KeyboardIdentifier PCAT_103KEY, LayerDriver KOR kbd103.dll
  • KeyboardTypeが7のとき
    • KeyboardSubTypeが2のとき — KeyboardIdentifier PCAT_106KEY, LayerDriver JPN kbd106.dll or kbd106n.dll
    • KeyboardSubTypeが0x52(10進数で82)のとき — KeyboardIdentifier FUJITSU_OYAYUBI, LayerDriver JPN f3ahvoas.dll(富士通親指シフト用の設定)
    • KeyboardSubTypeが0x0d02 — USB接続のNEC PC98シリーズキーボード

といった感じでkbd106n.dll、f3ahvoas.dllなんかはあからさまに違う。

とりあえずHKEY_LOCAL_MACHINESYSTEMCurrentControlSetEnumHID{PnP ID}{うんたらかんたら}Device Parametersで確認できたのは、

  • KeyboardTypeが4のとき — 101キーボード
  • keyboardTypeが7のとき
    • KeyboardSubTypeが0, 1のとき — 101キーボード
    • KeyboardSubTypeが2のとき — 106キーボード

っていう感じ。

そういうわけで、HID_106_Keyboard_Instでは

[HID_106_Keyboard_Inst.AddReg.NT.HW]
HKR,,"KeyboardTypeOverride",0x00010001,7
HKR,,"KeyboardSubtypeOverride",0x00010001,2

なので106キーボードになる。

[HID_101_Keyboard_Inst.AddReg.NT.HW]
HKR,,"KeyboardTypeOverride",0x00010001,4
HKR,,"KeyboardSubtypeOverride",0x00010001,0

はキーボードタイプが101キーボードでサブタイプが存在しない記述だが、KeyboardTypeOverrideを7にしても日本語キーボードのサブタイプ0は101キーボードであるため、どちらでも101キーボードになる。

で、個人的に予想していたのに外れたのが、KeyboardTypeを7、KeyboardSubTypeを1にした場合。
AXキーボードのレイアウトが適用されるんじゃないかと思って試したんだけども普通に101キーボードのレイアウトだった。

keyboard.infには記述はないが、HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesi8042prtParametersの方で

値の名称 データ型
LayerDriver JPN REG_SZ kbdax2.dll
OverrideKeyboardIdentifier REG_SZ AX_105KEY
OverrideKeyboardSubtype REG_DWORD 1
OverrideKeyboardType REG_DWORD 7

と設定してやればAXキーボードのレイアウトで利用することができる。(詳しくはここ参照)
ただし、これはシステムのデフォルトを上書きする形での利用になり、HKEY_LOCAL_MACHINESYSTEMCurrentControlSetEnumHID{PnP ID}{うんたらかんたら}Device ParametersでのOverride設定の方が優先されるため、この方法を利用する場合はあらかじめPnP ID別の上書き設定は削除しておくこと。

そういうわけで、どうも

HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesi8042prtParametersのOverrideKeyboardType, OverrideKeyboardSubtype

HKEY_LOCAL_MACHINESYSTEMCurrentControlSetEnumHID{PnP ID}{うんたらかんたら}Device ParametersのKeyboardTypeOverride, KeyboardSubtypeOverride

は完全にマッチするわけではないようだ。

まあ、たいていは101か106の二択なので、KeyboardTypeは7でKeyboardSubTypeを0にするか2にするかで事足りるだろう。

以下diff。

68a69
> %TOPRE%=TOPRE_KBD,NTamd64
262a264,267
> [TOPRE_KBD.NTamd64]
> %HIDVID_0853&PID_010E.DeviceDesc%=HID_101_Keyboard_Inst,, HIDVID_0853&PID_010E
> %HIDVID_0853&PID_0200.DeviceDesc%=HID_106_Keyboard_Inst,, HIDVID_0853&PID_0200
>
552a558,579
> ; English 101 Keyboard (USB)
> ; ==============================================
> [HID_101_Keyboard_Inst.NT]
> Copyfiles = HID_Keyboard_Inst.CopyFiles.NT
> ;Copyfiles = 101_TYPE_LayerDriverFiles
> AddReg = HID_101_Keyboard_Inst.AddReg
>
> [HID_101_Keyboard_Inst.AddReg]
>
> [HID_101_Keyboard_Inst.NT.HW]
> AddReg = HID_101_Keyboard_Inst.AddReg.NT.HW
> AddReg = HID_Keyboard_Inst.AddReg.NT
>
> [HID_101_Keyboard_Inst.AddReg.NT.HW]
> HKR,,"KeyboardTypeOverride",0x00010001,7
> HKR,,"KeyboardSubtypeOverride",0x00010001,0
>
> [HID_101_Keyboard_Inst.NT.Services]
> AddService = kbdhid,%SPSVCINST_ASSOCSERVICE%,KbdHid_Service_Inst,KbdHid_EventLog_Inst ; Port Driver
> AddService = kbdclass,, kbdclass_Service_Inst, kbdclass_EventLog_Inst            ; Class Driver
>
> ; ==============================================
778a806
> TOPRE                   = "Topre"
921a950,951
> HIDVID_0853&PID_010E.DeviceDesc = "Topre Realforce86U USB Keyboard"
> HIDVID_0853&PID_0200.DeviceDesc = "Topre Realforce91UBK USB Keyboard"

「Windows7でのキーボードレイアウトの指定」への1件のフィードバック

  1. 本記事大変参考になりました。おかげで、Windows7 32bitの環境で、日本語配列のApple Wireless Keyboardと、英語配列のHHKBとを共存させることに成功しました。Windows7の場合、起動オプションで署名がないドライバの読み込みを有効にしないと、動かないようですね。

     KeyboardTypeのところは、[HID_101_Keyboard_Inst.AddReg.NT.HW]にて、「OverrideKeyboardIdentifier」と「LayerDriver JPN」をKeyboard.infで追加指定してみました。この状態でも日本語と英語キーボードが共存できているので、深く考えずに各種パラメータ直接書いてもいいかもしれません。因果関係を精査していないので、無駄な設定かもしれませんが、一応 ということで

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>