using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using Yaulw.Thread; using System.Timers; namespace Yaulw.WinForms { /// /// Initiate ControlClickHelper with a Control that you want to implement a Single/Double Mouse Click /// This Class helps you get accurate Single/Double Mouse Click Events /// public class ControlClickHelper { #region Public Events /// /// Single Mouse Click Delegate for subscribing to SingleMouseClick Events /// /// MouseEventArgs public delegate void SingleMouseClick(MouseEventArgs e); /// /// Double Mouse Click Delegate for subscribing to DoubleMouseClick Events /// /// MouseEventArgs public delegate void DoubleMouseClick(MouseEventArgs e); /// /// Left Mouse Click Event /// public event SingleMouseClick LeftMouseClick; /// /// Right Mouse Click Event /// public event SingleMouseClick RightMouseClick; /// /// Left Mouse Double Click Event /// public event DoubleMouseClick LeftMouseDoubleClick; /// /// Right Mouse Double Click Event /// public event DoubleMouseClick RightMouseDoubleClick; #endregion #region Private Members private Control _Control = null; private TTimerDisp SingleLeftClickDetectTimer = null; private TTimerDisp SingleRightClickDetectTimer = null; private TimeSpan _LastFiredEvent = new TimeSpan(DateTime.Now.Ticks); private const int _MILISECONDS_FOR_SINGLEMOUSE_CLICKEVENT_TOCOUNT = 350; private const int _N_SECONDS_TOIGNORE_NEXT_SIGNLEMOUSE_CLICKEVENT = 2; // to avoid tripple clicks, etc... (only sends one double click) private MouseEventArgs _LeftClickEventArgs; private MouseEventArgs _RightClickEventArgs; /// /// Returns true if enough time since _LastFiredEvent has passed /// private bool EnoughTimeSinceLastEventHasElapsed { get { return (DateTime.Now.Ticks - _LastFiredEvent.Ticks) >= (TimeSpan.FromSeconds(_N_SECONDS_TOIGNORE_NEXT_SIGNLEMOUSE_CLICKEVENT).Ticks); } } #endregion #region Construction /// /// Initiate ControlClickHelper with a Control that you want to implement a Single/Double Mouse Click /// This Class helps you get accurate Single/Double Mouse Click Events /// /// a control for which you want to implement Single/Double Mouse Click public ControlClickHelper(Control control) { this._Control = control; this.SingleLeftClickDetectTimer = new TTimerDisp(new ElapsedEventHandler(RealSingleLeftClickDetectTimer_ElapsedEventHandler), _MILISECONDS_FOR_SINGLEMOUSE_CLICKEVENT_TOCOUNT); this.SingleRightClickDetectTimer = new TTimerDisp(new ElapsedEventHandler(RealSingleRightClickDetectTimer_ElapsedEventHandler), _MILISECONDS_FOR_SINGLEMOUSE_CLICKEVENT_TOCOUNT); // Add Event Handlers control.MouseClick += new MouseEventHandler(control_MouseClick); control.MouseDoubleClick += new MouseEventHandler(control_MouseDoubleClick); } #endregion #region Click Event Handlers /// /// Called by Control DoubleClick Event, We filter for only the left/right mouse double-click, /// event and fire event when neccessary /// /// control /// MouseEventArgs private void control_MouseDoubleClick(object sender, MouseEventArgs e) { MouseEventArgs args = (MouseEventArgs)e; if (args.Button == MouseButtons.Left) { SingleLeftClickDetectTimer.Stop(); if (LeftMouseDoubleClick != null && EnoughTimeSinceLastEventHasElapsed) { _LastFiredEvent = new TimeSpan(DateTime.Now.Ticks); LeftMouseDoubleClick(new MouseEventArgs(MouseButtons.Left, 2, args.X, args.Y, args.Delta)); } } else if (args.Button == MouseButtons.Right) { SingleRightClickDetectTimer.Stop(); if (RightMouseDoubleClick != null && EnoughTimeSinceLastEventHasElapsed) { _LastFiredEvent = new TimeSpan(DateTime.Now.Ticks); RightMouseDoubleClick(new MouseEventArgs(MouseButtons.Right, 2, args.X, args.Y, args.Delta)); } } } /// // Called by NotifyIcon Click Event, We filter for only the left mouse click, /// event and fire event when neccessary /// /// control /// MouseEventArgs private void control_MouseClick(object sender, MouseEventArgs e) { MouseEventArgs args = (MouseEventArgs)e; if (args.Button == MouseButtons.Left && EnoughTimeSinceLastEventHasElapsed) { SingleLeftClickDetectTimer.Start(); // Start Single Click Detect Timer _LeftClickEventArgs = e; } else if (args.Button == MouseButtons.Right && EnoughTimeSinceLastEventHasElapsed) { SingleRightClickDetectTimer.Start(); // Start Single Click Detect Timer _RightClickEventArgs = e; } } /// /// Used to detect ONLY Single Left Clicks, since a single-click and then a double-click fires, /// we want to ignore the first click,and first see if a double-click comes in, if so, ignore /// the single click, otherwise send it. /// /// control /// MouseEventArgs private void RealSingleLeftClickDetectTimer_ElapsedEventHandler(object sender, ElapsedEventArgs e) { SingleLeftClickDetectTimer.Stop(); if (LeftMouseClick != null) { _LastFiredEvent = new TimeSpan(DateTime.Now.Ticks); LeftMouseClick(new MouseEventArgs(MouseButtons.Right, 1, _LeftClickEventArgs.X, _LeftClickEventArgs.Y, _LeftClickEventArgs.Delta)); } } /// /// Used to detect ONLY Single Right Clicks, since a single-click and then a double-click fires, /// we want to ignore the first click,and first see if a double-click comes in, if so, ignore /// the single click, otherwise send it. /// /// control /// MouseEventArgs private void RealSingleRightClickDetectTimer_ElapsedEventHandler(object sender, ElapsedEventArgs e) { SingleRightClickDetectTimer.Stop(); if (RightMouseClick != null) { _LastFiredEvent = new TimeSpan(DateTime.Now.Ticks); RightMouseClick(new MouseEventArgs(MouseButtons.Right, 1, _RightClickEventArgs.X, _RightClickEventArgs.Y, _RightClickEventArgs.Delta)); } } #endregion } }