C#实现可捕获几乎所有键盘鼠标事件的钩子类完整实例

2019-12-30 12:48:22于丽

using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace MouseKeyboardLibrary
{
  /// <summary>
  /// Standard Keyboard Shortcuts used by most applications
  /// </summary>
  public enum StandardShortcut
  {
    Copy,
    Cut,
    Paste,
    SelectAll,
    Save,
    Open,
    New,
    Close,
    Print
  }
  /// <summary>
  /// Simulate keyboard key presses
  /// </summary>
  public static class KeyboardSimulator
  {
    #region Windows API Code
    const int KEYEVENTF_EXTENDEDKEY = 0x1;
    const int KEYEVENTF_KEYUP = 0x2;
    [DllImport("user32.dll")]
    static extern void keybd_event(byte key, byte scan, int flags, int extraInfo);
    #endregion
    #region Methods
    public static void KeyDown(Keys key)
    {
      keybd_event(ParseKey(key), 0, 0, 0);
    }
    public static void KeyUp(Keys key)
    {
      keybd_event(ParseKey(key), 0, KEYEVENTF_KEYUP, 0);
    }
    public static void KeyPress(Keys key)
    {
      KeyDown(key);
      KeyUp(key);
    }
    public static void SimulateStandardShortcut(StandardShortcut shortcut)
    {
      switch (shortcut)
      {
        case StandardShortcut.Copy:
          KeyDown(Keys.Control);
          KeyPress(Keys.C);
          KeyUp(Keys.Control);
          break;
        case StandardShortcut.Cut:
          KeyDown(Keys.Control);
          KeyPress(Keys.X);
          KeyUp(Keys.Control);
          break;
        case StandardShortcut.Paste:
          KeyDown(Keys.Control);
          KeyPress(Keys.V);
          KeyUp(Keys.Control);
          break;
        case StandardShortcut.SelectAll:
          KeyDown(Keys.Control);
          KeyPress(Keys.A);
          KeyUp(Keys.Control);
          break;
        case StandardShortcut.Save:
          KeyDown(Keys.Control);
          KeyPress(Keys.S);
          KeyUp(Keys.Control);
          break;
        case StandardShortcut.Open:
          KeyDown(Keys.Control);
          KeyPress(Keys.O);
          KeyUp(Keys.Control);
          break;
        case StandardShortcut.New:
          KeyDown(Keys.Control);
          KeyPress(Keys.N);
          KeyUp(Keys.Control);
          break;
        case StandardShortcut.Close:
          KeyDown(Keys.Alt);
          KeyPress(Keys.F4);
          KeyUp(Keys.Alt);
          break;
        case StandardShortcut.Print:
          KeyDown(Keys.Control);
          KeyPress(Keys.P);
          KeyUp(Keys.Control);
          break;
      }
    }
    static byte ParseKey(Keys key)
    {
      // Alt, Shift, and Control need to be changed for API function to work with them
      switch (key)
      {
        case Keys.Alt:
          return (byte)18;
        case Keys.Control:
          return (byte)17;
        case Keys.Shift:
          return (byte)16;
        default:
          return (byte)key;
      }
    }
    #endregion
  }
}


using System;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace MouseKeyboardLibrary
{
  /// <summary>
  /// Captures global mouse events
  /// </summary>
  public class MouseHook : GlobalHook
  {
    #region MouseEventType Enum
    private enum MouseEventType
    {
      None,
      MouseDown,
      MouseUp,
      DoubleClick,
      MouseWheel,
      MouseMove
    }
    #endregion
    #region Events
    public event MouseEventHandler MouseDown;
    public event MouseEventHandler MouseUp;
    public event MouseEventHandler MouseMove;
    public event MouseEventHandler MouseWheel;
    public event EventHandler Click;
    public event EventHandler DoubleClick;
    #endregion
    #region Constructor
    public MouseHook()
    {
      _hookType = WH_MOUSE_LL;
    }
    #endregion
    #region Methods
    protected override int HookCallbackProcedure(int nCode, int wParam, IntPtr lParam)
    {
      if (nCode > -1 && (MouseDown != null || MouseUp != null || MouseMove != null))
      {
        MouseLLHookStruct mouseHookStruct =
          (MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct));
        MouseButtons button = GetButton(wParam);
        MouseEventType eventType = GetEventType(wParam);
        MouseEventArgs e = new MouseEventArgs(
          button,
          (eventType == MouseEventType.DoubleClick ? 2 : 1),
          mouseHookStruct.pt.x,
          mouseHookStruct.pt.y,
          (eventType == MouseEventType.MouseWheel ? (short)((mouseHookStruct.mouseData >> 16) & 0xffff) : 0));
        // Prevent multiple Right Click events (this probably happens for popup menus)
        if (button == MouseButtons.Right && mouseHookStruct.flags != 0)
        {
          eventType = MouseEventType.None;
        }
        switch (eventType)
        {
          case MouseEventType.MouseDown:
            if (MouseDown != null)
            {
              MouseDown(this, e);
            }
            break;
          case MouseEventType.MouseUp:
            if (Click != null)
            {
              Click(this, new EventArgs());
            }
            if (MouseUp != null)
            {
              MouseUp(this, e);
            }
            break;
          case MouseEventType.DoubleClick:
            if (DoubleClick != null)
            {
              DoubleClick(this, new EventArgs());
            }
            break;
          case MouseEventType.MouseWheel:
            if (MouseWheel != null)
            {
              MouseWheel(this, e);
            }
            break;
          case MouseEventType.MouseMove:
            if (MouseMove != null)
            {
              MouseMove(this, e);
            }
            break;
          default:
            break;
        }
      }
      return CallNextHookEx(_handleToHook, nCode, wParam, lParam);
    }
    private MouseButtons GetButton(Int32 wParam)
    {
      switch (wParam)
      {
        case WM_LBUTTONDOWN:
        case WM_LBUTTONUP:
        case WM_LBUTTONDBLCLK:
          return MouseButtons.Left;
        case WM_RBUTTONDOWN:
        case WM_RBUTTONUP:
        case WM_RBUTTONDBLCLK:
          return MouseButtons.Right;
        case WM_MBUTTONDOWN:
        case WM_MBUTTONUP:
        case WM_MBUTTONDBLCLK:
          return MouseButtons.Middle;
        default:
          return MouseButtons.None;
      }
    }
    private MouseEventType GetEventType(Int32 wParam)
    {
      switch (wParam)
      {
        case WM_LBUTTONDOWN:
        case WM_RBUTTONDOWN:
        case WM_MBUTTONDOWN:
          return MouseEventType.MouseDown;
        case WM_LBUTTONUP:
        case WM_RBUTTONUP:
        case WM_MBUTTONUP:
          return MouseEventType.MouseUp;
        case WM_LBUTTONDBLCLK:
        case WM_RBUTTONDBLCLK:
        case WM_MBUTTONDBLCLK:
          return MouseEventType.DoubleClick;
        case WM_MOUSEWHEEL:
          return MouseEventType.MouseWheel;
        case WM_MOUSEMOVE:
          return MouseEventType.MouseMove;
        default:
          return MouseEventType.None;
      }
    }
    #endregion
  }
}