Squashed 'NotifyIconWpf/' content from commit 7307bdf
git-subtree-dir: NotifyIconWpf git-subtree-split: 7307bdf5402239df475ea38a0647901cb4b95645
This commit is contained in:
309
NotifyIconWpf/Util.cs
Normal file
309
NotifyIconWpf/Util.cs
Normal file
@@ -0,0 +1,309 @@
|
||||
// hardcodet.net NotifyIcon for WPF
|
||||
// Copyright (c) 2009 - 2020 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
|
||||
{
|
||||
/// <summary>
|
||||
/// Util and extension methods.
|
||||
/// </summary>
|
||||
internal static class Util
|
||||
{
|
||||
public static readonly object SyncRoot = new object();
|
||||
|
||||
#region IsDesignMode
|
||||
|
||||
private static readonly bool isDesignMode;
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the application is currently in design mode.
|
||||
/// </summary>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Creates an transparent window without dimension that
|
||||
/// can be used to temporarily obtain focus and/or
|
||||
/// be used as a window message sink.
|
||||
/// </summary>
|
||||
/// <returns>Empty window.</returns>
|
||||
public static Window CreateHelperWindow()
|
||||
{
|
||||
return new Window
|
||||
{
|
||||
Width = 0,
|
||||
Height = 0,
|
||||
ShowInTaskbar = false,
|
||||
WindowStyle = WindowStyle.None,
|
||||
AllowsTransparency = true,
|
||||
Opacity = 0
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WriteIconData
|
||||
|
||||
/// <summary>
|
||||
/// Updates the taskbar icons with data provided by a given
|
||||
/// <see cref="NotifyIconData"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="data">Configuration settings for the NotifyIcon.</param>
|
||||
/// <param name="command">Operation on the icon (e.g. delete the icon).</param>
|
||||
/// <returns>True if the data was successfully written.</returns>
|
||||
/// <remarks>See Shell_NotifyIcon documentation on MSDN for details.</remarks>
|
||||
public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command)
|
||||
{
|
||||
return WriteIconData(ref data, command, data.ValidMembers);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Updates the taskbar icons with data provided by a given
|
||||
/// <see cref="NotifyIconData"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="data">Configuration settings for the NotifyIcon.</param>
|
||||
/// <param name="command">Operation on the icon (e.g. delete the icon).</param>
|
||||
/// <param name="flags">Defines which members of the <paramref name="data"/>
|
||||
/// structure are set.</param>
|
||||
/// <returns>True if the data was successfully written.</returns>
|
||||
/// <remarks>See Shell_NotifyIcon documentation on MSDN for details.</remarks>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="BalloonFlags"/> enum value that
|
||||
/// matches a given <see cref="BalloonIcon"/>.
|
||||
/// </summary>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Reads a given image resource into a WinForms icon.
|
||||
/// </summary>
|
||||
/// <param name="imageSource">Image source pointing to
|
||||
/// an icon file (*.ico).</param>
|
||||
/// <returns>An icon object that can be used with the
|
||||
/// taskbar area.</returns>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Checks a list of candidates for equality to a given
|
||||
/// reference value.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="value">The evaluated value.</param>
|
||||
/// <param name="candidates">A liste of possible values that are
|
||||
/// regarded valid.</param>
|
||||
/// <returns>True if one of the submitted <paramref name="candidates"/>
|
||||
/// matches the evaluated value. If the <paramref name="candidates"/>
|
||||
/// parameter itself is null, too, the method returns false as well,
|
||||
/// which allows to check with null values, too.</returns>
|
||||
/// <exception cref="ArgumentNullException">If <paramref name="candidates"/>
|
||||
/// is a null reference.</exception>
|
||||
public static bool Is<T>(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
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a given <see cref="PopupActivationMode"/> is a match for
|
||||
/// an effectively pressed mouse button.
|
||||
/// </summary>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Executes a given command if its <see cref="ICommand.CanExecute"/> method
|
||||
/// indicates it can run.
|
||||
/// </summary>
|
||||
/// <param name="command">The command to be executed, or a null reference.</param>
|
||||
/// <param name="commandParameter">An optional parameter that is associated with
|
||||
/// the command.</param>
|
||||
/// <param name="target">The target element on which to raise the command.</param>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Returns a dispatcher for multi-threaded scenarios
|
||||
/// </summary>
|
||||
/// <returns>Dispatcher</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the <see cref="FrameworkElement.DataContextProperty"/>
|
||||
/// is bound or not.
|
||||
/// </summary>
|
||||
/// <param name="element">The element to be checked.</param>
|
||||
/// <returns>True if the data context property is being managed by a
|
||||
/// binding expression.</returns>
|
||||
/// <exception cref="ArgumentNullException">If <paramref name="element"/>
|
||||
/// is a null reference.</exception>
|
||||
public static bool IsDataContextDataBound(this FrameworkElement element)
|
||||
{
|
||||
if (element == null) throw new ArgumentNullException("element");
|
||||
return element.GetBindingExpression(FrameworkElement.DataContextProperty) != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user