zoukankan      html  css  js  c++  java
  • [Winform]通过钩子监控键盘操作和鼠标移动

    摘要

    有这样一个需求,在程序隐藏之后,需要监控当前电脑是否有操作,如果1分钟内,无操作,则弹出视频,循环播放。

    解决办法

    从网上找的一个解决办法,可以通过钩子的方式实现,这里记录一下。

        /// <summary>
        ///监控键盘钩子
        /// </summary>
        public class KeyboardHook
        {
            private const int WM_KEYDOWN = 0x100;
            private const int WM_KEYUP = 0x101;
            private const int WM_SYSKEYDOWN = 0x104;
            private const int WM_SYSKEYUP = 0x105;
    
            //全局事件  
            public event KeyEventHandler OnKeyDownEvent;
            public event KeyEventHandler OnKeyUpEvent;
            public event KeyPressEventHandler OnKeyPressEvent;
    
            static int hKeyboardHook = 0;
    
            //鼠标常量  
            public const int WH_KEYBOARD_LL = 13;
    
            public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
    
            //声明键盘钩子事件类型  
            HookProc KeyboardHookProcedure;
    
            /// <summary>  
            /// 声明键盘钩子的封送结构类型  
            /// </summary>  
            [StructLayout(LayoutKind.Sequential)]
            public class KeyboardHookStruct
            {
                public int vkCode;//表示一个1到254间的虚拟键盘码  
                public int scanCode;//表示硬件扫描码  
                public int flags;
                public int time;
                public int dwExtraInfo;
            }
            [DllImport("kernel32.dll")]
            public static extern IntPtr GetModuleHandle(string lpModuleName);
    
            //安装钩子  
            [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 int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
            //卸载钩子  
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern bool UnhookWindowsHookEx(int idHook);
    
            private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
            {
                if ((nCode >= 0) && (OnKeyDownEvent != null || OnKeyUpEvent != null || OnKeyPressEvent != null))
                {
                    KeyboardHookStruct MyKBHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
    
                    //引发OnKeyDownEvent  
                    if (OnKeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
                    {
                        Keys keyData = (Keys)MyKBHookStruct.vkCode;
                        KeyEventArgs e = new KeyEventArgs(keyData);
                        OnKeyDownEvent(this, e);
                    }
                }
                return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
            }
    
            public void Start()
            {
                if (hKeyboardHook == 0)
                {
                    KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                    using (System.Diagnostics.Process curProcess = System.Diagnostics.Process.GetCurrentProcess())
                    using (System.Diagnostics.ProcessModule curModule = curProcess.MainModule)
                        hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(curModule.ModuleName), 0);
    
                    if (hKeyboardHook == 0)
                    {
                        Stop();
                        throw new Exception("Set GlobalKeyboardHook failed!");
                    }
                }
            }
    
            public void Stop()
            {
                bool retKeyboard = true;
                if (hKeyboardHook != 0)
                {
                    retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
                    hKeyboardHook = 0;
                }
                if (!retKeyboard)
                    throw new Exception("Unload GlobalKeyboardHook failed!");
            }
    
            //构造函数中安装钩子  
            public KeyboardHook()
            {
            }
            //析构函数中卸载钩子  
            ~KeyboardHook()
            {
                Stop();
            }
        }
       /// <summary>
        /// 监控鼠标钩子
        /// </summary>
        public class MouseHook
        {
            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;
    
            //全局的事件    
            public event MouseEventHandler OnMouseActivity;
    
            static int hMouseHook = 0; //鼠标钩子句柄    
    
            //鼠标常量    
            public const int WH_MOUSE_LL = 14; //mouse hook constant    
    
            HookProc MouseHookProcedure; //声明鼠标钩子事件类型.    
    
            //声明一个Point的封送类型    
            [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;
            }
            [DllImport("kernel32.dll")]
            public static extern IntPtr GetModuleHandle(string lpModuleName);
            //装置钩子的函数    
            [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, Int32 wParam, IntPtr lParam);
    
            public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
    
            /// <summary>    
            /// 墨认的构造函数构造当前类的实例.    
            /// </summary>    
            public MouseHook()
            {
            }
    
            //析构函数.    
            ~MouseHook()
            {
                Stop();
            }
    
            public void Start()
            {
                //安装鼠标钩子    
                if (hMouseHook == 0)
                {
                    //生成一个HookProc的实例.    
                    MouseHookProcedure = new HookProc(MouseHookProc);
                    using (System.Diagnostics.Process curProcess = System.Diagnostics.Process.GetCurrentProcess())
                    using (System.Diagnostics.ProcessModule curModule = curProcess.MainModule)
                        hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, GetModuleHandle(curModule.ModuleName), 0);
    
                    //如果装置失败停止钩子    
                    if (hMouseHook == 0)
                    {
                        Stop();
                        throw new Exception("SetWindowsHookEx failed.");
                    }
                }
            }
    
            public void Stop()
            {
                bool retMouse = true;
                if (hMouseHook != 0)
                {
                    retMouse = UnhookWindowsHookEx(hMouseHook);
                    hMouseHook = 0;
                }
    
                //如果卸下钩子失败    
                if (!(retMouse)) throw new Exception("UnhookWindowsHookEx failed.");
            }
    
            private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
            {
                //如果正常运行并且用户要监听鼠标的消息    
                if ((nCode >= 0) && (OnMouseActivity != null))
                {
                    MouseButtons button = MouseButtons.None;
                    int clickCount = 0;
    
                    switch (wParam)
                    {
                        case WM_LBUTTONDOWN:
                            button = MouseButtons.Left;
                            clickCount = 1;
                            break;
                        case WM_LBUTTONUP:
                            button = MouseButtons.Left;
                            clickCount = 1;
                            break;
                        case WM_LBUTTONDBLCLK:
                            button = MouseButtons.Left;
                            clickCount = 2;
                            break;
                        case WM_RBUTTONDOWN:
                            button = MouseButtons.Right;
                            clickCount = 1;
                            break;
                        case WM_RBUTTONUP:
                            button = MouseButtons.Right;
                            clickCount = 1;
                            break;
                        case WM_RBUTTONDBLCLK:
                            button = MouseButtons.Right;
                            clickCount = 2;
                            break;
                    }
    
                    //从回调函数中得到鼠标的信息    
                    MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
                    MouseEventArgs e = new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0);
    
                    OnMouseActivity(this, e);
                }
                return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
            }
        }

    使用

        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            KeyboardHook key = new KeyboardHook();
            MouseHook mouse = new MouseHook();
            private void Form1_Load(object sender, EventArgs e)
            {
                mouse.OnMouseActivity += mouse_OnMouseActivity;
                key.OnKeyDownEvent += key_OnKeyDownEvent;
                mouse.Start();
                key.Start();
                this.FormClosing += Form1_FormClosing;
    
            }
    
            void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                key.Stop();
                mouse.Stop();
            }
            void key_OnKeyDownEvent(object sender, System.Windows.Forms.KeyEventArgs e)
            {
                this.Text = e.KeyData.ToString();
            }
    
            void mouse_OnMouseActivity(object sender, System.Windows.Forms.MouseEventArgs e)
            {
    
                this.Text = "X=" + e.X + ",Y=" + e.Y;
            }
        }

    测试

    最小化到任务栏之后

    原文

    http://blog.csdn.net/gdjlc/article/details/8660191

  • 相关阅读:
    [转帖]能感动天地的老人,你拿什么来感动CCTV
    SaaS, 8,9点的太阳
    ERP软件开源是中国软件行业未来之路
    觉得为时已晚的时候,恰恰是最早的时候。
    新画皮故事——ERP软件为什么要免费
    如何定制SharePoint“欢迎”菜单?
    软件产品在什么情况下一定要走精品路线
    我的blogs
    测试环境中安装sharepoint server 2010过程中出现的一些问题及解决过程
    windows server 2008 与windows server 2008 r2区别
  • 原文地址:https://www.cnblogs.com/wolf-sun/p/7243897.html
Copyright © 2011-2022 走看看