Example #1
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="name"></param>
 public LowLevelMouseHook(string name)
 {
     _name = name;
     _hookID = IntPtr.Zero;
     _hookProc = HookCallback;
     _state = DoubleClickState.Empty;
     _strategy = MoveStrategy.Standard;
 }
Example #2
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="name"></param>
 public LowLevelMouseHook(string name)
 {
     _name     = name;
     _hookID   = IntPtr.Zero;
     _hookProc = HookCallback;
     _state    = DoubleClickState.Empty;
     _strategy = MoveStrategy.Standard;
 }
Example #3
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        private IntPtr HookCallback(int nCode, int wParam, IntPtr lParam)
        {
            long now = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            if (nCode >= 0)
            {
                Win32.MSLLHOOKSTRUCT info = (Win32.MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(Win32.MSLLHOOKSTRUCT));


                bool isDown = false;
                int nClicks = 1;
                MouseButtons button = MouseButtons.None;

                #region setting mouse data
                Win32.INPUT input = new Win32.INPUT();
                input.type = (IntPtr)Win32.INPUTF.MOUSE;
                input.mi.dwExtraInfo = (IntPtr)0;
                input.mi.mouseData = 0;
                input.mi.time = (IntPtr)0;
                input.mi.dx = (IntPtr)0;
                input.mi.dy = (IntPtr)0;
                switch (wParam) // figure out which button was pressed, if any
                {
                    ////////// down events
                    case (int)Win32.WM.LBUTTONDOWN:
                        input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.LEFTDOWN;
                        button = MouseButtons.Left;
                        isDown = true;
                        nClicks = HandleDoubleClickLogic(button, info.pt.x, info.pt.y, now);
                        break;
                    case (int)Win32.WM.RBUTTONDOWN:
                        input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.RIGHTDOWN;
                        button = MouseButtons.Right;
                        isDown = true;
                        nClicks = HandleDoubleClickLogic(button, info.pt.x, info.pt.y, now);
                        break;
                    case (int)Win32.WM.MBUTTONDOWN:
                        input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.MIDDLEDOWN;
                        button = MouseButtons.Middle;
                        isDown = true;
                        nClicks = HandleDoubleClickLogic(button, info.pt.x, info.pt.y, now);
                        break;
                    case (int)Win32.WM.XBUTTONDOWN:

                        if ((wParam >> 16) == 1)
                        { // high-order word specifies which button was pressed
                            button = MouseButtons.XButton1;
                            input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.XBUTTON1;
                        }
                        else if ((wParam >> 16) == 2)
                        {
                            button = MouseButtons.XButton2;
                            input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.XBUTTON2;
                        }

                        else Debug.Fail("XButton message received without a button identifier.");
                        isDown = true;
                        nClicks = HandleDoubleClickLogic(button, info.pt.x, info.pt.y, now);
                        break;

                    ////////// up events
                    case (int)Win32.WM.LBUTTONUP:
                        input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.LEFTUP;
                        button = MouseButtons.Left;
                        nClicks = _state.IssueDoubleClickOnMouseUp ? 2 : 1;
                        break;
                    case (int)Win32.WM.RBUTTONUP:
                        input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.RIGHTUP;
                        button = MouseButtons.Right;
                        nClicks = _state.IssueDoubleClickOnMouseUp ? 2 : 1;
                        break;
                    case (int)Win32.WM.MBUTTONUP:
                        input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.MIDDLEUP;
                        button = MouseButtons.Middle;
                        nClicks = _state.IssueDoubleClickOnMouseUp ? 2 : 1;
                        break;
                    case (int)Win32.WM.XBUTTONUP:
                        if ((wParam >> 16) == 1)
                        { // high-order word specifies which button was pressed
                            button = MouseButtons.XButton1;
                            input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.XUP;
                        }
                        else if ((wParam >> 16) == 2)
                        {
                            button = MouseButtons.XButton2;
                            input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.XUP;
                        }
                        else Debug.Fail("XButton message received without a button identifier.");
                        nClicks = _state.IssueDoubleClickOnMouseUp ? 2 : 1;
                        break;
                }

                short delta = -1; // wheel
                if (wParam == (int)Win32.WM.MOUSEWHEEL)
                {
                    input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.WHEEL;
                    delta = (short)((info.mouseData >> 16) & 0xffff);
                    nClicks = 0;
                }

                #endregion

                MouseEventArgs e = null;


                switch (_strategy)
                {
                    case MoveStrategy.Standard:
                        _curr = new Point(info.pt.x, info.pt.y);
                        _prev = _curr;
                        Win32.SetCursorPos(_curr.X, _curr.Y);
                        break;


                    case MoveStrategy.Clipped:

                        // set up the event argument
                        int deltx = info.pt.x - _prev.X;
                        int delty = info.pt.y - _prev.Y;

                        if (deltx < 100 && delty < 100)
                        {
                            int newx = _curr.X + deltx;
                            int newy = _curr.Y + delty;
                            _curr.X += deltx;
                            _curr.Y += delty;

                            #region clip to the screen bounds
                            if (_curr.X < 0)
                                _curr.X = 0;
                            else if (_curr.X >= System.Windows.SystemParameters.VirtualScreenWidth)
                                _curr.X = (int)System.Windows.SystemParameters.VirtualScreenWidth - 1;

                            if (_curr.Y < 0)
                                _curr.Y = 0;
                            else if (_curr.Y >= System.Windows.SystemParameters.VirtualScreenHeight)
                                _curr.Y = (int)System.Windows.SystemParameters.VirtualScreenHeight - 1;
                            #endregion

                        }
                        break;


                    case MoveStrategy.Relative:
                        deltx = info.pt.x - _prev.X;
                        delty = info.pt.y - _prev.Y;
                        if (deltx < 100 && delty < 100)
                        {
                            int newx = _curr.X + deltx;
                            int newy = _curr.Y + delty;
                            _curr.X += deltx;
                            _curr.Y += delty;

                            _physicalCursorLocation.X += deltx;
                            _physicalCursorLocation.Y += delty;

                            _prev = _physicalCursorLocation;

                            #region clip to the screen bounds
                            if (_curr.X < 0)
                                _curr.X = 0;
                            else if (_curr.X >= System.Windows.SystemParameters.VirtualScreenWidth)
                                _curr.X = (int)System.Windows.SystemParameters.VirtualScreenWidth - 1;

                            if (_curr.Y < 0)
                                _curr.Y = 0;
                            else if (_curr.Y >= System.Windows.SystemParameters.VirtualScreenHeight)
                                _curr.Y = (int)System.Windows.SystemParameters.VirtualScreenHeight - 1;
                            #endregion
                            Win32.SetCursorPos(_physicalCursorLocation.X, _physicalCursorLocation.Y);
                        }
                        break;
                }

                e = new MouseEventArgs(button, nClicks, _curr.X, _curr.Y, delta);


                // fire the appropriate event
                if (button != MouseButtons.None)
                {

                    if (isDown)
                    {
                        if (OnPreviewMouseDown != null)
                        {
                            SuppressArgs hp = new SuppressArgs();
                            OnPreviewMouseDown(e, hp);
                            if (!hp.SuppressMouseEvent)
                            {
                                Win32.SendMouseDown(e);
                                if (OnMouseDown != null)
                                    OnMouseDown(this, e);
                            }
                        }
                        else
                        {
                            Win32.SendMouseDown(e);
                            if (OnMouseDown != null)
                                OnMouseDown(this, e);

                        }
                    }
                    else // button came up
                    {
                        if (Control.MouseButtons != MouseButtons.None)
                            Win32.SendMouseUp(e);

                        if (_state.IssueDoubleClickOnMouseUp)
                        {
                            if (OnMouseDoubleClick != null)
                                OnMouseDoubleClick(this, e);
                            _state = DoubleClickState.Empty; // unset
                        }
                        else if (_state.IssueClickOnMouseUp)
                        {
                            if (OnMouseClick != null)
                                OnMouseClick(this, e);
                            _state.IssueClickOnMouseUp = false; // unset
                        }
                        if (OnMouseUp != null)
                        {
                            OnMouseUp(this, e);
                        }
                    }
                }
                else // no buttons -- wheel or mouse movement
                {

                    if (delta != -1)
                    {
                        Win32.SendMouseWheel(e);
                        //Win32.SendInput(1, ref input, Marshal.SizeOf(new Win32.INPUT()));
                        if (OnMouseWheel != null)
                        {
                            OnMouseWheel(this, e);
                        }
                    }
                    else // mouse movement
                    {
                        if (OnMouseMove != null)
                        {
                            OnMouseMove(this, e);
                        }
                    }
                }
            }

            Win32.CallNextHookEx(_hookID, nCode, wParam, lParam);
            return (IntPtr)0;
        }
Example #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        private IntPtr HookCallback(int nCode, int wParam, IntPtr lParam)
        {
            long now = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;

            if (nCode >= 0)
            {
                Win32.MSLLHOOKSTRUCT info = (Win32.MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(Win32.MSLLHOOKSTRUCT));


                bool         isDown  = false;
                int          nClicks = 1;
                MouseButtons button  = MouseButtons.None;

                #region setting mouse data
                Win32.INPUT input = new Win32.INPUT();
                input.type           = (IntPtr)Win32.INPUTF.MOUSE;
                input.mi.dwExtraInfo = (IntPtr)0;
                input.mi.mouseData   = 0;
                input.mi.time        = (IntPtr)0;
                input.mi.dx          = (IntPtr)0;
                input.mi.dy          = (IntPtr)0;
                switch (wParam) // figure out which button was pressed, if any
                {
                ////////// down events
                case (int)Win32.WM.LBUTTONDOWN:
                    input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.LEFTDOWN;
                    button           = MouseButtons.Left;
                    isDown           = true;
                    nClicks          = HandleDoubleClickLogic(button, info.pt.x, info.pt.y, now);
                    break;

                case (int)Win32.WM.RBUTTONDOWN:
                    input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.RIGHTDOWN;
                    button           = MouseButtons.Right;
                    isDown           = true;
                    nClicks          = HandleDoubleClickLogic(button, info.pt.x, info.pt.y, now);
                    break;

                case (int)Win32.WM.MBUTTONDOWN:
                    input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.MIDDLEDOWN;
                    button           = MouseButtons.Middle;
                    isDown           = true;
                    nClicks          = HandleDoubleClickLogic(button, info.pt.x, info.pt.y, now);
                    break;

                case (int)Win32.WM.XBUTTONDOWN:

                    if ((wParam >> 16) == 1)
                    {     // high-order word specifies which button was pressed
                        button           = MouseButtons.XButton1;
                        input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.XBUTTON1;
                    }
                    else if ((wParam >> 16) == 2)
                    {
                        button           = MouseButtons.XButton2;
                        input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.XBUTTON2;
                    }

                    else
                    {
                        Debug.Fail("XButton message received without a button identifier.");
                    }
                    isDown  = true;
                    nClicks = HandleDoubleClickLogic(button, info.pt.x, info.pt.y, now);
                    break;

                ////////// up events
                case (int)Win32.WM.LBUTTONUP:
                    input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.LEFTUP;
                    button           = MouseButtons.Left;
                    nClicks          = _state.IssueDoubleClickOnMouseUp ? 2 : 1;
                    break;

                case (int)Win32.WM.RBUTTONUP:
                    input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.RIGHTUP;
                    button           = MouseButtons.Right;
                    nClicks          = _state.IssueDoubleClickOnMouseUp ? 2 : 1;
                    break;

                case (int)Win32.WM.MBUTTONUP:
                    input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.MIDDLEUP;
                    button           = MouseButtons.Middle;
                    nClicks          = _state.IssueDoubleClickOnMouseUp ? 2 : 1;
                    break;

                case (int)Win32.WM.XBUTTONUP:
                    if ((wParam >> 16) == 1)
                    {     // high-order word specifies which button was pressed
                        button           = MouseButtons.XButton1;
                        input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.XUP;
                    }
                    else if ((wParam >> 16) == 2)
                    {
                        button           = MouseButtons.XButton2;
                        input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.XUP;
                    }
                    else
                    {
                        Debug.Fail("XButton message received without a button identifier.");
                    }
                    nClicks = _state.IssueDoubleClickOnMouseUp ? 2 : 1;
                    break;
                }

                short delta = -1; // wheel
                if (wParam == (int)Win32.WM.MOUSEWHEEL)
                {
                    input.mi.dwFlags = (IntPtr)Win32.MOUSEEVENTF.WHEEL;
                    delta            = (short)((info.mouseData >> 16) & 0xffff);
                    nClicks          = 0;
                }

                #endregion

                MouseEventArgs e = null;


                switch (_strategy)
                {
                case MoveStrategy.Standard:
                    _curr = new Point(info.pt.x, info.pt.y);
                    _prev = _curr;
                    Win32.SetCursorPos(_curr.X, _curr.Y);
                    break;


                case MoveStrategy.Clipped:

                    // set up the event argument
                    int deltx = info.pt.x - _prev.X;
                    int delty = info.pt.y - _prev.Y;

                    if (deltx < 100 && delty < 100)
                    {
                        int newx = _curr.X + deltx;
                        int newy = _curr.Y + delty;
                        _curr.X += deltx;
                        _curr.Y += delty;

                        #region clip to the screen bounds
                        if (_curr.X < 0)
                        {
                            _curr.X = 0;
                        }
                        else if (_curr.X >= System.Windows.SystemParameters.VirtualScreenWidth)
                        {
                            _curr.X = (int)System.Windows.SystemParameters.VirtualScreenWidth - 1;
                        }

                        if (_curr.Y < 0)
                        {
                            _curr.Y = 0;
                        }
                        else if (_curr.Y >= System.Windows.SystemParameters.VirtualScreenHeight)
                        {
                            _curr.Y = (int)System.Windows.SystemParameters.VirtualScreenHeight - 1;
                        }
                        #endregion
                    }
                    break;


                case MoveStrategy.Relative:
                    deltx = info.pt.x - _prev.X;
                    delty = info.pt.y - _prev.Y;
                    if (deltx < 100 && delty < 100)
                    {
                        int newx = _curr.X + deltx;
                        int newy = _curr.Y + delty;
                        _curr.X += deltx;
                        _curr.Y += delty;

                        _physicalCursorLocation.X += deltx;
                        _physicalCursorLocation.Y += delty;

                        _prev = _physicalCursorLocation;

                        #region clip to the screen bounds
                        if (_curr.X < 0)
                        {
                            _curr.X = 0;
                        }
                        else if (_curr.X >= System.Windows.SystemParameters.VirtualScreenWidth)
                        {
                            _curr.X = (int)System.Windows.SystemParameters.VirtualScreenWidth - 1;
                        }

                        if (_curr.Y < 0)
                        {
                            _curr.Y = 0;
                        }
                        else if (_curr.Y >= System.Windows.SystemParameters.VirtualScreenHeight)
                        {
                            _curr.Y = (int)System.Windows.SystemParameters.VirtualScreenHeight - 1;
                        }
                        #endregion
                        Win32.SetCursorPos(_physicalCursorLocation.X, _physicalCursorLocation.Y);
                    }
                    break;
                }

                e = new MouseEventArgs(button, nClicks, _curr.X, _curr.Y, delta);


                // fire the appropriate event
                if (button != MouseButtons.None)
                {
                    if (isDown)
                    {
                        if (OnPreviewMouseDown != null)
                        {
                            SuppressArgs hp = new SuppressArgs();
                            OnPreviewMouseDown(e, hp);
                            if (!hp.SuppressMouseEvent)
                            {
                                Win32.SendMouseDown(e);
                                if (OnMouseDown != null)
                                {
                                    OnMouseDown(this, e);
                                }
                            }
                        }
                        else
                        {
                            Win32.SendMouseDown(e);
                            if (OnMouseDown != null)
                            {
                                OnMouseDown(this, e);
                            }
                        }
                    }
                    else // button came up
                    {
                        if (Control.MouseButtons != MouseButtons.None)
                        {
                            Win32.SendMouseUp(e);
                        }

                        if (_state.IssueDoubleClickOnMouseUp)
                        {
                            if (OnMouseDoubleClick != null)
                            {
                                OnMouseDoubleClick(this, e);
                            }
                            _state = DoubleClickState.Empty; // unset
                        }
                        else if (_state.IssueClickOnMouseUp)
                        {
                            if (OnMouseClick != null)
                            {
                                OnMouseClick(this, e);
                            }
                            _state.IssueClickOnMouseUp = false; // unset
                        }
                        if (OnMouseUp != null)
                        {
                            OnMouseUp(this, e);
                        }
                    }
                }
                else // no buttons -- wheel or mouse movement
                {
                    if (delta != -1)
                    {
                        Win32.SendMouseWheel(e);
                        //Win32.SendInput(1, ref input, Marshal.SizeOf(new Win32.INPUT()));
                        if (OnMouseWheel != null)
                        {
                            OnMouseWheel(this, e);
                        }
                    }
                    else // mouse movement
                    {
                        if (OnMouseMove != null)
                        {
                            OnMouseMove(this, e);
                        }
                    }
                }
            }

            Win32.CallNextHookEx(_hookID, nCode, wParam, lParam);
            return((IntPtr)0);
        }