利用windows消息机制,截获特定应用程序里鼠标、键盘的消息事件

最近做一个项目,需要截获特定应用程序里鼠标和键盘的消息事件。之前本人对windows底层的消息处理机制并不熟悉,通过学习知道钩子机制可以帮助我们截获处理windows消息或特定事件,现将本人所掌握的知识内容总结如下:

1.调用windows底层API,定义winAPI类

  using System.Runtime.InteropServices;

    public class WinApi
    {
        [StructLayout(LayoutKind.Sequential)]
        public class POINT
        {
            public int x;
            public int y;
        }
        [StructLayout(LayoutKind.Sequential)]
        public class MouseHookStruct
        {
            public POINT pt;
            public int hwnd;
            public int wHitTestCode;
            public int dwExtraInfo;
        }
        [StructLayout(LayoutKind.Sequential)]
        public class KeyboardHookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }
        public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
        //安装钩子
        [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("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr GetForegroundWindow();
        //获得窗体名称
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetWindowText();
   }
2.定义鼠标钩子和键盘钩子

    public class MouseHook
    {        
        private Point point;
        private Point Point
        {
            get { return point; }
            set
            {
                if (point != value)
                {
                    point = value;
                }
            }
        }
        private int hHook;
        public const int WH_MOUSE_LL = 14;
        public WinApi.HookProc hProc;
        public MouseHook()
        {
            this.Point = new Point(); 
        }
        public int SetHook()
        {
            hProc = new WinApi.HookProc(MouseHookProc);
            hHook = WinApi.SetWindowsHookEx(WH_MOUSE_LL, hProc, IntPtr.Zero,0);
            return hHook;
        }
        public void UnHook()
        {
            WinApi.UnhookWindowsHookEx(hHook);
        }
        private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {            
            if (nCode < 0)
            {
                return WinApi.CallNextHookEx(hHook, nCode, wParam, lParam);
            }
            else
            {
               WinApi.MouseHookStruct MyMouseHookStruct = (WinApi.MouseHookStruct)Marshal.PtrToStructure
                      (lParam, typeof(WinApi.MouseHookStruct));
               MouseButtons button = MouseButtons.None;
               int clickCount = 0;
               switch ((Int32)wParam)
               {
                   case WM_LBUTTONDOWN: 
                        button = MouseButtons.Left;
                        clickCount = 1;
                        var e = new MouseEventArgs(button, clickCount, point.X, point.Y, 0);
                        MouseClick(this, e);
                        break;
                   case WM_MOUSEMOVE: 
                        var e = new MouseEventArgs(button, clickCount, point.X, point.Y, 0);
                        MouseMove(this, e);
                        break;
                    }
               this.Point = new Point(MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y);
               return WinApi.CallNextHookEx(hHook, nCode, wParam, lParam);
            }
        }
        //委托+事件(把钩到的消息封装为事件,由调用者处理)
        public delegate void MouseMoveHandler(object sender, MouseEventArgs e);
        public event MouseMoveHandler MouseMove;

        public delegate void MouseClickHandler(object sender, MouseEventArgs e);
        public event MouseClickHandler MouseClick;
    }    
    public class KeyboardHook
    {        
        private int hHook;
        public WinApi.HookProc hProc;

        public int SetHook()
        {
            hProc = new WinApi.HookProc(KeyboardHookProc);
            hHook = WinApi.SetWindowsHookEx(WH_KEYBOARD_LL, hProc, IntPtr.Zero,0);
            return hHook;
        }
        public void UnHook()
        {
            WinApi.UnhookWindowsHookEx(hHook);
        }
        private int KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {            
            if (nCode >= 0)
            {
               WinApi.KeyboardHookStruct kbhs= (WinApi.KeyboardHookStruct)Marshal.PtrToStructure(lParam,
                      typeof(WinApi.KeyboardHookStruct));
              Keys key = (Keys)kbhs.vkCode;
               switch ((Int32)wParam)
               {
                   case WM_KEYDOWN:                         
                        var e = new KeyEventArgs(key);
                        KeyDown(this, e);
                        break;
                   case WM_KEYUP: 
                        var e1 = new KeyEventArgs(key);
                        KeyUp(this, e1);
                        break;
                }               
            }
            return WinApi.CallNextHookEx(hHook, nCode, wParam, lParam);
      }
      //委托+事件(把钩到的消息封装为事件,由调用者处理) 
      public delegate void KeyDownEventHandler(object sender, KeyEventArgs e); 
      public delegate void KeyUpEventHandler(object sender, KeyEventArgs e); 

      public event KeyDownEventHandler KeyDown; 
      public event KeyUpEventHandler KeyUp; 
   }
3.应用程序调用
MouseHook mh;
KeyboardHook kh;
public Form1()
{
      InitializeComponent();
      //启动程序自动隐藏窗体
     this.WindowState = FormWindowState.Minimized;
     this.ShowInTaskbar = false;
     SetVisibleCore(false);
}
private void Form1_Load(object sender, EventArgs e)
{
      mh = new MouseHook();
      mh.SetHook();
      mh.MouseMove += mh_MouseMove;
      mh.MouseClick += mh_MouseClick;
      kh = new KeyboardHook();
      kh.SetHook();
      kh.KeyDown += kh_KeyDown;
      kh.KeyUp += kh_KeyUp;
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
       mh.UnHook();
       kh.UnHook();
}
private void mh_MouseMove(object sender, MouseEventArgs e)
{
}
private void mh_MouseClick(object sender, MouseEventArgs e)
{
}
private void kh_KeyDown(object sender, KeyEventArgs e)
{
}
private void kh_KeyUp(object sender, KeyEventArgs e)
{
}

你可能感兴趣的:(c#,WinForm)