Statistics
| Branch: | Revision:

root / trunk / NotifyIconWpf / Util.cs @ 5e31048f

History | View | Annotate | Download (10 kB)

1
// hardcodet.net NotifyIcon for WPF
2
// Copyright (c) 2009 Philipp Sumi
3
// Contact and Information: http://www.hardcodet.net
4
//
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
8
// version.
9
// 
10
// The above copyright notice and this permission notice shall be
11
// included in all copies or substantial portions of the Software.
12
// 
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.
21
//
22
// THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE
23

    
24

    
25
using System;
26
using System.ComponentModel;
27
using System.Drawing;
28
using System.Windows;
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;
34

    
35
namespace Hardcodet.Wpf.TaskbarNotification
36
{
37
  /// <summary>
38
  /// Util and extension methods.
39
  /// </summary>
40
  internal static class Util
41
  {
42
    public static readonly object SyncRoot = new object();
43

    
44
    #region IsDesignMode
45

    
46
    private static readonly bool isDesignMode;
47

    
48
    /// <summary>
49
    /// Checks whether the application is currently in design mode.
50
    /// </summary>
51
    public static bool IsDesignMode
52
    {
53
      get { return isDesignMode; }
54
    }
55

    
56
    #endregion
57

    
58
    #region construction
59

    
60
    static Util()
61
    {
62
      isDesignMode =
63
          (bool)
64
          DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof (FrameworkElement))
65
              .Metadata.DefaultValue;
66
    }
67

    
68
    #endregion
69

    
70
    #region CreateHelperWindow
71

    
72
    /// <summary>
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.
76
    /// </summary>
77
    /// <returns>Empty window.</returns>
78
    public static Window CreateHelperWindow()
79
    {
80
      return new Window
81
               {
82
                   Width = 0,
83
                   Height = 0,
84
                   ShowInTaskbar = false,
85
                   WindowStyle = WindowStyle.None,
86
                   AllowsTransparency = true,
87
                   Opacity = 0
88
               };
89
    }
90

    
91
    #endregion
92

    
93
    #region WriteIconData
94

    
95
    /// <summary>
96
    /// Updates the taskbar icons with data provided by a given
97
    /// <see cref="NotifyIconData"/> instance.
98
    /// </summary>
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)
104
    {
105
      return WriteIconData(ref data, command, data.ValidMembers);
106
    }
107

    
108

    
109
    /// <summary>
110
    /// Updates the taskbar icons with data provided by a given
111
    /// <see cref="NotifyIconData"/> instance.
112
    /// </summary>
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)
120
    {
121
      //do nothing if in design mode
122
      if (IsDesignMode) return true;
123

    
124
      data.ValidMembers = flags;
125
      lock (SyncRoot)
126
      {
127
        return WinApi.Shell_NotifyIcon(command, ref data);
128
      }
129
    }
130

    
131
    #endregion
132

    
133
    #region GetBalloonFlag
134

    
135
    /// <summary>
136
    /// Gets a <see cref="BalloonFlags"/> enum value that
137
    /// matches a given <see cref="BalloonIcon"/>.
138
    /// </summary>
139
    public static BalloonFlags GetBalloonFlag(this BalloonIcon icon)
140
    {
141
      switch (icon)
142
      {
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;
151
        default:
152
          throw new ArgumentOutOfRangeException("icon");
153
      }
154
    }
155

    
156
    #endregion
157

    
158
    #region ImageSource to Icon
159

    
160
    /// <summary>
161
    /// Reads a given image resource into a WinForms icon.
162
    /// </summary>
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)
168
    {
169
      if (imageSource == null) return null;
170

    
171
      Uri uri = new Uri(imageSource.ToString());
172
      StreamResourceInfo streamInfo = Application.GetResourceStream(uri);
173

    
174
      if (streamInfo == null)
175
      {
176
        string msg = "The supplied image source '{0}' could not be resolved.";
177
        msg = String.Format(msg, imageSource);
178
        throw new ArgumentException(msg);
179
      }
180

    
181
      return new Icon(streamInfo.Stream);
182
    }
183

    
184
    #endregion
185

    
186
    #region evaluate listings
187

    
188
    /// <summary>
189
    /// Checks a list of candidates for equality to a given
190
    /// reference value.
191
    /// </summary>
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)
203
    {
204
      if (candidates == null) return false;
205

    
206
      foreach (var t in candidates)
207
      {
208
        if (value.Equals(t)) return true;
209
      }
210

    
211
      return false;
212
    }
213

    
214
    #endregion
215

    
216
    #region match MouseEvent to PopupActivation
217

    
218
    /// <summary>
219
    /// Checks if a given <see cref="PopupActivationMode"/> is a match for
220
    /// an effectively pressed mouse button.
221
    /// </summary>
222
    public static bool IsMatch(this MouseEvent me, PopupActivationMode activationMode)
223
    {
224
      switch (activationMode)
225
      {
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;
241
        default:
242
          throw new ArgumentOutOfRangeException("activationMode");
243
      }
244
    }
245

    
246
    #endregion
247

    
248
    #region execute command
249

    
250
    /// <summary>
251
    /// Executes a given command if its <see cref="ICommand.CanExecute"/> method
252
    /// indicates it can run.
253
    /// </summary>
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)
259
    {
260
      if (command == null) return;
261

    
262
      RoutedCommand rc = command as RoutedCommand;
263
      if (rc != null)
264
      {
265
        //routed commands work on a target
266
        if (rc.CanExecute(commandParameter, target)) rc.Execute(commandParameter, target);
267
      }
268
      else if (command.CanExecute(commandParameter))
269
      {
270
        command.Execute(commandParameter);
271
      }
272
    }
273

    
274
    #endregion
275

    
276
    /// <summary>
277
    /// Returns a dispatcher for multi-threaded scenarios
278
    /// </summary>
279
    /// <returns></returns>
280
    internal static Dispatcher GetDispatcher(this DispatcherObject source)
281
    {
282
      //use the application's dispatcher by default
283
      if (Application.Current != null) return Application.Current.Dispatcher;
284

    
285
      //fallback for WinForms environments
286
      if (source.Dispatcher != null) return source.Dispatcher;
287

    
288
      //ultimatively use the thread's dispatcher
289
      return Dispatcher.CurrentDispatcher;
290
    }
291

    
292

    
293
    /// <summary>
294
    /// Checks whether the <see cref="FrameworkElement.DataContextProperty"/>
295
    ///  is bound or not.
296
    /// </summary>
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)
303
    {
304
      if (element == null) throw new ArgumentNullException("element");
305
      return element.GetBindingExpression(FrameworkElement.DataContextProperty) != null;
306
    }
307
  }
308
}