Мне нужно захватить глобальные сообщения клавиатуры, поэтому я использую SetWindowsHookEx() с WH_KEYBOARD_LL. Но он работает только тогда, когда приложение находится в фокусе и не вызывает Callback во всем мире. Почти тот же код отлично работает с 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);
}
}
в целом безопаснее использовать горячие клавиши вместо крючков. Есть ли специальная причина, по которой вам нужен крючок вместо горячей клавиши? – Guido
Yeap, мне нужно будет записывать каждый вход, так как это будет «рекордер». – UnknitSplash
Если это код вашей основной формы, то разве вы не должны регистрировать обработчик событий где-нибудь? – Guido