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