Как заставить хук ловить 2 клавиши? - C#

Узнай цену своей работы

Формулировка задачи:

Есть глобальный хук
Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Runtime.InteropServices;
  7. using System.Windows.Forms;
  8. namespace Sp108.com
  9. {
  10. public class Hook : IDisposable
  11. {
  12. #region Declare WinAPI functions
  13. [DllImport("kernel32.dll")]
  14. private static extern IntPtr LoadLibrary(string lpFileName);
  15. [DllImport("user32.dll")]
  16. private static extern IntPtr SetWindowsHookEx(int idHook, KeyboardHookProc callback, IntPtr hInstance, uint threadId);
  17. [DllImport("user32.dll")]
  18. private static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, int wParam, IntPtr lParam);
  19. [DllImport("user32.dll")]
  20. private static extern bool UnhookWindowsHookEx(IntPtr hInstance);
  21. #endregion
  22. #region Constants
  23. private const int WH_KEYBOARD_LL = 13;
  24. private const int WH_KEYDOWN = 0x0100;
  25. #endregion
  26. // код клавиши на которую ставим хук
  27. private int _key;
  28. private int _key2;
  29. public event KeyPressEventHandler KeyPressed;
  30. private delegate IntPtr KeyboardHookProc(int code, IntPtr wParam, IntPtr lParam);
  31. private KeyboardHookProc _proc;
  32. private IntPtr _hHook = IntPtr.Zero;
  33. public Hook(int keyCode, int keyCode2 = -1)
  34. {
  35. _key = keyCode;
  36. _key2 = keyCode2;
  37. _proc = HookProc;
  38. }
  39. public void SetHook()
  40. {
  41. var hInstance = LoadLibrary("User32");
  42. _hHook = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, hInstance, 0);
  43. }
  44. public void Dispose()
  45. {
  46. UnHook();
  47. }
  48. public void UnHook()
  49. {
  50. UnhookWindowsHookEx(_hHook);
  51. }
  52. private IntPtr HookProc(int code, IntPtr wParam, IntPtr lParam)
  53. {
  54. if(_key2 != -1)
  55. {
  56. if ((code >= 0 && wParam == (IntPtr)WH_KEYDOWN) && Marshal.ReadInt32(lParam) == _key && Marshal.ReadInt32(lParam) == _key2)
  57. {
  58. if (KeyPressed != null)
  59. {
  60. KeyPressed(this, new KeyPressEventArgs(Convert.ToChar(code)));
  61. }
  62. }
  63. } else
  64. {
  65. if ((code >= 0 && wParam == (IntPtr)WH_KEYDOWN) && Marshal.ReadInt32(lParam) == _key)
  66. {
  67. if (KeyPressed != null)
  68. {
  69. KeyPressed(this, new KeyPressEventArgs(Convert.ToChar(code)));
  70. }
  71. }
  72. }
  73. // пробрасываем хук дальше
  74. return CallNextHookEx(_hHook, code, (int)wParam, lParam);
  75. }
  76. }
  77. }
Вызов
Листинг программы
  1. private void Form1_Load(object sender, EventArgs e)
  2. {
  3. _hook = new com.Hook(0x60);
  4. _hook.KeyPressed += new KeyPressEventHandler(_hook_hide);
  5. _hook.SetHook();
  6. }
  7. void _hook_hide(object sender, KeyPressEventArgs e) //Событие нажатия клавиш
  8. {
  9. this.Visible = !this.Visible;
  10. this.Activate();
  11. }
Но проблема в том что он ловит только 1 клавишу. А надо чтобы ловил комбинации. Как видно я добавил в код переменные _key2 и конструкцию которая проверяет не равен ли он -1 и вставляет его в код. Но не работает. Помогите. Заранее спс.

Решение задачи: «Как заставить хук ловить 2 клавиши?»

textual
Листинг программы
  1.     [StructLayout(LayoutKind.Sequential)]
  2.     private struct KeyboardDescription
  3.     {
  4.       public uint KeyCode;
  5.       public uint ScanCode;
  6.       public KeyboardFlags Flags;
  7.       public uint Time;
  8.       public IntPtr ExtraInfo;
  9.     }
  10.  
  11.     [Flags]
  12.     private enum KeyboardFlags
  13.     {
  14.       Extended = 0x01,
  15.       Injected = 0x10,
  16.       AltDown = 0x20,
  17.     }
  18.  
  19.     private static IntPtr HookCallback(int code, IntPtr wParam, IntPtr lParam)
  20.     {
  21.       if (code == 0)
  22.       {
  23.         var description = (KeyboardDescription)Marshal.PtrToStructure(lParam, typeof(KeyboardDescription));
  24.         var keys = (Keys)description.KeyCode;
  25.         var isDown = wParam.ToInt32() == 0x100 || wParam.ToInt32() == 0x104;
  26.  
  27.         if (isDown)
  28.         {
  29.           // Нажата
  30.         }
  31.         else
  32.         {
  33.           // Поднята
  34.         }
  35.       }
  36.  
  37.       return CallNextHookEx(hookHandle, code, wParam, lParam);
  38.     }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы