C#监测全局键盘与鼠标事件

在C#中一般不能用SetWindowHookEx监视全局键盘与鼠标事件,微软给出的解释是托管程序不能与非托管共享链接库交互,在网上找了老半天才发现了这个解决方案,拿出来与大家分享一下,希望可以节约对这方面又需求和希望学习的朋友们的时间.

         WH_KEYBOARD_LL和WH_MOUSE_LL是个例外,可以做到对全局鼠标与键盘事件监控.具体示例代码如下:

using System;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using System.ComponentModel;

namespace ScreenCapyure2
{
      public class UserActivityHook
      {
          #region Windows structure definitions

          [StructLayout(LayoutKind.Sequential)]
          private class POINT
          {
              public int x;
              public int y;
          }

          [StructLayout(LayoutKind.Sequential)]
          private class MouseHookStruct
          {
              public POINT pt;
              public int hwnd;
              public int wHitTestCode;
              public int dwExtraInfo;
          }

          [StructLayout(LayoutKind.Sequential)]
          private class MouseLLHookStruct
          {
              public POINT pt;
              public int mouseData;
              public int flags;
              public int time;
              public int dwExtraInfo;
          }

          [StructLayout(LayoutKind.Sequential)]
          private class KeyboardHookStruct
          {
              public int vkCode;
              public int scanCode;
              public int flags;
              public int time;
              public int dwExtraInfo;
          }
          #endregion

          #region Windows function imports

          [DllImport("user32.dll", CharSet = CharSet.Auto,
             CallingConvention = CallingConvention.StdCall, SetLastError = true)]
          private static extern int SetWindowsHookEx(
              int idHook,
              HookProc lpfn,
              IntPtr hMod,
              int dwThreadId);

          [DllImport("user32.dll", CharSet = CharSet.Auto,
              CallingConvention = CallingConvention.StdCall, SetLastError = true)]
          private static extern int UnhookWindowsHookEx(int idHook);

          [DllImport("user32.dll", CharSet = CharSet.Auto,
               CallingConvention = CallingConvention.StdCall)]
          private static extern int CallNextHookEx(
              int idHook,
              int nCode,
              int wParam,
              IntPtr lParam);

          private delegate int HookProc(int nCode, int wParam, IntPtr lParam);

          [DllImport("user32")]
          private static extern int ToAscii(
              int uVirtKey,
              int uScanCode,
              byte[] lpbKeyState,
              byte[] lpwTransKey,
              int fuState);

          [DllImport("user32")]
          private static extern int GetKeyboardState(byte[] pbKeyState);

          [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
          private static extern short GetKeyState(int vKey);

          #endregion

          #region Windows constants

          private const int WH_MOUSE_LL = 14;
          private const int WH_KEYBOARD_LL = 13;
          private const int WH_MOUSE = 7;
          private const int WH_KEYBOARD = 2;
          private const int WM_MOUSEMOVE = 0x200;
          private const int WM_LBUTTONDOWN = 0x201;
          private const int WM_RBUTTONDOWN = 0x204;
          private const int WM_MBUTTONDOWN = 0x207;
          private const int WM_LBUTTONUP = 0x202;
          private const int WM_RBUTTONUP = 0x205;
          private const int WM_MBUTTONUP = 0x208;
          private const int WM_LBUTTONDBLCLK = 0x203;
          private const int WM_RBUTTONDBLCLK = 0x206;
          private const int WM_MBUTTONDBLCLK = 0x209;
          private const int WM_MOUSEWHEEL = 0x020A;
          private const int WM_KEYDOWN = 0x100;
          private const int WM_KEYUP = 0x101;
          private const int WM_SYSKEYDOWN = 0x104;
          private const int WM_SYSKEYUP = 0x105;

          private const byte VK_SHIFT = 0x10;
          private const byte VK_CAPITAL = 0x14;
          private const byte VK_NUMLOCK = 0x90;

          #endregion

          public UserActivityHook()
          {
              Start();
          }

          public UserActivityHook(bool InstallMouseHook, bool InstallKeyboardHook)
          {
              Start(InstallMouseHook, InstallKeyboardHook);
          }

          ~UserActivityHook()
          {
              Stop(true, true, false);
          }

          public event MouseEventHandler OnMouseActivity;
          public event KeyEventHandler KeyDown;
          public event KeyPressEventHandler KeyPress;
          public event KeyEventHandler KeyUp;

          private int hMouseHook = 0;
          private int hKeyboardHook = 0;

          private static HookProc MouseHookProcedure;
          private static HookProc KeyboardHookProcedure;
          public void Start()
          {
              this.Start(true, true);
          }
          public void Start(bool InstallMouseHook, bool InstallKeyboardHook)
          {
              if (hMouseHook == 0 && InstallMouseHook)
              {
                  MouseHookProcedure = new HookProc(MouseHookProc);
                  hMouseHook = SetWindowsHookEx(
                      WH_MOUSE_LL,
                      MouseHookProcedure,
                      Marshal.GetHINSTANCE(
                          Assembly.GetExecutingAssembly().GetModules()[0]),
                      0);
                  if (hMouseHook == 0)
                  {
                      int errorCode = Marshal.GetLastWin32Error();
                      Stop(true, false, false);
                      throw new Win32Exception(errorCode);
                  }
              }
              if (hKeyboardHook == 0 && InstallKeyboardHook)
              {
                  KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                  hKeyboardHook = SetWindowsHookEx(
                      WH_KEYBOARD_LL,
                      KeyboardHookProcedure,
                      Marshal.GetHINSTANCE(
                      Assembly.GetExecutingAssembly().GetModules()[0]),
                      0);
                  if (hKeyboardHook == 0)
                  {
                      int errorCode = Marshal.GetLastWin32Error();
                      Stop(false, true, false);
                      throw new Win32Exception(errorCode);
                  }
              }
          }

          public void Stop()
          {
              this.Stop(true, true, true);
          }

          public void Stop(bool UninstallMouseHook, bool UninstallKeyboardHook, bool ThrowExceptions)
          {
              if (hMouseHook != 0 && UninstallMouseHook)
              {
                  int retMouse = UnhookWindowsHookEx(hMouseHook);
                  hMouseHook = 0;
                  if (retMouse == 0 && ThrowExceptions)
                  {
                      int errorCode = Marshal.GetLastWin32Error();
                      throw new Win32Exception(errorCode);
                  }
              }
              if (hKeyboardHook != 0 && UninstallKeyboardHook)
              {
                  int retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
                  hKeyboardHook = 0;
                  if (retKeyboard == 0 && ThrowExceptions)
                  {
                      int errorCode = Marshal.GetLastWin32Error();
                      throw new Win32Exception(errorCode);
                  }
              }
          }

          private int MouseHookProc(int nCode, int wParam, IntPtr lParam)
          {
              if ((nCode >= 0) && (OnMouseActivity != null))
              {
                  MouseLLHookStruct mouseHookStruct = (MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct));
                  MouseButtons button = MouseButtons.None;
                  short mouseDelta = 0;
                  switch (wParam)
                  {
                      case WM_LBUTTONDOWN:
                          button = MouseButtons.Left;
                          break;
                      case WM_LBUTTONUP:
                          button = MouseButtons.Right;
                          break;
                      case WM_MOUSEWHEEL:
                          mouseDelta = (short)((mouseHookStruct.mouseData >> 16) & 0xffff);
                          break;
                  }
                  int clickCount = 0;
                  if (button != MouseButtons.None)
                      if (wParam == WM_LBUTTONDBLCLK || wParam == WM_RBUTTONDBLCLK) clickCount = 2;
                      else clickCount = 1;
                  MouseEventArgs e = new MouseEventArgs(
                                                     button,
                                                     clickCount,
                                                     mouseHookStruct.pt.x,
                                                     mouseHookStruct.pt.y,
                                                     mouseDelta);
                  OnMouseActivity(this, e);
              }
              return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
          }
          private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
          {
              bool handled = false;
              if ((nCode >= 0) && (KeyDown != null || KeyUp != null || KeyPress != null))
              {
                  KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
                  if (KeyDown != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
                  {
                      Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                      KeyEventArgs e = new KeyEventArgs(keyData);
                      KeyDown(this, e);
                      handled = handled || e.Handled;
                  }
                  if (KeyPress != null && wParam == WM_KEYDOWN)
                  {
                      bool isDownShift = ((GetKeyState(VK_SHIFT) & 0x80) == 0x80 ? true : false);
                      bool isDownCapslock = (GetKeyState(VK_CAPITAL) != 0 ? true : false);

                      byte[] keyState = new byte[256];
                      GetKeyboardState(keyState);
                      byte[] inBuffer = new byte[2];
                      if (ToAscii(MyKeyboardHookStruct.vkCode,
                                MyKeyboardHookStruct.scanCode,
                                keyState,
                                inBuffer,
                                MyKeyboardHookStruct.flags) == 1)
                      {
                          char key = (char)inBuffer[0];
                          if ((isDownCapslock ^ isDownShift) && Char.IsLetter(key)) key = Char.ToUpper(key);
                          KeyPressEventArgs e = new KeyPressEventArgs(key);
                          KeyPress(this, e);
                          handled = handled || e.Handled;
                      }
                  }
                  if (KeyUp != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
                  {
                      Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                      KeyEventArgs e = new KeyEventArgs(keyData);
                      KeyUp(this, e);
                      handled = handled || e.Handled;
                  }

              }
              if (handled)
                  return 1;
              else
                  return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
          }
      }
}

 

以下为在窗体中监视事件

 

UserActivityHook choosesc;


choosesc = new UserActivityHook();
             choosesc.OnMouseActivity += new MouseEventHandler(choose_OnMouseActivity);
             choosesc.KeyDown += new KeyEventHandler(MyKeyDown);
             choosesc.KeyPress += new KeyPressEventHandler(MyKeyPress);
             choosesc.KeyUp += new KeyEventHandler(MyKeyUp);

 

public void MyKeyDown(object sender, KeyEventArgs e)
         {
         }

         public void MyKeyPress(object sender, KeyPressEventArgs e)
         {
         }

         public void MyKeyUp(object sender, KeyEventArgs e)
         {
         }

void choose_OnMouseActivity(object sender, MouseEventArgs e)
          {
              if (e.Clicks > 0)
              {
                  if ((MouseButtons)(e.Button) == MouseButtons.Left)
                  {
                      point[0] = e.Location;
                  }
                  if ((MouseButtons)(e.Button) == MouseButtons.Right)
                  {
                      point[1] = e.Location;
                  }
              }
              //throw new Exception("The method or operation is not implemented.");
          }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Microsoft Visual Studio 2010做的C#实时监控鼠标位置和左键点击时的位置实例,主要代码: public class MouseHook { private Point point; private Point Point { get { return point; } set { if (point != value) { point = value; if (MouseMoveEvent != null) { var e = new MouseEventArgs(MouseButtons.None, 0, point.X, point.Y, 0); MouseMoveEvent(this, e); } } } } private int hHook; private const int WM_LBUTTONDOWN = 0x201; public const int WH_MOUSE_LL = 14; public Win32Api.HookProc hProc; public MouseHook() { this.Point = new Point(); } public int SetHook() { hProc = new Win32Api.HookProc(MouseHookProc); hHook = Win32Api.SetWindowsHookEx(WH_MOUSE_LL, hProc, IntPtr.Zero, 0); return hHook; } public void UnHook() { Win32Api.UnhookWindowsHookEx(hHook); } private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam) { Win32Api.MouseHookStruct MyMouseHookStruct = (Win32Api.MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(Win32Api.MouseHookStruct)); if (nCode < 0) { return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam); } else { if (MouseClickEvent != null) { MouseButtons button = MouseButtons.None; int clickCount = 0; switch ((Int32)wParam) { case WM_LBUTTONDOWN: button = MouseButtons.Left; clickCount = 1; break; } var e = new MouseEventArgs(button, clickCount, point.X, point.Y, 0); MouseClickEvent(this, e); } this.Point = new Point(MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y); return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam); } } public delegate void MouseMoveHandler(object sender, MouseEventArgs e); public event MouseMoveHandler MouseMoveEvent; public delegate void MouseClickHandler(object sender, MouseEventArgs e); public event MouseClickHandler MouseClickEvent; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值