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);
    }

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

  • 相关阅读:
    notion笔记
    PHP性能分析工具xdebug+qcachegrind
    Homebrew1.5之后安装PHP和扩展
    Yii2 创建新项目目录
    MAC的一些实用
    Item2 + zsh
    YII2 RBAC Admin User权限相关
    ITEM 2 MAC OSX 功能略强大的终端
    MAC终端配色Solarized
    微服务 SpringCloud + docker
  • 原文地址:https://www.cnblogs.com/wantoo/p/3949939.html
Copyright © 2011-2022 走看看