キーボードフックをインストールしてすべてのキーをキャプチャし、それらに関連するテキストを表示するプログラムを作成しています。
しかし、私は引っ掛かりにぶつかりました、そしてそれはフックがインストールされるときいくつかのキーが振る舞いを変えることです。
小さいながらも完全なテストプログラムを投稿する方法については説明しますが、ここでは問題について説明します。
この問題は、C#プログラムである.NET4.0のWindows764ビットで発生します。私はこれは問題ではないと思います。
私のフックはそれ自体を経由してインストールSetWindowsHookEx
し、システムで処理されるすべてのキーを処理します。
フックメソッドが単に戻るか、キーの最小限の処理を実行する場合(動作を変更するものをすぐに投稿します)、キーボードはプログラムで期待どおりに機能します。
ただし、User32.dllからこの関数を呼び出しToAscii
て、キーボードのOemTildeまたは同様のキーが実際にどのキーであるかを判断すると、「次のキーをオーバーレイする」キーは機能しなくなります。そのようなキーの正しい名前はわかりませんが、2つのアポストロフィタイプである「」と「, as well as
´〜¨ and
」は機能を停止します。
たとえば、を押してからを押す~
とN
、次のように表示されます。
- キーボードフックが取り付けられていない場合:ñ
- キーボードフックが取り付けられている場合:n(上記のno〜に注意してください)
なぜこれが起こるのか、そしてどうすればこの問題を解決できるのか誰かが知っていますか?
今のところ、他のプログラムでキーを正しく処理するだけで解決します。それは、自分のプログラムで正しいキーシーケンスを正しく検出できないことを意味します。
いくつかの詳細情報:
ToAscii
フックメソッドの一部として関数を呼び出すと、別の問題が発生します。のようなキー¨
は2回処理されます。¨
一度押すと、メモ帳は2¨¨
文字を受け取り、N
今押すと。が追加されますN
。
ただし、BeginInvoke
別のスレッドでキーを処理するために使用する場合、キーボードフックメソッドから戻った後、最初の問題が発生します。
私のプログラムはおそらくその点で少し特別です:
- キーボードの状態を使用していません(つまり、渡す「キーの状態」の256バイト配列は0でいっぱいです)
- 私はデッドキーを気にしません(私のプログラムがそれらを処理しないという意味で、私は自分のプログラムがそれらをシステムの他の部分に役に立たなくすることを望まないようにそれらを十分に気にします)
そのため、私のコードは次のようになりました。
private bool IsDeadKey(uint key)
{
return ((Hook.Interop.MapVirtualKey(key, 2) & 2147483648) == 2147483648);
}
void _Hook_KeyDown_Async(KeyDownEventArgs e)
{
var inBuffer = new byte[2];
char key = '\0';
if (!IsDeadKey((uint)e.KeyCode))
{
int ascii = Hook.Interop.ToAscii((int) e.KeyCode,
e.ScanCode,
_KeyState,
inBuffer,
e.Flags);
if (ascii == 1)
{
key = Char.ToUpper((char) inBuffer[0]);
}
}
BeginInvoke(
new Action<Keys, Boolean, Boolean, Boolean, Char>(ProcessKeyboardEvent),
e.KeyCode, e.Control, e.Shift, e.Alt, key);
}