// hardcodet.net NotifyIcon for WPF // Copyright (c) 2009 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 /// /// 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; //ultimatively 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; } } }