// hardcodet.net NotifyIcon for WPF
// Copyright (c) 2009 - 2013 Philipp Sumi
// Contact and Information: http://www.hardcodet.net
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Code Project Open License (CPOL);
// either version 1.0 of the License, or (at your option) any later
// version.
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Resources;
using System.Windows.Threading;
using Hardcodet.Wpf.TaskbarNotification.Interop;
namespace Hardcodet.Wpf.TaskbarNotification
{
///
/// Util and extension methods.
///
internal static class Util
{
public static readonly object SyncRoot = new object();
#region IsDesignMode
private static readonly bool isDesignMode;
///
/// Checks whether the application is currently in design mode.
///
public static bool IsDesignMode
{
get { return isDesignMode; }
}
#endregion
#region construction
static Util()
{
isDesignMode =
(bool)
DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty,
typeof (FrameworkElement))
.Metadata.DefaultValue;
}
#endregion
#region CreateHelperWindow
///
/// Creates an transparent window without dimension that
/// can be used to temporarily obtain focus and/or
/// be used as a window message sink.
///
/// Empty window.
public static Window CreateHelperWindow()
{
return new Window
{
Width = 0,
Height = 0,
ShowInTaskbar = false,
WindowStyle = WindowStyle.None,
AllowsTransparency = true,
Opacity = 0
};
}
#endregion
#region WriteIconData
///
/// Updates the taskbar icons with data provided by a given
/// instance.
///
/// Configuration settings for the NotifyIcon.
/// Operation on the icon (e.g. delete the icon).
/// True if the data was successfully written.
/// See Shell_NotifyIcon documentation on MSDN for details.
public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command)
{
return WriteIconData(ref data, command, data.ValidMembers);
}
///
/// Updates the taskbar icons with data provided by a given
/// instance.
///
/// Configuration settings for the NotifyIcon.
/// Operation on the icon (e.g. delete the icon).
/// Defines which members of the
/// structure are set.
/// True if the data was successfully written.
/// See Shell_NotifyIcon documentation on MSDN for details.
public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command, IconDataMembers flags)
{
//do nothing if in design mode
if (IsDesignMode) return true;
data.ValidMembers = flags;
lock (SyncRoot)
{
return WinApi.Shell_NotifyIcon(command, ref data);
}
}
#endregion
#region GetBalloonFlag
///
/// Gets a enum value that
/// matches a given .
///
public static BalloonFlags GetBalloonFlag(this BalloonIcon icon)
{
switch (icon)
{
case BalloonIcon.None:
return BalloonFlags.None;
case BalloonIcon.Info:
return BalloonFlags.Info;
case BalloonIcon.Warning:
return BalloonFlags.Warning;
case BalloonIcon.Error:
return BalloonFlags.Error;
default:
throw new ArgumentOutOfRangeException("icon");
}
}
#endregion
#region ImageSource to Icon
///
/// Reads a given image resource into a WinForms icon.
///
/// Image source pointing to
/// an icon file (*.ico).
/// An icon object that can be used with the
/// taskbar area.
public static Icon ToIcon(this ImageSource imageSource)
{
if (imageSource == null) return null;
Uri uri = new Uri(imageSource.ToString());
StreamResourceInfo streamInfo = Application.GetResourceStream(uri);
if (streamInfo == null)
{
string msg = "The supplied image source '{0}' could not be resolved.";
msg = string.Format(msg, imageSource);
throw new ArgumentException(msg);
}
return new Icon(streamInfo.Stream);
}
#endregion
#region evaluate listings
///
/// Checks a list of candidates for equality to a given
/// reference value.
///
///
/// The evaluated value.
/// A liste of possible values that are
/// regarded valid.
/// True if one of the submitted
/// matches the evaluated value. If the
/// parameter itself is null, too, the method returns false as well,
/// which allows to check with null values, too.
/// If
/// is a null reference.
public static bool Is(this T value, params T[] candidates)
{
if (candidates == null) return false;
foreach (var t in candidates)
{
if (value.Equals(t)) return true;
}
return false;
}
#endregion
#region match MouseEvent to PopupActivation
///
/// Checks if a given is a match for
/// an effectively pressed mouse button.
///
public static bool IsMatch(this MouseEvent me, PopupActivationMode activationMode)
{
switch (activationMode)
{
case PopupActivationMode.LeftClick:
return me == MouseEvent.IconLeftMouseUp;
case PopupActivationMode.RightClick:
return me == MouseEvent.IconRightMouseUp;
case PopupActivationMode.LeftOrRightClick:
return me.Is(MouseEvent.IconLeftMouseUp, MouseEvent.IconRightMouseUp);
case PopupActivationMode.LeftOrDoubleClick:
return me.Is(MouseEvent.IconLeftMouseUp, MouseEvent.IconDoubleClick);
case PopupActivationMode.DoubleClick:
return me.Is(MouseEvent.IconDoubleClick);
case PopupActivationMode.MiddleClick:
return me == MouseEvent.IconMiddleMouseUp;
case PopupActivationMode.All:
//return true for everything except mouse movements
return me != MouseEvent.MouseMove;
default:
throw new ArgumentOutOfRangeException("activationMode");
}
}
#endregion
#region execute command
///
/// Executes a given command if its method
/// indicates it can run.
///
/// The command to be executed, or a null reference.
/// An optional parameter that is associated with
/// the command.
/// The target element on which to raise the command.
public static void ExecuteIfEnabled(this ICommand command, object commandParameter, IInputElement target)
{
if (command == null) return;
RoutedCommand rc = command as RoutedCommand;
if (rc != null)
{
//routed commands work on a target
if (rc.CanExecute(commandParameter, target)) rc.Execute(commandParameter, target);
}
else if (command.CanExecute(commandParameter))
{
command.Execute(commandParameter);
}
}
#endregion
///
/// Returns a dispatcher for multi-threaded scenarios
///
/// Dispatcher
internal static Dispatcher GetDispatcher(this DispatcherObject source)
{
//use the application's dispatcher by default
if (Application.Current != null) return Application.Current.Dispatcher;
//fallback for WinForms environments
if (source.Dispatcher != null) return source.Dispatcher;
// ultimately use the thread's dispatcher
return Dispatcher.CurrentDispatcher;
}
///
/// Checks whether the
/// is bound or not.
///
/// The element to be checked.
/// True if the data context property is being managed by a
/// binding expression.
/// If
/// is a null reference.
public static bool IsDataContextDataBound(this FrameworkElement element)
{
if (element == null) throw new ArgumentNullException("element");
return element.GetBindingExpression(FrameworkElement.DataContextProperty) != null;
}
}
}