私はWindowsドライバプログラミングの経験がないので、誰かが何か間違ったことに気づいたら、私を訂正してください。
ただし、NEOレイアウト(正確にはAdNWバリアント)を使用していて興味があったので、DDKをダウンロードして、ドキュメントから何を学べるかを確認しました。私はあなたのための解決策を本当に持っていません、そしてあなたはすでにこのようなもののいくつかを知っているかもしれないと思います、しかし私が見つけたものを書き留めることは少しでも物事を片付けるためだけならまだいくらか役に立つかもしれないと思いました。
概要
私の知る限り、キーボードデータの発信元となるパスは2つあります。PS / 2デバイスがあり、次にUSBキーボードがあります。どちらも異なるパスを使用しますが(USBデータはHIDインフラストラクチャにソースがあり、PS / 2データはI8042prtドライバーによって生成されます)、最終的にはいわゆる「キーボードクラスドライバー」になります。
そこから、データはDirectInputまたはuser32レガシーインターフェースに渡されます。レイアウトがどこで機能するかは完全には明確ではありませんが、Keyboardクラスドライバーの上に実装されていると思います。
レイアウト
キーボードレイアウトは基本的にKBDTABLES
、kbd.hで定義された構造に準拠した一連のデータ構造のようです。基本的に、低レベルのドライバーはScanCodeを生成し、これらのコードの解釈はこの構造で行われます。
最初の重要なものは、、pusVSCtoVK
およびpVSCtoVK_E0
ですpVSCtoVK_E1
。これは、ドライバーの生のスキャンコード(および拡張スキャンコード)をハードウェアに依存しない仮想キーコードにマップします。これらのキーコードは、キーを説明します。文字のマッピングは後で行われます。したがって、レイアウトが後でこれを別のものに変えたとしても、左カーソルキーはを生成VK_LEFT
し、Sキーはを生成します。VK_S
次に、がpCharModifiers
あります。これは、どの仮想キーが修飾子であり、どの組み合わせが異なるシフト状態を生成するかを指定します。
最後にpVkToWcharTable
、シフト状態に応じて、すべての仮想キーをUnicode文字にマップするものがあります。これは、実際のレイアウトのほとんどが存在する場所です。デッドキーとリガチャーにはいくつかの特別な値がありますが、とりあえずそれは脇に置いておきましょう。
アプリケーション
さて、アプリケーションは最後に何を取得しますか?WM_INPUT
明らかに、彼らは、、、 …などの通常のウィンドウメッセージから仮想キーコードとスキャンコードを取得できWM_KEYDOWN
ます。また、などの関数を使用して、Unicode文字のレイアウトを照会することもできますToUnicodeEx
。仮想キーコードとUnicode文字はレイアウトによって提供されます。
通常のキャラクターの場合、すべてが問題ありません。アプリケーションは入力イベントを受け取り、レイアウトに文字を要求すると、そこに移動します。ただし、仮想キーから文字へのマッピングは不要であり、意味がないため、カーソルキーは異なります。アプリケーションはキーを処理しますが、文字は処理しません。したがって、アクションは仮想キーコードに基づいて行われます。の場合VK_LEFT
、カーソルを左に移動します。の場合VK_RIGHT
、カーソルは右に移動します。
これにはジレンマが残ります。ModX+Sでカーソルを左に移動させたい場合pVkToWcharTable
、アプリケーションは文字ではなくキーを要求するため、修飾子対応は役に立ちません。そして明らかにSは左のキーと同じキーではありません。制御文字(私が知る限り存在しない)を作成しても、アプリケーションがそれを要求したり解釈したりしないため、おそらくどちらも役に立ちません。
したがって、実際に必要なのは、適切な修飾キーが押された場合にSキーが異なる仮想キーコードを生成することですが、レイアウトのデータ構造ではそのようなマッピングは許可されません。結局のところ、コードを実行しているのではなく、データ構造だけを実行しています。
テンキーはどうですか?
テンキーは必要なことをしているようです。キーのスキャンコードは同じままですが、Numlockの状態に応じて、異なる仮想キーコードを生成します。ただし、ここではWindowsが特別な処理を行うと思います。これらのキーには、KBDNUMPAD
フラグが設定されていpusVSCtoVK
ます。Windowsはそれを検出し、Numlockの状態に応じて仮想キーを交換するようです。
私は少なくともその証拠をいくつか見つけました。Googleで「xxxNumpadCursor」を検索してみてください。リークされたように見えるWindowsコードがいくつか表示されます。KBDNUMPAD
ShiftとNumlockに応じて、仮想キーを置き換えるように見えるコードとのチェックがあります。これがこの目的のために利用できるとは思えません。
それも可能ですか?
では、レイアウトでこれを実行できない場合、誰が実行できますか?明らかに、生のスキャンコードを生成するいくつかの低レベルのドライバー。DDKには、「kbfiltr」と呼ばれるいわゆるフィルタードライバーのサンプルがあります。基本的に、このようなフィルタードライバーは既存のドライバーに接続してドライバーからのデータを書き換えることができるようですので、別のキーを押すとSキーのスキャンコードを左に書き換えることができるはずです。
ただし、これはレイアウトではなくドライバーであることに注意してください。それが実用的な解決策かどうかはわかりません。選択したレイアウトに気付かない限り、変更はすべてのレイアウトに適用されます。(ここでレイアウト全体を実装し、それをオフに切り替えるためのキーを追加することは可能かもしれません。)また、そのようなドライバーのインストールがどれほど複雑になるか、ドライバーに署名する必要があるかどうかもわかりません。事態はさらに悪化します。
私は、このアプローチに賛成または反対するために、ドライバープログラミングの経験が十分ではありません(つまり、まったく経験がありません)。実験する価値があるかもしれませんが(ここでは仮想マシンをお勧めします)、現在行われている単純なレイアウトの置き換えよりもはるかに難しいようです。Autohotkeyソリューションはおそらく依然として最良のソリューションです(すべてのアプリケーションで機能するとは限らないという欠点があります)。
アップデート
私はもう少し調査をしました。これはフィルタードライバーで可能だと思います。このドライバーは、基本的にHIDインフラストラクチャまたはI8042prtドライバーとキーボードクラスドライバーの間に存在します。次に、クラスドライバーに到着する前にデータを変更し、そこに到着する前にキーイベントを置換/削除/追加できます。最終的には、特別なレイアウト(追加のUnicode文字用)とドライバーを使用する必要があります。ドライバーは、デバイスマネージャーを介して個々のキーボードにインストールできます。このソリューションは、すべてのアプリケーションで機能するはずです。
ここでの問題は、ドライバーの署名です。カーネルモードドライバーとして、64ビットVista / Win7で醜いハッキングなしにロードするには、署名する必要があります。そして、ドライバーに署名するのは安くはないので、基本的にそのアプローチでは運が悪いです。ユーザーモードドライバー(署名する必要はありません)を作成することでそれを回避できると思いましたが、問題は、フィルターをキーボードクラスドライバーの下にインストールする必要があることです。残念ながら、ユーザーモードのフィルタードライバーは、その上にカーネルモードのドライバーを置くことができないようです。したがって、これはオプションではありません。
だから私はあなたが基本的にAutoHotkeyで立ち往生していると思います。カーネルモードのドライバーを作成して署名の問題に対処する意思と能力がない限り。