2012-02-28 17 views
0

ウィンドウがアクティブでなくても、特定のキーボードのプレスを処理する必要のあるアプリケーションを作成しました。しかし、処理されたキーはまだウィンドウに伝播されています(私のアプリケーションが最初に処理しているかどうかはわかりません。ウィンドウに伝播しないキーボードショートカット

私のアプリが私が望むキーを処理できますが、キーを現在のアプリケーション/ウィンドウに送ることができないようにする方法はありますか?

EX)私は、印刷用の数字パッドを監視している私のアプリをバックグラウンドで開いています。数字パッド上の数字キーを押すたびに、その数字を表示用のテキストボックスに追加します。今私はクロムが開いていると、アドレスバーにカーソルを持って、私はそれらを処理する間に数字キーを押すことができるようにしたいが、クロムアドレスバーに表示されていない。

ありがとうございました。

これは基本的に非常に単純なキーロガーです。あなたはWM_KEYSが伝播したくない場合は

EDIT) キーボードフック

#endregion 
using System; 
using System.Text; 
using System.Collections.Generic; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 

public class GlobalKeyboardHook 
{ 
[DllImport("user32.dll")] 
static extern int CallNextHookEx(IntPtr hhk, int code, int wParam, ref keyBoardHookStruct lParam); 
[DllImport("user32.dll")] 
static extern IntPtr SetWindowsHookEx(int idHook, LLKeyboardHook callback, IntPtr hInstance, uint theardID); 
[DllImport("user32.dll")] 
static extern bool UnhookWindowsHookEx(IntPtr hInstance); 
[DllImport("kernel32.dll")] 
static extern IntPtr LoadLibrary(string lpFileName); 

public delegate int LLKeyboardHook(int Code, int wParam, ref keyBoardHookStruct lParam); 

public struct keyBoardHookStruct 
{ 
    public int vkCode; 
    public int scanCode; 
    public int flags; 
    public int time; 
    public int dwExtraInfo; 
} 

const int WH_KEYBOARD_LL = 13; 
const int WM_KEYDOWN = 0x0100; 
const int WM_KEYUP = 0x0101; 
const int WM_SYSKEYDOWN = 0x0104; 
const int WM_SYSKEYUP = 0x0105; 

LLKeyboardHook llkh; 
public List<Keys> HookedKeys = new List<Keys>(); 

IntPtr Hook = IntPtr.Zero; 

public event KeyEventHandler KeyDown; 
public event KeyEventHandler KeyUp; 

public GlobalKeyboardHook() 
{ 
    llkh = new LLKeyboardHook(HookProc); 
    hook(); 
} 
~GlobalKeyboardHook() 
{ unhook(); } 

public void hook() 
{ 
    IntPtr hInstance = LoadLibrary("User32"); 
    Hook = SetWindowsHookEx(WH_KEYBOARD_LL, llkh, hInstance, 0); 
} 

public void unhook() 
{ 
    UnhookWindowsHookEx(Hook); 
} 

public int HookProc(int Code, int wParam, ref keyBoardHookStruct lParam) 
{ 
    if (Code >= 0) 
    { 
     Keys key = (Keys)lParam.vkCode; 
     if (HookedKeys.Contains(key)) 
     { 
      KeyEventArgs kArg = new KeyEventArgs(key); 
      if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null)) 
       KeyDown(this, kArg); 
      else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null)) 
       KeyUp(this, kArg); 
      if (kArg.Handled) 
       return 1; 
     } 
    } 
    return CallNextHookEx(Hook, Code, wParam, ref lParam); 
} 

} 

あなたhookProcでGlobalKeyboardHook

GlobalKeyboardHook gHook; 
private void Form1_Load(object sender, EventArgs e) 
{ 
    gHook = new GlobalKeyboardHook(); // Create a new GlobalKeyboardHook 
    // Declare a KeyDown Event 
    gHook.KeyDown += new KeyEventHandler(gHook_KeyDown); 
    // Add the keys you want to hook to the HookedKeys list 
    foreach (Keys key in Enum.GetValues(typeof(Keys))) 
     gHook.HookedKeys.Add(key); 
} 

// Handle the KeyDown Event 
public void gHook_KeyDown(object sender, KeyEventArgs e) 
{ 
    textBox1.Text += ((char)e.KeyValue).ToString(); 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    gHook.hook(); 
} 

private void button2_Click(object sender, EventArgs e) 
{ 
    gHook.unhook(); 
} 

private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    gHook.unhook(); 
} 
+0

私はあなたの説明からこれをどうやって見ていないのですか?少し明確に説明するためのコードを投稿できますか? – KingCronus

+0

コードの使い方の簡単な例を追加しました。 – Richard

+0

フックの代わりにRegisterHotkeyを使用すると便利です。 http://stackoverflow.com/questions/4598895/how-to-create-non-window-bound-keyboard-shortcuts – CodesInChaos

答えて

1

の使い方、あなたはreturn CallNextHookEx(Hook, Code, wParam, ref lParam);を呼び出してはいけません。

CallNextHookExを呼び出すと、メッセージが伝達されます。

Btw、スレッド固有のフックではなく、グローバルフックを使用していることはご存じですか?したがって、あなたはあなたのアプリに関連するものだけでなく、すべてのキーの押下をキャプチャしています。

+0

それはうまくいった、ありがとう。 私はすべてのキープレスをキャプチャしていることを知っています。私は、私のアプリがバックグラウンド(アクティブではない)になり、依然としてキーを押すことができるようにしたい。 スレッド固有のフックの意味は100%ではありません(これは、私のアプリケーションがアクティブなものである場合にのみ、プレスを受け取ることを意味しますか?) もっと良い方法があれば教えてください私は常により良い方法を学ぶために開いています。 – Richard

+0

実際に特定のプロセスにフックすることができます。私はスレッドを言うが、実際はプロセスである。だから、アプリに送信された主要なメッセージは、アクティブなときにのみ処理されます。あなたが必要とするものではありません。 – squelos