【发布时间】:2013-03-21 12:47:48
【问题描述】:
我需要捕获全局键盘消息,因此我将 SetWindowsHookEx() 与 WH_KEYBOARD_LL 一起使用。但它仅在应用程序处于焦点时有效,并且不会全局触发回调。几乎相同的代码适用于 mouse_LL(具有其他结构等)请帮助!
public const int WH_KEYBOARD_LL = 13;
public const int VK_INSERT = 0x2D;
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
HookProc KeyboardHookProcedure;
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn,
IntPtr hInstance, int threadId);
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[StructLayout(LayoutKind.Sequential)]
private struct KBDLLHOOKSTRUCT
{
public uint vkCode;
public uint scanCode;
public uint flags;
public uint time;
public IntPtr dxExtraInfo;
}
private void SetHookKeyboard()
{
if (kHook == 0)
{
KeyboardHookLL();
//If the SetWindowsHookEx function fails.
if (kHook == 0)
{
MessageBox.Show("SetWindowsHookEx Failed");
return;
}
button1.Text = "UnHook Windows Hook";
}
else
{
bool ret = UnhookWindowsHookEx(kHook);
//If the UnhookWindowsHookEx function fails.
if (ret == false)
{
MessageBox.Show("UnhookWindowsHookEx Failed");
return;
}
kHook = 0;
this.Text = "Keyboard Hook";
}
}
private void KeyboardHookLL()
{
KeyboardHookProcedure = new HookProc(MainForm.KeyboardHookProc);
kHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle("user32"), 0);
}
public static int KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
KBDLLHOOKSTRUCT MyKeyboardHookStruct = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(KBDLLHOOKSTRUCT));
if (nCode < 0)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
else
{
Form tempForm = Form.ActiveForm;
tempForm.Text = MyKeyboardHookStruct.vkCode.ToString();
if (MyKeyboardHookStruct.vkCode == VK_INSERT)
{
MainForm.botAlive = false;
MessageBox.Show(MainForm.botAlive.ToString());
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
}
【问题讨论】:
-
一般来说使用热键而不是钩子更安全。您需要挂钩而不是热键是否有特殊原因?
-
是的,我需要捕捉每一个输入,因为它将成为一个“记录器”。
-
如果这是你的主窗体的代码,那么你不应该在某个地方注册事件处理程序吗?
-
这是从整体代码中选择的。 KeyboardHookProc 是一个回调方法,所以我不必注册任何事件处理程序。它捕获键盘输入(但仅当调用应用程序处于焦点并且我需要它来捕获全局键盘消息时)
标签: keyboard-hook setwindowshookex