Revision 7fcbf914 trunk/NotifyIconWpf/Util.cs

b/trunk/NotifyIconWpf/Util.cs
1 1
// hardcodet.net NotifyIcon for WPF
2
// Copyright (c) 2009 Philipp Sumi
2
// Copyright (c) 2009 - 2013 Philipp Sumi
3 3
// Contact and Information: http://www.hardcodet.net
4 4
//
5 5
// This library is free software; you can redistribute it and/or
......
34 34

  
35 35
namespace Hardcodet.Wpf.TaskbarNotification
36 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 37
    /// <summary>
294
    /// Checks whether the <see cref="FrameworkElement.DataContextProperty"/>
295
    ///  is bound or not.
38
    /// Util and extension methods.
296 39
    /// </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)
40
    internal static class Util
303 41
    {
304
      if (element == null) throw new ArgumentNullException("element");
305
      return element.GetBindingExpression(FrameworkElement.DataContextProperty) != null;
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,
65
                        typeof (FrameworkElement))
66
                        .Metadata.DefaultValue;
67
        }
68

  
69
        #endregion
70

  
71
        #region CreateHelperWindow
72

  
73
        /// <summary>
74
        /// Creates an transparent window without dimension that
75
        /// can be used to temporarily obtain focus and/or
76
        /// be used as a window message sink.
77
        /// </summary>
78
        /// <returns>Empty window.</returns>
79
        public static Window CreateHelperWindow()
80
        {
81
            return new Window
82
            {
83
                Width = 0,
84
                Height = 0,
85
                ShowInTaskbar = false,
86
                WindowStyle = WindowStyle.None,
87
                AllowsTransparency = true,
88
                Opacity = 0
89
            };
90
        }
91

  
92
        #endregion
93

  
94
        #region WriteIconData
95

  
96
        /// <summary>
97
        /// Updates the taskbar icons with data provided by a given
98
        /// <see cref="NotifyIconData"/> instance.
99
        /// </summary>
100
        /// <param name="data">Configuration settings for the NotifyIcon.</param>
101
        /// <param name="command">Operation on the icon (e.g. delete the icon).</param>
102
        /// <returns>True if the data was successfully written.</returns>
103
        /// <remarks>See Shell_NotifyIcon documentation on MSDN for details.</remarks>
104
        public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command)
105
        {
106
            return WriteIconData(ref data, command, data.ValidMembers);
107
        }
108

  
109

  
110
        /// <summary>
111
        /// Updates the taskbar icons with data provided by a given
112
        /// <see cref="NotifyIconData"/> instance.
113
        /// </summary>
114
        /// <param name="data">Configuration settings for the NotifyIcon.</param>
115
        /// <param name="command">Operation on the icon (e.g. delete the icon).</param>
116
        /// <param name="flags">Defines which members of the <paramref name="data"/>
117
        /// structure are set.</param>
118
        /// <returns>True if the data was successfully written.</returns>
119
        /// <remarks>See Shell_NotifyIcon documentation on MSDN for details.</remarks>
120
        public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command, IconDataMembers flags)
121
        {
122
            //do nothing if in design mode
123
            if (IsDesignMode) return true;
124

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

  
132
        #endregion
133

  
134
        #region GetBalloonFlag
135

  
136
        /// <summary>
137
        /// Gets a <see cref="BalloonFlags"/> enum value that
138
        /// matches a given <see cref="BalloonIcon"/>.
139
        /// </summary>
140
        public static BalloonFlags GetBalloonFlag(this BalloonIcon icon)
141
        {
142
            switch (icon)
143
            {
144
                case BalloonIcon.None:
145
                    return BalloonFlags.None;
146
                case BalloonIcon.Info:
147
                    return BalloonFlags.Info;
148
                case BalloonIcon.Warning:
149
                    return BalloonFlags.Warning;
150
                case BalloonIcon.Error:
151
                    return BalloonFlags.Error;
152
                default:
153
                    throw new ArgumentOutOfRangeException("icon");
154
            }
155
        }
156

  
157
        #endregion
158

  
159
        #region ImageSource to Icon
160

  
161
        /// <summary>
162
        /// Reads a given image resource into a WinForms icon.
163
        /// </summary>
164
        /// <param name="imageSource">Image source pointing to
165
        /// an icon file (*.ico).</param>
166
        /// <returns>An icon object that can be used with the
167
        /// taskbar area.</returns>
168
        public static Icon ToIcon(this ImageSource imageSource)
169
        {
170
            if (imageSource == null) return null;
171

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

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

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

  
185
        #endregion
186

  
187
        #region evaluate listings
188

  
189
        /// <summary>
190
        /// Checks a list of candidates for equality to a given
191
        /// reference value.
192
        /// </summary>
193
        /// <typeparam name="T"></typeparam>
194
        /// <param name="value">The evaluated value.</param>
195
        /// <param name="candidates">A liste of possible values that are
196
        /// regarded valid.</param>
197
        /// <returns>True if one of the submitted <paramref name="candidates"/>
198
        /// matches the evaluated value. If the <paramref name="candidates"/>
199
        /// parameter itself is null, too, the method returns false as well,
200
        /// which allows to check with null values, too.</returns>
201
        /// <exception cref="ArgumentNullException">If <paramref name="candidates"/>
202
        /// is a null reference.</exception>
203
        public static bool Is<T>(this T value, params T[] candidates)
204
        {
205
            if (candidates == null) return false;
206

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

  
212
            return false;
213
        }
214

  
215
        #endregion
216

  
217
        #region match MouseEvent to PopupActivation
218

  
219
        /// <summary>
220
        /// Checks if a given <see cref="PopupActivationMode"/> is a match for
221
        /// an effectively pressed mouse button.
222
        /// </summary>
223
        public static bool IsMatch(this MouseEvent me, PopupActivationMode activationMode)
224
        {
225
            switch (activationMode)
226
            {
227
                case PopupActivationMode.LeftClick:
228
                    return me == MouseEvent.IconLeftMouseUp;
229
                case PopupActivationMode.RightClick:
230
                    return me == MouseEvent.IconRightMouseUp;
231
                case PopupActivationMode.LeftOrRightClick:
232
                    return me.Is(MouseEvent.IconLeftMouseUp, MouseEvent.IconRightMouseUp);
233
                case PopupActivationMode.LeftOrDoubleClick:
234
                    return me.Is(MouseEvent.IconLeftMouseUp, MouseEvent.IconDoubleClick);
235
                case PopupActivationMode.DoubleClick:
236
                    return me.Is(MouseEvent.IconDoubleClick);
237
                case PopupActivationMode.MiddleClick:
238
                    return me == MouseEvent.IconMiddleMouseUp;
239
                case PopupActivationMode.All:
240
                    //return true for everything except mouse movements
241
                    return me != MouseEvent.MouseMove;
242
                default:
243
                    throw new ArgumentOutOfRangeException("activationMode");
244
            }
245
        }
246

  
247
        #endregion
248

  
249
        #region execute command
250

  
251
        /// <summary>
252
        /// Executes a given command if its <see cref="ICommand.CanExecute"/> method
253
        /// indicates it can run.
254
        /// </summary>
255
        /// <param name="command">The command to be executed, or a null reference.</param>
256
        /// <param name="commandParameter">An optional parameter that is associated with
257
        /// the command.</param>
258
        /// <param name="target">The target element on which to raise the command.</param>
259
        public static void ExecuteIfEnabled(this ICommand command, object commandParameter, IInputElement target)
260
        {
261
            if (command == null) return;
262

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

  
275
        #endregion
276

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

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

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

  
293

  
294
        /// <summary>
295
        /// Checks whether the <see cref="FrameworkElement.DataContextProperty"/>
296
        ///  is bound or not.
297
        /// </summary>
298
        /// <param name="element">The element to be checked.</param>
299
        /// <returns>True if the data context property is being managed by a
300
        /// binding expression.</returns>
301
        /// <exception cref="ArgumentNullException">If <paramref name="element"/>
302
        /// is a null reference.</exception>
303
        public static bool IsDataContextDataBound(this FrameworkElement element)
304
        {
305
            if (element == null) throw new ArgumentNullException("element");
306
            return element.GetBindingExpression(FrameworkElement.DataContextProperty) != null;
307
        }
306 308
    }
307
  }
308 309
}

Also available in: Unified diff