Zzz – Rev 1

Subversion Repositories:
Rev:
using System;
using System.Drawing;
using System.Threading;

namespace Zzz.Idle
{
    public class MouseInput : IDisposable
    {
        #region Static Fields and Constants

        private const int WhMouseLl = 14;

        private static Timer _mouseMovedTimer;

        #endregion

        #region Public Events & Delegates

        public event EventHandler<MouseMovedEventArgs> MouseMoved;

        public event EventHandler<EventArgs> MouseClicked;

        public event EventHandler<EventArgs> MouseWheelScrolled;

        #endregion

        #region Private Delegates, Events, Enums, Properties, Indexers and Fields

        private readonly WindowsHookHelper.HookDelegate _mouseDelegate;

        private readonly IntPtr _mouseHandle;

        private bool _disposed;

        private Point? _startMousePosition;

        private Point? _stopMousePosition;

        #endregion

        #region Constructors, Destructors and Finalizers

        public MouseInput()
        {
            _mouseMovedTimer = new Timer(MouseMovementStopped, null, TimeSpan.FromSeconds(1), TimeSpan.Zero);

            _mouseDelegate = MouseHookDelegate;
            _mouseHandle = WindowsHookHelper.SetWindowsHookEx(WhMouseLl, _mouseDelegate, IntPtr.Zero, 0);
        }

        public void Dispose()
        {
            _mouseMovedTimer?.Dispose();
            _mouseMovedTimer = null;

            Dispose(true);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (_mouseHandle != IntPtr.Zero)
                {
                    WindowsHookHelper.UnhookWindowsHookEx(_mouseHandle);
                }

                _disposed = true;
            }
        }

        ~MouseInput()
        {
            Dispose(false);
        }

        #endregion

        #region Private Methods

        private IntPtr MouseHookDelegate(int code, IntPtr wParam, IntPtr lParam)
        {
            if (code < 0)
            {
                return WindowsHookHelper.CallNextHookEx(_mouseHandle, code, wParam, lParam);
            }

            switch ((WindowsHookHelper.WM) wParam)
            {
                case WindowsHookHelper.WM.LBUTTONDOWN:
                case WindowsHookHelper.WM.LBUTTONUP:
                case WindowsHookHelper.WM.LBUTTONDBLCLK:
                case WindowsHookHelper.WM.RBUTTONDOWN:
                case WindowsHookHelper.WM.RBUTTONUP:
                case WindowsHookHelper.WM.RBUTTONDBLCLK:
                case WindowsHookHelper.WM.MBUTTONDOWN:
                case WindowsHookHelper.WM.MBUTTONUP:
                case WindowsHookHelper.WM.MBUTTONDBLCLK:
                    MouseClicked?.BeginInvoke(this, EventArgs.Empty, ar => { }, null);
                    break;
                case WindowsHookHelper.WM.MOUSEWHEEL:
                case WindowsHookHelper.WM.MOUSEHWHEEL:
                    MouseWheelScrolled?.BeginInvoke(this, EventArgs.Empty, ar => { }, null);
                    break;
                case WindowsHookHelper.WM.MOUSEMOVE:
                    if (_startMousePosition == null)
                    {
                        _startMousePosition = WindowsHookHelper.GetCursorPosition();
                    }

                    _mouseMovedTimer?.Change(TimeSpan.FromSeconds(1), TimeSpan.Zero);
                    break;
            }

            return WindowsHookHelper.CallNextHookEx(_mouseHandle, code, wParam, lParam);
        }

        private void MouseMovementStopped(object state)
        {
            _stopMousePosition = WindowsHookHelper.GetCursorPosition();
            var distance = Distance(_startMousePosition, _stopMousePosition);

            MouseMoved?.Invoke(this, new MouseMovedEventArgs(distance));

            _startMousePosition = null;
        }

        private static double Distance(Point? startMousePosition, Point? stopMousePosition)
        {
            if (startMousePosition == null || stopMousePosition == null)
            {
                return 0;
            }

            var p1 = (Point) startMousePosition;
            var p2 = (Point) stopMousePosition;
            return Math.Sqrt(Math.Pow(p2.X - p1.X, 2) + Math.Pow(p2.Y - p1.Y, 2));
        }

        #endregion
    }
}

Generated by GNU Enscript 1.6.5.90.