186 lines
7.6 KiB
C#
186 lines
7.6 KiB
C#
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
|
|
{
|
|
/// <remarks>
|
|
/// 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
|
|
/// </remarks>
|
|
public class ControlClickHelper
|
|
{
|
|
#region Public Events
|
|
|
|
/// <summary>
|
|
/// Single Mouse Click Delegate for subscribing to SingleMouseClick Events
|
|
/// </summary>
|
|
/// <param name="e">MouseEventArgs</param>
|
|
public delegate void SingleMouseClick(MouseEventArgs e);
|
|
|
|
/// <summary>
|
|
/// Double Mouse Click Delegate for subscribing to DoubleMouseClick Events
|
|
/// </summary>
|
|
/// <param name="e">MouseEventArgs</param>
|
|
public delegate void DoubleMouseClick(MouseEventArgs e);
|
|
|
|
/// <summary>
|
|
/// Left Mouse Click Event
|
|
/// </summary>
|
|
public event SingleMouseClick LeftMouseClick;
|
|
|
|
/// <summary>
|
|
/// Right Mouse Click Event
|
|
/// </summary>
|
|
public event SingleMouseClick RightMouseClick;
|
|
|
|
/// <summary>
|
|
/// Left Mouse Double Click Event
|
|
/// </summary>
|
|
public event DoubleMouseClick LeftMouseDoubleClick;
|
|
|
|
/// <summary>
|
|
/// Right Mouse Double Click Event
|
|
/// </summary>
|
|
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;
|
|
|
|
/// <summary>
|
|
/// Returns true if enough time since _LastFiredEvent has passed
|
|
/// </summary>
|
|
private bool EnoughTimeSinceLastEventHasElapsed
|
|
{
|
|
get
|
|
{
|
|
return (DateTime.Now.Ticks - _LastFiredEvent.Ticks) >= (TimeSpan.FromSeconds(_N_SECONDS_TOIGNORE_NEXT_SIGNLEMOUSE_CLICKEVENT).Ticks);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Construction
|
|
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
/// <param name="control">a control for which you want to implement Single/Double Mouse Click</param>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Called by Control DoubleClick Event, We filter for only the left/right mouse double-click,
|
|
/// event and fire event when neccessary
|
|
/// </summary>
|
|
/// <param name="sender">control</param>
|
|
/// <param name="e">MouseEventArgs</param>
|
|
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));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
// Called by NotifyIcon Click Event, We filter for only the left mouse click,
|
|
/// event and fire event when neccessary
|
|
/// </summary>
|
|
/// <param name="sender">control</param>
|
|
/// <param name="e">MouseEventArgs</param>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <param name="sender">control</param>
|
|
/// <param name="e">MouseEventArgs</param>
|
|
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));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
/// <param name="sender">control</param>
|
|
/// <param name="e">MouseEventArgs</param>
|
|
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
|
|
}
|
|
}
|