Toasts – Diff between revs 12 and 15

Subversion Repositories:
Rev:
Show entire fileIgnore whitespace
Rev 12 Rev 15
Line 1... Line 1...
1 // =====COPYRIGHT===== 1 // =====COPYRIGHT=====
2 // Code originally retrieved from http://www.vbforums.com/showthread.php?t=547778 - no license information supplied 2 // Code originally retrieved from http://www.vbforums.com/showthread.php?t=547778 - no license information supplied
3 // =====COPYRIGHT===== 3 // =====COPYRIGHT=====
Line 4... Line 4...
4   4  
5 using System; 5 using System;
6 using System.Collections.Generic; 6 using System.Collections.Concurrent;
7 using System.Drawing; 7 using System.Drawing;
-   8 using System.IO;
8 using System.IO; 9 using System.Linq;
9 using System.Media; 10 using System.Media;
10 using System.Windows.Forms; 11 using System.Windows.Forms;
Line 11... Line 12...
11 using Toasts.Properties; 12 using Toasts.Properties;
12   13  
13 namespace Toasts 14 namespace Toasts
14 { 15 {
15 public partial class ToastForm : Form 16 public partial class ToastForm : Form
Line 16... Line 17...
16 { 17 {
17 #region Static Fields and Constants -  
18   -  
19 private static readonly List<ToastForm> OpenNotifications = new List<ToastForm>(); -  
20   -  
21 #endregion -  
22   -  
23 #region Public Methods -  
24   -  
25 /// <summary> -  
26 /// Displays the form -  
27 /// </summary> -  
28 /// <remarks> -  
29 /// Required to allow the form to determine the current foreground window before being displayed -  
30 /// </remarks> -  
31 public new void Show() -  
32 { -  
33 // Determine the current foreground window so it can be reactivated each time this form tries to get the focus -  
34 _currentForegroundWindow = NativeMethods.GetForegroundWindow(); -  
Line 35... Line 18...
35   18 #region Static Fields and Constants
Line 36... Line 19...
36 base.Show(); 19  
Line 62... Line 45...
62 #region Constructors, Destructors and Finalizers 45 #region Constructors, Destructors and Finalizers
Line 63... Line 46...
63   46  
64 private ToastForm() 47 private ToastForm()
65 { 48 {
-   49 InitializeComponent();
-   50  
-   51 foreach (var control in Controls.Cast<Control>())
-   52 {
-   53 control.Click += Toast_Click;
-   54 }
-   55  
-   56 Click += Toast_Click;
-   57  
-   58 _toastTimer = new System.Timers.Timer();
-   59 _toastTimer.Elapsed += ToastTimer_Elapsed;
66 InitializeComponent(); 60 _toastTimer.Enabled = false;
Line 67... Line 61...
67 } 61 }
-   62  
68   63 /// <summary>
69 /// <summary> 64 /// Display a toast with a title, body and a logo indefinitely on screen.
70 /// </summary> 65 /// </summary>
71 /// <param name="title"></param> 66 /// <param name="title">the toast title</param>
-   67 /// <param name="body">the toast body</param>
-   68 /// <param name="logo">the toast logo</param>
-   69 public ToastForm(string title, string body, Image logo) : this()
-   70 {
-   71 _toastTimer.Enabled = false;
-   72 labelTitle.Text = title;
-   73 labelBody.Text = body;
-   74 imageBox.Image = logo;
-   75  
-   76 _animator = new FormAnimator(this, FormAnimator.AnimationMethod.Slide, FormAnimator.AnimationDirection.Up,
-   77 500);
-   78  
-   79 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20));
-   80 }
-   81  
-   82 /// <summary>
72 /// <param name="body"></param> 83 /// Display a toast on screen.
73 /// <param name="duration"></param> 84 /// </summary>
-   85 /// <param name="title">the toast title</param>
74 /// <param name="image"></param> 86 /// <param name="body">the toast body</param>
-   87 /// <param name="duration">the duration in milliseconds to display the toast on screen for</param>
-   88 /// <param name="logo">the toast logo</param>
-   89 /// <param name="background">the background image for the toast</param>
-   90 /// <param name="sound">a sound to play when the toast is displayed</param>
75 /// <param name="animation"></param> 91 /// <param name="animation">the form animation type <see cref="FormAnimator"/></param>
76 /// <param name="direction"></param> 92 /// <param name="direction">the form animation direction <see cref="FormAnimator"/></param>
77 public ToastForm(string title, string body, int duration, Image logo, Image background, byte[] sound, 93 public ToastForm(string title, string body, int duration, Image logo, Image background, byte[] sound,
-   94 FormAnimator.AnimationMethod animation, FormAnimator.AnimationDirection direction) : this()
78 FormAnimator.AnimationMethod animation, FormAnimator.AnimationDirection direction) : this() 95 {
79 { 96 _toastTimer.Enabled = true;
80 lifeTimer.Interval = duration; 97 _toastTimer.Interval = duration;
81 labelTitle.Text = title; 98 labelTitle.Text = title;
82 labelBody.Text = body; 99 labelBody.Text = body;
Line 88... Line 105...
88 _animator = new FormAnimator(this, animation, direction, 500); 105 _animator = new FormAnimator(this, animation, direction, 500);
Line 89... Line 106...
89   106  
90 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20)); 107 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20));
Line -... Line 108...
-   108 }
-   109  
-   110 /// <summary>
-   111 /// Display a toast on screen.
-   112 /// </summary>
-   113 /// <param name="title">the toast title</param>
-   114 /// <param name="body">the toast body</param>
-   115 /// <param name="duration">the duration in milliseconds to display the toast on screen for</param>
-   116 /// <param name="logo">the toast logo</param>
-   117 /// <param name="sound">a sound to play when the toast is displayed</param>
91 } 118 /// <param name="animation">the form animation type <see cref="FormAnimator"/></param>
92   119 /// <param name="direction">the form animation direction <see cref="FormAnimator"/></param>
93 public ToastForm(string title, string body, int duration, Image logo, byte[] sound, 120 public ToastForm(string title, string body, int duration, Image logo, byte[] sound,
-   121 FormAnimator.AnimationMethod animation, FormAnimator.AnimationDirection direction) : this()
94 FormAnimator.AnimationMethod animation, FormAnimator.AnimationDirection direction) : this() 122 {
95 { 123 _toastTimer.Enabled = true;
96 lifeTimer.Interval = duration; 124 _toastTimer.Interval = duration;
97 labelTitle.Text = title; 125 labelTitle.Text = title;
Line 98... Line 126...
98 labelBody.Text = body; 126 labelBody.Text = body;
Line 103... Line 131...
103 _animator = new FormAnimator(this, animation, direction, 500); 131 _animator = new FormAnimator(this, animation, direction, 500);
Line 104... Line 132...
104   132  
105 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20)); 133 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20));
Line -... Line 134...
-   134 }
-   135  
-   136 /// <summary>
-   137 /// Display a toast on screen.
-   138 /// </summary>
-   139 /// <param name="title">the toast title</param>
-   140 /// <param name="body">the toast body</param>
-   141 /// <param name="duration">the duration in milliseconds to display the toast on screen for</param>
106 } 142 /// <param name="logo">the toast logo</param>
107   143 /// <param name="sound">a sound to play when the toast is displayed</param>
-   144 public ToastForm(string title, string body, int duration, Image logo, byte[] sound) : this()
108 public ToastForm(string title, string body, int duration, Image logo, byte[] sound) : this() 145 {
109 { 146 _toastTimer.Enabled = true;
110 lifeTimer.Interval = duration; 147 _toastTimer.Interval = duration;
111 labelTitle.Text = title; 148 labelTitle.Text = title;
Line 112... Line 149...
112 labelBody.Text = body; 149 labelBody.Text = body;
Line 118... Line 155...
118 500); 155 500);
Line 119... Line 156...
119   156  
120 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20)); 157 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20));
Line -... Line 158...
-   158 }
-   159  
-   160 /// <summary>
-   161 /// Display a toast on screen.
-   162 /// </summary>
-   163 /// <param name="title">the toast title</param>
-   164 /// <param name="body">the toast body</param>
121 } 165 /// <param name="duration">the duration in milliseconds to display the toast on screen for</param>
122   166 /// <param name="logo">the toast logo</param>
-   167 public ToastForm(string title, string body, int duration, Image logo) : this()
123 public ToastForm(string title, string body, int duration, Image logo) : this() 168 {
124 { 169 _toastTimer.Enabled = true;
125 lifeTimer.Interval = duration; 170 _toastTimer.Interval = duration;
126 labelTitle.Text = title; 171 labelTitle.Text = title;
Line 127... Line 172...
127 labelBody.Text = body; 172 labelBody.Text = body;
128 imageBox.Image = logo; 173 imageBox.Image = logo;
Line 129... Line 174...
129   174  
130 _animator = new FormAnimator(this, FormAnimator.AnimationMethod.Slide, FormAnimator.AnimationDirection.Up, 175 _animator = new FormAnimator(this, FormAnimator.AnimationMethod.Slide, FormAnimator.AnimationDirection.Up,
Line -... Line 176...
-   176 500);
-   177  
-   178 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20));
-   179 }
-   180  
-   181 /// <summary>
-   182 /// Display a toast on screen.
131 500); 183 /// </summary>
132   184 /// <param name="title">the toast title</param>
133 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20)); 185 /// <param name="body">the toast body</param>
134 } 186 /// <param name="duration">the duration in milliseconds to display the toast on screen for</param>
135   187 /// <param name="logo">the toast logo</param>
136 public ToastForm(string title, string body, int duration, Icon logo) : this() 188 public ToastForm(string title, string body, int duration, Icon logo) : this()
Line 137... Line 189...
137 { 189 {
Line 160... Line 212...
160   212  
Line 161... Line 213...
161 #region Private Delegates, Events, Enums, Properties, Indexers and Fields 213 #region Private Delegates, Events, Enums, Properties, Indexers and Fields
Line 162... Line -...
162   -  
163 private readonly FormAnimator _animator; -  
164   -  
165 private bool _allowFocus; -  
166   214  
Line -... Line 215...
-   215 private readonly FormAnimator _animator;
-   216  
167 private IntPtr _currentForegroundWindow; 217 private byte[] _sound;
Line 168... Line 218...
168   218  
Line 169... Line 219...
169 private byte[] _sound; 219 private readonly System.Timers.Timer _toastTimer;
Line 191... Line 241...
191 { 241 {
192 player.Play(); 242 player.Play();
193 } 243 }
194 } 244 }
Line 195... Line -...
195   -  
196 // Display the form just above the system tray. -  
197 Location = new Point(Screen.PrimaryScreen.WorkingArea.Width - Width, -  
198 Screen.PrimaryScreen.WorkingArea.Height - Height); -  
199   245  
200 // Move each open form upwards to make room for this one 246 // Move each open form upwards to make room for this one
201 foreach (var openForm in OpenNotifications) 247 foreach (var openForm in OpenNotifications.Values)
202 { 248 {
203 if (openForm.InvokeRequired) 249 if (openForm.InvokeRequired)
-   250 {
-   251 void Move()
204 { 252 {
-   253 openForm.Top -= Height;
-   254 }
205 Action action = delegate { openForm.Top -= Height; }; 255  
Line 206... Line 256...
206 openForm.Invoke(action); 256 openForm.Invoke((Action)Move);
207   257  
Line 208... Line 258...
208 continue; 258 continue;
209 } 259 }
Line 210... Line 260...
210   260  
-   261 openForm.Top -= Height;
211 openForm.Top -= Height; 262 }
212 } -  
Line 213... Line 263...
213   263  
214 OpenNotifications.Add(this); 264 // Display the form just above the system tray.
215 lifeTimer.Start(); 265 Location = new Point(Screen.PrimaryScreen.WorkingArea.Width - Width,
216 } 266 Screen.PrimaryScreen.WorkingArea.Height - Height);
217   267  
218 private void Notification_Activated(object sender, EventArgs e) 268 OpenNotifications.TryAdd(Handle, this);
-   269  
219 { 270 // Only start the timer if it has been enabled in the constructor.
Line 220... Line 271...
220 // Prevent the form taking focus when it is initially shown 271 if (_toastTimer.Enabled)
221 if (!_allowFocus) 272 {
222 // Activate the window that previously had focus -  
223 NativeMethods.SetForegroundWindow(_currentForegroundWindow); -  
224 } -  
225   273 _toastTimer.Start();
226 private void Notification_Shown(object sender, EventArgs e) 274 }
227 { 275 }
228 // Once the animation has completed the form can receive focus 276  
Line 229... Line 277...
229 _allowFocus = true; 277 private void Notification_Shown(object sender, EventArgs e)
230   278 {
231 // Close the form by sliding down. 279 // Close the form by sliding down.
232 _animator.Duration = 0; 280 _animator.Duration = 0;
233 _animator.Direction = FormAnimator.AnimationDirection.Down; 281 _animator.Direction = FormAnimator.AnimationDirection.Down;
234 } 282 }
235   -  
236 private void Notification_FormClosed(object sender, FormClosedEventArgs e) 283  
Line 237... Line 284...
237 { 284 private void Notification_FormClosed(object sender, FormClosedEventArgs e)
238 // Move down any open forms above this one 285 {
-   286 // Move down any open forms above this one
-   287 foreach (var openForm in OpenNotifications.Values)
239 foreach (var openForm in OpenNotifications) 288 {
-   289 if (openForm.Handle == Handle)
-   290 continue;
240 { 291  
-   292 if (openForm.InvokeRequired)
-   293 {
241 if (openForm == this) 294 void Move()
-   295 {
-   296 openForm.Top += Height;
242 // Remaining forms are below this one 297 }
Line 243... Line 298...
243 break; 298  
244   299 openForm.Invoke((Action)Move);
Line 245... Line 300...
245 if (openForm.InvokeRequired) 300  
246 { 301 continue;
247 Action action = delegate { openForm.Top += Height; }; 302 }
248 openForm.Invoke(action); 303  
-   304 openForm.Top += Height;
Line 249... Line -...
249 } -  
250 } -  
251   305 }
252 OpenNotifications.Remove(this); 306  
Line 253... Line -...
253 } -  
254   -  
255 private void LifeTimer_Tick(object sender, EventArgs e) 307 OpenNotifications.TryRemove(Handle, out _);
256 { 308 }
Line 257... Line 309...
257 Close(); 309  
258 } 310 private void ToastTimer_Elapsed(object sender, EventArgs e)
259   311 {
260 private void Notification_Click(object sender, EventArgs e) 312 if (InvokeRequired)
Line 261... Line 313...
261 { 313 {