using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using WatchdogLib.Thread;
using System.Timers;
namespace WatchdogLib.WinForms
{
///
/// Wrapper Class around .Net NotifyIcon, to make it easier to work with an System Tray Icon.
/// Instantiate the object and set ContextMenu or ContextMenuStrip in order to have a right click menu.
/// Subscripe to the MouseLeftClick, and MouseLeftDoubleClick event to get accurate events to handle,
/// Call Show()/Hide() to show/hide the System Tray Icon, respectively.
///
public class SysTray
{
#region Public Properties
public NotifyIcon trayNotify { get; private set; }
public Icon Icon { get { return trayNotify.Icon; } set { trayNotify.Icon = value; } }
public ContextMenu trayMenu { get { return trayNotify.ContextMenu; } set { trayNotify.ContextMenu = value; } }
public ContextMenuStrip trayMenuStrip { get { return trayNotify.ContextMenuStrip; } set { trayNotify.ContextMenuStrip = value; } }
public string toolTip { get { return trayNotify.Text; } set { trayNotify.Text = value; } }
public bool Visible { get { return trayNotify.Visible; } }
#endregion
#region Public Events
public delegate void SingleLeftMouseClick(MouseEventArgs e);
///
/// Subscribe to get the Left Mouse Single Click Event
///
public event SingleLeftMouseClick LeftMouseClick;
public delegate void DoubleLeftMouseClick(MouseEventArgs e);
///
/// Subscribe to get the Left Mouse Double Click Event
///
public event DoubleLeftMouseClick LeftMouseDoubleClick;
public delegate void RightMouseClick(MouseEventArgs e);
///
/// Subscribe to get any Right Mouse Fired Event, use to redo context menu, if needed
///
public event RightMouseClick RightMouseFired;
#endregion
#region Private Members
private TTimer SingleClickDetectTimer = null;
private TimeSpan _LastFiredEvent = new TimeSpan(DateTime.Now.Ticks);
private const int _MILISECONDS_FOR_SINGLEMOUSE_CLICKEVENT_TOCOUNT = 500;
private const int _N_SECONDS_TOIGNORE_NEXT_SIGNLEMOUSE_CLICKEVENT = 2; // to avoid tripple clicks, etc... (only sends one double click)
///
/// Returns true if enough time since _LastFiredEvent has passed
///
private bool EnoughTimeSinceLastEventHasElapsed
{
get
{
// 1 second is 10 Million ticks, one Milisecond is 10K
return (DateTime.Now.Ticks - _LastFiredEvent.Ticks) >= (_N_SECONDS_TOIGNORE_NEXT_SIGNLEMOUSE_CLICKEVENT * 1000 * 10000);
}
}
#endregion
#region Construction
///
/// Construct a System Tray Icon (use public properties like ContextMenu,Icon,toolTip to customize further)
///
/// pass in an initial ToolTip to display, defaults to ""
/// if null, defaults to systemIcons.Application
//public SysTray(string toolTip = "", Icon icon = null)
public SysTray(string toolTip, Icon icon)
{
// Create internal objects
this.trayNotify = new NotifyIcon();
this.SingleClickDetectTimer = new TTimer(new ElapsedEventHandler(RealSingleClickDetectTimer_ElapsedEventHandler), _MILISECONDS_FOR_SINGLEMOUSE_CLICKEVENT_TOCOUNT, false, true);
// Add Single / Double-Click Event Handlers
trayNotify.Click += new EventHandler(trayNotify_Click);
trayNotify.DoubleClick += new EventHandler(trayNotify_DoubleClick);
trayNotify.MouseDown += new MouseEventHandler(trayNotify_MouseDown);
// Set ToolTip
if (!String.IsNullOrEmpty(toolTip))
this.toolTip = toolTip;
// Set Icon
if (icon == null)
this.Icon = new Icon(SystemIcons.Application, 40, 40);
else
this.Icon = icon;
}
#endregion
#region Click Event Handlers
///
/// Called by NotifyIcon DoubleClick Event, We filter for only the left mouse double-click,
/// event and fire event when neccessary
///
///
///
private void trayNotify_DoubleClick(object sender, EventArgs e)
{
MouseEventArgs args = (MouseEventArgs)e;
if (args.Button == MouseButtons.Left)
{
SingleClickDetectTimer.Stop();
if (LeftMouseDoubleClick != null && EnoughTimeSinceLastEventHasElapsed)
{
_LastFiredEvent = new TimeSpan(DateTime.Now.Ticks);
LeftMouseDoubleClick(new MouseEventArgs(MouseButtons.Left, 2, 0, 0, 0));
}
}
}
///
// Called by NotifyIcon Click Event, We filter for only the left mouse click,
/// event and fire event when neccessary
///
///
///
private void trayNotify_Click(object sender, EventArgs e)
{
MouseEventArgs args = (MouseEventArgs) e;
if (args.Button == MouseButtons.Left && EnoughTimeSinceLastEventHasElapsed)
SingleClickDetectTimer.Start(); // Start Single Click Detect Timer
}
///
/// In order to accurately re-do a context menu, we handle MouseDown for the
/// Right-Mouse click. Mouse Down comes in before the click event, which gives
/// the caller an opportunity to handle/recreate the context menu dynamically, if needed
///
///
///
void trayNotify_MouseDown(object sender, MouseEventArgs e)
{
MouseEventArgs args = (MouseEventArgs)e;
if (args.Button == MouseButtons.Right && (RightMouseFired != null))
RightMouseFired(args);
}
///
/// Used to detect ONLY Single 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. (this is done by trayNotify_Click & transNotify_DoubleClick)
///
///
///
private void RealSingleClickDetectTimer_ElapsedEventHandler(object sender, ElapsedEventArgs e)
{
SingleClickDetectTimer.Stop();
if (LeftMouseClick != null)
{
_LastFiredEvent = new TimeSpan(DateTime.Now.Ticks);
LeftMouseClick(new MouseEventArgs(MouseButtons.Left, 1, 0, 0, 0));
}
}
#endregion
#region Show N' Hide
///
/// Show the System Tray Icon
///
public void Show()
{
trayNotify.Visible = true;
}
///
/// Hide the System Tray Icon
///
public void Hide()
{
trayNotify.Visible = false;
}
#endregion
#region Public ShowBallon
///
/// Pops up a Ballon over the System Tray Icon
///
/// Specify the Timeout in Seconds
//public void ShowBallon_Default(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds = 10)
public void ShowBallon_Default(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds)
{
trayNotify.ShowBalloonTip((nTimeoutInSeconds * 1000), BallonTipTitle, BallonTipText, ToolTipIcon.None);
}
///
/// Pops up a Error Ballon over the System Tray Icon
///
/// Specify the Timeout in Seconds
//public void ShowBallon_Error(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds = 10)
public void ShowBallon_Error(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds)
{
trayNotify.ShowBalloonTip((nTimeoutInSeconds * 1000), BallonTipTitle, BallonTipText, ToolTipIcon.Error);
}
///
/// Pops up a Warning Ballon over the System Tray Icon
///
/// Specify the Timeout in Seconds
//public void ShowBallon_Warning(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds = 10)
public void ShowBallon_Warning(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds)
{
trayNotify.ShowBalloonTip((nTimeoutInSeconds * 1000), BallonTipTitle, BallonTipText, ToolTipIcon.Warning);
}
///
/// Pops up a Info Ballon over the System Tray Icon
///
/// Specify the Timeout in Seconds
//public void ShowBallon_Info(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds = 10)
public void ShowBallon_Info(string BallonTipTitle, string BallonTipText, int nTimeoutInSeconds)
{
trayNotify.ShowBalloonTip((nTimeoutInSeconds * 1000), BallonTipTitle, BallonTipText, ToolTipIcon.Info);
}
#endregion
}
}