zoukankan      html  css  js  c++  java
  • C#中使用全局鼠标Hook实现全局双击动作捕获

    相关参考文档:

    http://www.cnblogs.com/michaelxu/archive/2006/09/22/511557.html

    http://www.cnblogs.com/Johness/archive/2012/12/28/2837977.html

    http://support.microsoft.com/default.aspx?scid=kb;en-us;318804

    使用Low-level的钩子可以实现全局捕获相关动作,微软提供的有WH_MOUSE_LL和WH_KEYBOARD_LL这两个Low-level的钩子来实现对全局鼠标和全局键盘的捕获,配合SetWindowsHookEx,就可以将具体的钩子挂在到全局。

    网上很多例子中,对于鼠标双击的动作捕获,都是认为可以捕获WM_LBUTTONDBLCLK这个消息,通过该消息来设定是否为双击,但实际挂在钩子后,Windows并不会直接捕获到WM_LBUTTONDBLCLK这个消息,而是两次WM_LBUTTONDOWN消息,因此,如果要实现双击的捕获,可考虑计算两次点击的时间间隔,和系统的双击时间间隔进行比较,从而判定是否为双击。

    代码中引入系统的双击时间

    [DllImport("user32.dll")]
    public static extern int GetDoubleClickTime();

    设定一个静态变量存储上一次点击的时间,以及一个静态变量存储具体的点击数

    static DateTime lastClickTime;
    static clickCount;

    鼠标钩子回调函数中通过计算两次点击的时间间隔来区分双击与否,合理利用clickCount来避免三次快速点击时候被识别为两次双击

    private int CallBackMouseHookProc(int nCode, int wParam, IntPtr lParam)
    {
        if (nCode < 0)
        {
            CallNextHookEx(mshHook, nCode, wParam, lParam);
        }
    
        MOUSEHOOKSTRUCT mouseHookStruct = (MOUSEHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MOUSEHOOKSTRUCT));
        MouseButtons mouseButton = MouseButtons.None;
    
        switch (wParam)
        {
            case (int)MsgType.WM_LBUTTONDOWN:
                mouseButton = MouseButtons.Left;
                break;
            case (int)MsgType.WM_RBUTTONDOWN:
                mouseButton = MouseButtons.Right;
                break;
            case (int)MsgType.WM_MOUSEMOVE:
                clickCount = 0;
                break;
            default:
                break;
        }
    
        if (mouseButton == MouseButtons.Left)
        {
            System.TimeSpan deltaMs = DateTime.Now - lastClickTime;
            lastClickTime = DateTime.Now;
    
            if (deltaMs.TotalMilliseconds <= GetDoubleClickTime())
            {
                clickCount++;
            }
            else
            {
                clickCount = 1;
            }
    
            if (clickCount == 2)
            {
                MouseEventArgs e = new MouseEventArgs(
                    mouseButton,
                    clickCount,
                    mouseHookStruct.pt.x,
                    mouseHookStruct.pt.y,
                    0);
    
                clickCount = 0;
                OnMouseDoubleClick(this, e);
            }
        }
    
        return CallNextHookEx(mshHook, nCode, wParam, lParam);
    }

    更精确的还需要当鼠标移动时候则取消上一次的计算,不计入双击点击中

  • 相关阅读:
    [java]struts2入门
    [c#基础]ICloneable接口
    idea jsp html 空白页的问题
    在Intellij Idea中使用jstl标签库
    org.apache.catalina.LifecycleException: Failed to start component
    tomcat点击startup.bat一闪而退的方法
    [转]小心C# 5.0 中的await and async模式造成的死锁
    体验h5离线缓存
    [Asp.net core]使用Polly网络请求异常重试
    asp.net core读取appsettings.json,如何读取多环境开发配置
  • 原文地址:https://www.cnblogs.com/wantoo/p/3949939.html
Copyright © 2011-2022 走看看