Statistics
| Branch: | Revision:

root / trunk / NotifyIconWpf / Util.cs @ 7fcbf914

History | View | Annotate | Download (11.1 kB)

1
// hardcodet.net NotifyIcon for WPF
2
// Copyright (c) 2009 - 2013 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,
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
        }
308
    }
309
}