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

 

更精確的還需要當鼠標移動時候則取消上一次的計算,不計入雙擊點擊中

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM