private void ProcessPossibleDoubleClick(ref MouseEventExtArgs e)
 {
     if (IsDoubleClick(e.Button, e.Timestamp, e.Point))
     {
         e = e.ToDoubleClickEventArgs();
         m_DownButtonsWaitingForMouseUp = MouseButtons.None;
         m_PreviousClicked     = MouseButtons.None;
         m_PreviousClickedTime = 0;
     }
     else
     {
         m_DownButtonsWaitingForMouseUp |= e.Button;
         m_PreviousClickedTime           = e.Timestamp;
     }
 }
        private void ProcessMouseDown(ref MouseEventExtArgs e)
        {
            if (IsGlobal)
            {
                ProcessPossibleDoubleClick(ref e);
            }
            else
            {
                // These are only used for global. No need for them in AppHooks
                m_DownButtonsWaitingForMouseUp = MouseButtons.None;
                m_PreviousClicked     = MouseButtons.None;
                m_PreviousClickedTime = 0;
            }


            InvokeMouseEventHandler(MouseDown, e);
            InvokeMouseEventHandlerExt(MouseDownExt, e);
            if (e.Handled)
            {
                SetSupressButtonUpFlag(e.Button);
                e.Handled = true;
            }
        }
        //##################################################################
        #region ProcessCallback and related subroutines

        /// <summary>
        /// This method processes the data from the hook and initiates event firing.
        /// </summary>
        /// <param name="wParam">The first Windows Messages parameter.</param>
        /// <param name="lParam">The second Windows Messages parameter.</param>
        /// <returns>
        /// True - The hook will be passed along to other applications.
        /// <para>
        /// False - The hook will not be given to other applications, effectively blocking input.
        /// </para>
        /// </returns>
        protected override bool ProcessCallback(int wParam, IntPtr lParam)
        {
            MouseEventExtArgs e = MouseEventExtArgs.FromRawData(wParam, lParam, IsGlobal);

            if (e.IsMouseKeyDown)
            {
                ProcessMouseDown(ref e);
            }

            if (e.Clicks == 1 && e.IsMouseKeyUp && !e.Handled)
            {
                ProcessMouseClick(ref e);
            }

            if (e.Clicks == 2 && !e.Handled)
            {
                InvokeMouseEventHandler(MouseDoubleClick, e);
            }

            if (e.IsMouseKeyUp)
            {
                ProcessMouseUp(ref e);
            }

            if (e.WheelScrolled)
            {
                InvokeMouseEventHandler(MouseWheel, e);
            }

            if (HasMoved(e.Point))
            {
                ProcessMouseMove(ref e);
            }

            return(!e.Handled);
        }
        /// <summary>
        /// Creates <see cref="MouseEventExtArgs"/> from relevant mouse data.
        /// </summary>
        /// <param name="wParam">First Windows Message parameter.</param>
        /// <param name="mouseInfo">A MouseStruct containing information from which to construct MouseEventExtArgs.</param>
        /// <returns>A new MouseEventExtArgs object.</returns>
        private static MouseEventExtArgs FromRawDataUniversal(int wParam, MouseStruct mouseInfo)
        {
            MouseButtons button     = MouseButtons.None;
            short        mouseDelta = 0;
            int          clickCount = 0;

            bool isMouseKeyDown = false;
            bool isMouseKeyUp   = false;


            switch (wParam)
            {
            case Messages.WM_LBUTTONDOWN:
                isMouseKeyDown = true;
                button         = MouseButtons.Left;
                clickCount     = 1;
                break;

            case Messages.WM_LBUTTONUP:
                isMouseKeyUp = true;
                button       = MouseButtons.Left;
                clickCount   = 1;
                break;

            case Messages.WM_LBUTTONDBLCLK:
                isMouseKeyDown = true;
                button         = MouseButtons.Left;
                clickCount     = 2;
                break;

            case Messages.WM_RBUTTONDOWN:
                isMouseKeyDown = true;
                button         = MouseButtons.Right;
                clickCount     = 1;
                break;

            case Messages.WM_RBUTTONUP:
                isMouseKeyUp = true;
                button       = MouseButtons.Right;
                clickCount   = 1;
                break;

            case Messages.WM_RBUTTONDBLCLK:
                isMouseKeyDown = true;
                button         = MouseButtons.Right;
                clickCount     = 2;
                break;

            case Messages.WM_MBUTTONDOWN:
                isMouseKeyDown = true;
                button         = MouseButtons.Middle;
                clickCount     = 1;
                break;

            case Messages.WM_MBUTTONUP:
                isMouseKeyUp = true;
                button       = MouseButtons.Middle;
                clickCount   = 1;
                break;

            case Messages.WM_MBUTTONDBLCLK:
                isMouseKeyDown = true;
                button         = MouseButtons.Middle;
                clickCount     = 2;
                break;

            case Messages.WM_MOUSEWHEEL:
                mouseDelta = mouseInfo.MouseData;
                break;

            case Messages.WM_XBUTTONDOWN:
                button = mouseInfo.MouseData == 1 ? MouseButtons.XButton1 :
                         MouseButtons.XButton2;
                isMouseKeyDown = true;
                clickCount     = 1;
                break;

            case Messages.WM_XBUTTONUP:
                button = mouseInfo.MouseData == 1 ? MouseButtons.XButton1 :
                         MouseButtons.XButton2;
                isMouseKeyUp = true;
                clickCount   = 1;
                break;

            case Messages.WM_XBUTTONDBLCLK:
                isMouseKeyDown = true;
                button         = mouseInfo.MouseData == 1 ? MouseButtons.XButton1 :
                                 MouseButtons.XButton2;
                clickCount = 2;
                break;
            }

            var e = new MouseEventExtArgs(
                button,
                clickCount,
                mouseInfo.Point,
                mouseDelta,
                mouseInfo.Timestamp,
                isMouseKeyDown,
                isMouseKeyUp);

            return(e);
        }
 private void InvokeMouseEventHandlerExt(EventHandler <MouseEventExtArgs> handler, MouseEventExtArgs e)
 {
     if (handler != null)
     {
         handler(this, e);
     }
 }