1 // hardcodet.net NotifyIcon for WPF
2 // Copyright (c) 2009 Philipp Sumi
3 // Contact and Information: http://www.hardcodet.net
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the Code Project Open License (CPOL);
7 // either version 1.0 of the License, or (at your option) any later
10 // The above copyright notice and this permission notice shall be
11 // included in all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 // OTHER DEALINGS IN THE SOFTWARE.
22 // THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE
26 using System.ComponentModel;
29 using System.Windows.Input;
30 using System.Windows.Media;
31 using System.Windows.Resources;
32 using System.Windows.Threading;
33 using Hardcodet.Wpf.TaskbarNotification.Interop;
35 namespace Hardcodet.Wpf.TaskbarNotification
38 /// Util and extension methods.
40 internal static class Util
42 public static readonly object SyncRoot = new object();
46 private static readonly bool isDesignMode;
49 /// Checks whether the application is currently in design mode.
51 public static bool IsDesignMode
53 get { return isDesignMode; }
64 DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof (FrameworkElement))
65 .Metadata.DefaultValue;
70 #region CreateHelperWindow
73 /// Creates an transparent window without dimension that
74 /// can be used to temporarily obtain focus and/or
75 /// be used as a window message sink.
77 /// <returns>Empty window.</returns>
78 public static Window CreateHelperWindow()
84 ShowInTaskbar = false,
85 WindowStyle = WindowStyle.None,
86 AllowsTransparency = true,
96 /// Updates the taskbar icons with data provided by a given
97 /// <see cref="NotifyIconData"/> instance.
99 /// <param name="data">Configuration settings for the NotifyIcon.</param>
100 /// <param name="command">Operation on the icon (e.g. delete the icon).</param>
101 /// <returns>True if the data was successfully written.</returns>
102 /// <remarks>See Shell_NotifyIcon documentation on MSDN for details.</remarks>
103 public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command)
105 return WriteIconData(ref data, command, data.ValidMembers);
110 /// Updates the taskbar icons with data provided by a given
111 /// <see cref="NotifyIconData"/> instance.
113 /// <param name="data">Configuration settings for the NotifyIcon.</param>
114 /// <param name="command">Operation on the icon (e.g. delete the icon).</param>
115 /// <param name="flags">Defines which members of the <paramref name="data"/>
116 /// structure are set.</param>
117 /// <returns>True if the data was successfully written.</returns>
118 /// <remarks>See Shell_NotifyIcon documentation on MSDN for details.</remarks>
119 public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command, IconDataMembers flags)
121 //do nothing if in design mode
122 if (IsDesignMode) return true;
124 data.ValidMembers = flags;
127 return WinApi.Shell_NotifyIcon(command, ref data);
133 #region GetBalloonFlag
136 /// Gets a <see cref="BalloonFlags"/> enum value that
137 /// matches a given <see cref="BalloonIcon"/>.
139 public static BalloonFlags GetBalloonFlag(this BalloonIcon icon)
143 case BalloonIcon.None:
144 return BalloonFlags.None;
145 case BalloonIcon.Info:
146 return BalloonFlags.Info;
147 case BalloonIcon.Warning:
148 return BalloonFlags.Warning;
149 case BalloonIcon.Error:
150 return BalloonFlags.Error;
152 throw new ArgumentOutOfRangeException("icon");
158 #region ImageSource to Icon
161 /// Reads a given image resource into a WinForms icon.
163 /// <param name="imageSource">Image source pointing to
164 /// an icon file (*.ico).</param>
165 /// <returns>An icon object that can be used with the
166 /// taskbar area.</returns>
167 public static Icon ToIcon(this ImageSource imageSource)
169 if (imageSource == null) return null;
171 Uri uri = new Uri(imageSource.ToString());
172 StreamResourceInfo streamInfo = Application.GetResourceStream(uri);
174 if (streamInfo == null)
176 string msg = "The supplied image source '{0}' could not be resolved.";
177 msg = String.Format(msg, imageSource);
178 throw new ArgumentException(msg);
181 return new Icon(streamInfo.Stream);
186 #region evaluate listings
189 /// Checks a list of candidates for equality to a given
192 /// <typeparam name="T"></typeparam>
193 /// <param name="value">The evaluated value.</param>
194 /// <param name="candidates">A liste of possible values that are
195 /// regarded valid.</param>
196 /// <returns>True if one of the submitted <paramref name="candidates"/>
197 /// matches the evaluated value. If the <paramref name="candidates"/>
198 /// parameter itself is null, too, the method returns false as well,
199 /// which allows to check with null values, too.</returns>
200 /// <exception cref="ArgumentNullException">If <paramref name="candidates"/>
201 /// is a null reference.</exception>
202 public static bool Is<T>(this T value, params T[] candidates)
204 if (candidates == null) return false;
206 foreach (var t in candidates)
208 if (value.Equals(t)) return true;
216 #region match MouseEvent to PopupActivation
219 /// Checks if a given <see cref="PopupActivationMode"/> is a match for
220 /// an effectively pressed mouse button.
222 public static bool IsMatch(this MouseEvent me, PopupActivationMode activationMode)
224 switch (activationMode)
226 case PopupActivationMode.LeftClick:
227 return me == MouseEvent.IconLeftMouseUp;
228 case PopupActivationMode.RightClick:
229 return me == MouseEvent.IconRightMouseUp;
230 case PopupActivationMode.LeftOrRightClick:
231 return me.Is(MouseEvent.IconLeftMouseUp, MouseEvent.IconRightMouseUp);
232 case PopupActivationMode.LeftOrDoubleClick:
233 return me.Is(MouseEvent.IconLeftMouseUp, MouseEvent.IconDoubleClick);
234 case PopupActivationMode.DoubleClick:
235 return me.Is(MouseEvent.IconDoubleClick);
236 case PopupActivationMode.MiddleClick:
237 return me == MouseEvent.IconMiddleMouseUp;
238 case PopupActivationMode.All:
239 //return true for everything except mouse movements
240 return me != MouseEvent.MouseMove;
242 throw new ArgumentOutOfRangeException("activationMode");
248 #region execute command
251 /// Executes a given command if its <see cref="ICommand.CanExecute"/> method
252 /// indicates it can run.
254 /// <param name="command">The command to be executed, or a null reference.</param>
255 /// <param name="commandParameter">An optional parameter that is associated with
256 /// the command.</param>
257 /// <param name="target">The target element on which to raise the command.</param>
258 public static void ExecuteIfEnabled(this ICommand command, object commandParameter, IInputElement target)
260 if (command == null) return;
262 RoutedCommand rc = command as RoutedCommand;
265 //routed commands work on a target
266 if (rc.CanExecute(commandParameter, target)) rc.Execute(commandParameter, target);
268 else if (command.CanExecute(commandParameter))
270 command.Execute(commandParameter);
277 /// Returns a dispatcher for multi-threaded scenarios
279 /// <returns></returns>
280 internal static Dispatcher GetDispatcher(this DispatcherObject source)
282 //use the application's dispatcher by default
283 if (Application.Current != null) return Application.Current.Dispatcher;
285 //fallback for WinForms environments
286 if (source.Dispatcher != null) return source.Dispatcher;
288 //ultimatively use the thread's dispatcher
289 return Dispatcher.CurrentDispatcher;
294 /// Checks whether the <see cref="FrameworkElement.DataContextProperty"/>
297 /// <param name="element">The element to be checked.</param>
298 /// <returns>True if the data context property is being managed by a
299 /// binding expression.</returns>
300 /// <exception cref="ArgumentNullException">If <paramref name="element"/>
301 /// is a null reference.</exception>
302 public static bool IsDataContextDataBound(this FrameworkElement element)
304 if (element == null) throw new ArgumentNullException("element");
305 return element.GetBindingExpression(FrameworkElement.DataContextProperty) != null;