EasyHook实现

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Diagnostics;

namespace EasyHook
{
    public enum HookType
    {
        WH_MSGFILTER = -1,
        WH_JOURNALRECORD = 0,
        WH_JOURNALPLAYBACK = 1,
        WH_KEYBOARD = 2,
        WH_GETMESSAGE = 3,
        WH_CALLWNDPROC = 4,
        WH_CBT = 5,
        WH_SYSMSGFILTER = 6,
        WH_MOUSE = 7,
        WH_DEBUG = 9,
        WH_SHELL = 10,
        WH_FOREGROUNDIDLE = 11,
        WH_CALLWNDPROCRET = 12,
        WH_KEYBOARD_LL = 13,
        WH_MOUSE_LL = 14
    }

    public class CustomHookProc
    {
        private CustomHookProc(){}
        public delegate void HookProcHandler(int nCode, IntPtr wParam, IntPtr lParam);
    }

    public class HookManager
    {
        private HookManager(){}

        static readonly HookManager m_instance = new HookManager();
        Dictionary<HookType, _HookProc> m_hooks = new Dictionary<HookType, _HookProc>();

        public static HookManager Instance
        {
            get { return m_instance; }
        }

        public void RegisterHook(HookType a_eHookType, CustomHookProc.HookProcHandler a_pHookProc)
        {
            if(!m_hooks.ContainsKey(a_eHookType))
            {
                m_hooks.Add(a_eHookType, new _HookProc(a_eHookType, a_pHookProc));
            }
            else
            {
                throw new Exception(string.Format("{0} already exist!", a_eHookType.ToString()));
            }
        }
        public void Unregister(HookType a_eHookType)
        {
            m_hooks.Remove(a_eHookType);
        }
    }

    class _HookProc
    {
        #region "Declare API for Hook"
        [DllImport("user32.dll", CharSet = CharSet.Auto,
        CallingConvention = CallingConvention.StdCall)]
        static extern int SetWindowsHookEx(int idHook, _HookProcHandler lpfn,
        IntPtr hInstance, int threadId);

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

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

        [DllImport("kernel32.dll")]
        static extern int GetCurrentThreadId();
        #endregion

        #region "Hook Proc"
        int MyHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (m_CustomHookProc != null)
                m_CustomHookProc(nCode, wParam, lParam);
            return CallNextHookEx(m_HookHandle, nCode, wParam, lParam);
        }
        #endregion

        CustomHookProc.HookProcHandler m_CustomHookProc;
        delegate int _HookProcHandler(int nCode, IntPtr wParam, IntPtr lParam);
        _HookProcHandler m_KbdHookProc;
        int m_HookHandle = 0;

        public _HookProc(HookType a_eHookType, CustomHookProc.HookProcHandler a_pHookProc)
        {
            m_CustomHookProc = a_pHookProc;
            m_KbdHookProc = new _HookProcHandler(MyHookProc);
            m_HookHandle = SetWindowsHookEx((int)a_eHookType, m_KbdHookProc, IntPtr.Zero, GetCurrentThreadId());
            if (m_HookHandle == 0)
            {
                throw new Exception(string.Format("Hook {0} to {1} Error:{2}", a_eHookType.ToString(), a_pHookProc.ToString(), Marshal.GetLastWin32Error()));
            }
        }
        ~_HookProc()
        {
            UnhookWindowsHookEx(m_HookHandle);
            Debug.WriteLine(Marshal.GetLastWin32Error());
            m_HookHandle = 0;
        }
    }
}
EasyHook
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace EasyHook
{
    public class KeyboardInfo
    {
        private KeyboardInfo() { }
        [DllImport("user32")]
        private static extern short GetKeyState(int vKey);
        public static KeyStateInfo GetKeyState(Keys key)
        {
            int vkey = (int)key;
            if (key == Keys.Alt)
            {
                vkey = 0x12;    // VK_ALT
            }
            short keyState = GetKeyState(vkey);
            byte[] bits = BitConverter.GetBytes(keyState);
            bool toggled = bits[0] > 0, pressed = bits[1] > 0;
            return new KeyStateInfo(key, pressed, toggled);
        }
    }

    public struct KeyStateInfo
    {
        Keys m_key;
        bool m_isPressed,
             m_isToggled;
        public KeyStateInfo(Keys key,
                        bool ispressed,
                        bool istoggled)
        {
            m_key = key;
            m_isPressed = ispressed;
            m_isToggled = istoggled;
        }
        public static KeyStateInfo Default
        {
            get
            {
                return new KeyStateInfo(Keys.None, false, false);
            }
        }
        public Keys Key
        {
            get { return m_key; }
        }
        public bool IsPressed
        {
            get { return m_isPressed; }
        }
        public bool IsToggled
        {
            get { return m_isToggled; }
        }
    }
}
KeyboardInfo
using System.Runtime.InteropServices;

namespace EasyHook
{
    [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;
    }
}
MouseHookStruct

Usage:

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            HookManager.Instance.RegisterHook(HookType.WH_KEYBOARD, new CustomHookProc.HookProcHandler(KeyboardHookProc));
            HookManager.Instance.RegisterHook(HookType.WH_MOUSE, new CustomHookProc.HookProcHandler(MouseHookProc));
        }
        void KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            KeyStateInfo ctrlKey = KeyboardInfo.GetKeyState(Keys.ControlKey);
            KeyStateInfo altKey = KeyboardInfo.GetKeyState(Keys.Alt);
            KeyStateInfo shiftKey = KeyboardInfo.GetKeyState(Keys.ShiftKey);
            KeyStateInfo f8Key = KeyboardInfo.GetKeyState(Keys.F8);

            if (ctrlKey.IsPressed)
            {
                Console.WriteLine("Ctrl Pressed!");
            }
            if (altKey.IsPressed)
            {
                Console.WriteLine("Alt Pressed!");
            }
            if (shiftKey.IsPressed)
            {
                Console.WriteLine("Shift Pressed!");
            }
            if (f8Key.IsPressed)
            {
                Console.WriteLine("F8 Pressed!");
            }
        }

        void MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));

            if (nCode >= 0)
            {
                String strCaption = "x = " +
                MyMouseHookStruct.pt.x.ToString("d") +
                "  y = " +
                MyMouseHookStruct.pt.y.ToString("d");
                Form tempForm = Form.ActiveForm;

                tempForm.Text = strCaption;
            }
        }
    }

 

posted @ 2016-05-13 11:08  尼姑哪里跑  阅读(1070)  评论(0编辑  收藏  举报