Toasts – Diff between revs 15 and 16

Subversion Repositories:
Rev:
Show entire fileIgnore whitespace
Rev 15 Rev 16
Line 2... Line 2...
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.Concurrent;
-   7 using System.Collections.Generic;
6 using System.Collections.Concurrent; 8 using System.Diagnostics;
7 using System.Drawing; 9 using System.Drawing;
8 using System.IO; 10 using System.IO;
9 using System.Linq; 11 using System.Linq;
-   12 using System.Media;
-   13 using System.Threading;
10 using System.Media; 14 using System.Threading.Tasks;
11 using System.Windows.Forms; 15 using System.Windows.Forms;
Line 12... Line 16...
12 using Toasts.Properties; 16 using Toasts.Properties;
13   17  
14 namespace Toasts 18 namespace Toasts
15 { 19 {
16 public partial class ToastForm : Form 20 public partial class ToastForm : Form
Line -... Line 21...
-   21 {
-   22 #region Static Fields and Constants
17 { 23  
Line 18... Line 24...
18 #region Static Fields and Constants 24 private static readonly object OpenNotificationsLock = new object();
Line 19... Line 25...
19   25  
Line 45... Line 51...
45 #region Constructors, Destructors and Finalizers 51 #region Constructors, Destructors and Finalizers
Line 46... Line 52...
46   52  
47 private ToastForm() 53 private ToastForm()
48 { 54 {
-   55 InitializeComponent();
-   56 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20));
-   57
-   58 _screenWidth = Screen.PrimaryScreen.WorkingArea.Width;
Line -... Line 59...
-   59 _screenHeight = Screen.PrimaryScreen.WorkingArea.Height;
-   60  
-   61 _formAnimator = new FormAnimator(this, FormAnimator.AnimationMethod.Slide, FormAnimator.AnimationDirection.Up,
49 InitializeComponent(); 62 500);
50   63
51 foreach (var control in Controls.Cast<Control>()) 64 using (var memoryStream = new MemoryStream())
-   65 {
52 { 66 Resources.normal.CopyTo(memoryStream);
Line 53... Line 67...
53 control.Click += Toast_Click; 67  
-   68 memoryStream.Position = 0L;
Line 54... Line 69...
54 } 69  
55   70 _sound = memoryStream.ToArray();
56 Click += Toast_Click; 71 }
57   72  
Line 70... Line 85...
70 { 85 {
71 _toastTimer.Enabled = false; 86 _toastTimer.Enabled = false;
72 labelTitle.Text = title; 87 labelTitle.Text = title;
73 labelBody.Text = body; 88 labelBody.Text = body;
74 imageBox.Image = logo; 89 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 } 90 }
Line 81... Line 91...
81   91  
82 /// <summary> 92 /// <summary>
83 /// Display a toast on screen. 93 /// Display a toast on screen.
Line 100... Line 110...
100 imageBox.Image = logo; 110 imageBox.Image = logo;
101 BackgroundImage = background; 111 BackgroundImage = background;
Line 102... Line 112...
102   112  
Line 103... Line 113...
103 _sound = sound; 113 _sound = sound;
104   -  
105 _animator = new FormAnimator(this, animation, direction, 500); -  
106   114  
Line 107... Line 115...
107 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20)); 115 _formAnimator = new FormAnimator(this, animation, direction, 500);
108 } 116 }
109   117  
Line 126... Line 134...
126 labelBody.Text = body; 134 labelBody.Text = body;
127 imageBox.Image = logo; 135 imageBox.Image = logo;
Line 128... Line 136...
128   136  
Line 129... Line 137...
129 _sound = sound; 137 _sound = sound;
130   -  
131 _animator = new FormAnimator(this, animation, direction, 500); -  
132   138  
Line 133... Line 139...
133 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20)); 139 _formAnimator = new FormAnimator(this, animation, direction, 500);
134 } 140 }
135   141  
Line 148... Line 154...
148 labelTitle.Text = title; 154 labelTitle.Text = title;
149 labelBody.Text = body; 155 labelBody.Text = body;
150 imageBox.Image = logo; 156 imageBox.Image = logo;
Line 151... Line 157...
151   157  
152 _sound = sound; -  
153   -  
154 _animator = new FormAnimator(this, FormAnimator.AnimationMethod.Slide, FormAnimator.AnimationDirection.Up, -  
155 500); -  
156   -  
157 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20)); 158 _sound = sound;
Line 158... Line 159...
158 } 159 }
159   160  
160 /// <summary> 161 /// <summary>
Line 169... Line 170...
169 _toastTimer.Enabled = true; 170 _toastTimer.Enabled = true;
170 _toastTimer.Interval = duration; 171 _toastTimer.Interval = duration;
171 labelTitle.Text = title; 172 labelTitle.Text = title;
172 labelBody.Text = body; 173 labelBody.Text = body;
173 imageBox.Image = logo; 174 imageBox.Image = logo;
174   -  
175 _animator = new FormAnimator(this, FormAnimator.AnimationMethod.Slide, FormAnimator.AnimationDirection.Up, -  
176 500); -  
177   -  
178 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20)); -  
179 } 175 }
Line 180... Line 176...
180   176  
181 /// <summary> 177 /// <summary>
182 /// Display a toast on screen. 178 /// Display a toast on screen.
Line 189... Line 185...
189 { 185 {
190 _toastTimer.Interval = duration; 186 _toastTimer.Interval = duration;
191 labelTitle.Text = title; 187 labelTitle.Text = title;
192 labelBody.Text = body; 188 labelBody.Text = body;
193 imageBox.Image = logo.ToBitmap(); 189 imageBox.Image = logo.ToBitmap();
194   -  
195 _animator = new FormAnimator(this, FormAnimator.AnimationMethod.Slide, FormAnimator.AnimationDirection.Up, -  
196 500); -  
197   -  
198 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20)); -  
199 } 190 }
Line 200... Line 191...
200   191  
201 /// <summary> 192 /// <summary>
202 /// Clean up any resources being used. 193 /// Clean up any resources being used.
203 /// </summary> 194 /// </summary>
204 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 195 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
205 protected override void Dispose(bool disposing) 196 protected override void Dispose(bool disposing)
206 { 197 {
-   198 if (disposing && components != null)
-   199 {
-   200 if (_toastTimer != null)
-   201 {
-   202 _toastTimer.Dispose();
-   203 _toastTimer = null;
-   204 }
-   205  
-   206 components.Dispose();
207 if (disposing && components != null) components.Dispose(); 207 }
208 base.Dispose(disposing); 208 base.Dispose(disposing);
Line 209... Line 209...
209 } 209 }
Line 210... Line 210...
210   210  
Line 211... Line 211...
211 #endregion 211 #endregion
Line 212... Line 212...
212   212  
Line 213... Line 213...
213 #region Private Delegates, Events, Enums, Properties, Indexers and Fields 213 #region Private Delegates, Events, Enums, Properties, Indexers and Fields
-   214  
-   215 private readonly FormAnimator _formAnimator;
-   216  
-   217 private readonly byte[] _sound;
Line 214... Line 218...
214   218  
Line 215... Line 219...
215 private readonly FormAnimator _animator; 219 private System.Timers.Timer _toastTimer;
Line 216... Line 220...
216   220  
217 private byte[] _sound; 221 private readonly int _screenWidth;
218   -  
219 private readonly System.Timers.Timer _toastTimer; -  
220   -  
221 #endregion -  
222   -  
223 #region Event Handlers -  
224   222  
225 private void Notification_Load(object sender, EventArgs e) -  
226 { -  
227 // Play the sound. -  
228 if (_sound == null) -  
229 using (var memoryStream = new MemoryStream()) -  
230 { 223 private readonly int _screenHeight;
231 Resources.normal.CopyTo(memoryStream); 224  
232   225 #endregion
-   226  
-   227 #region Event Handlers
233 memoryStream.Position = 0L; 228  
-   229 private void Notification_Load(object sender, EventArgs e)
234   230 {
235 _sound = memoryStream.ToArray(); 231 Task.Factory.StartNew(() =>
Line 236... Line -...
236 } -  
237   232 {
238 using (var memoryStream = new MemoryStream(_sound)) 233 using (var memoryStream = new MemoryStream(_sound))
239 { 234 {
240 using (var player = new SoundPlayer(memoryStream)) 235 using (var player = new SoundPlayer(memoryStream))
-   236 {
-   237 player.Play();
241 { 238 }
242 player.Play(); 239 }
-   240 });
-   241  
-   242 try
-   243 {
-   244 lock (OpenNotificationsLock)
-   245 {
-   246 var notifications = OpenNotifications.ToArray();
-   247  
-   248 foreach (var openForm in notifications)
-   249 {
-   250 if (openForm == null)
-   251 {
-   252 continue;
-   253 }
-   254  
-   255 if (openForm.IsDisposed)
-   256 {
-   257 OpenNotifications.Remove(openForm);
-   258  
-   259 continue;
-   260 }
-   261  
-   262 if (openForm.IsHandleCreated != true)
-   263 {
-   264 continue;
-   265 }
-   266  
-   267 // Move each open form upwards to make room for this one
243 } 268 var handle = Handle;
-   269 openForm.BeginInvoke(new MethodInvoker(() =>
-   270 {
-   271 try
-   272 {
-   273 if (openForm.Handle == handle)
-   274 {
244 } 275 return;
Line 245... Line 276...
245   276 }
-   277  
-   278 openForm.Top -= Height;
-   279 }
Line 246... Line 280...
246 // Move each open form upwards to make room for this one 280 catch
247 foreach (var openForm in OpenNotifications.Values) -  
Line -... Line 281...
-   281 {
-   282 Debug.WriteLine("Error while moving forms up.");
-   283 }
248 { 284 }));
-   285 }
-   286  
249 if (openForm.InvokeRequired) 287 Invoke(new MethodInvoker(() =>
250 { -  
251 void Move() -  
252 { -  
253 openForm.Top -= Height; -  
254 } -  
255   -  
256 openForm.Invoke((Action)Move); -  
257   -  
258 continue; 288 {
259 } 289 Location = new Point(_screenWidth - Width, _screenHeight - Height);
260   290 }));
261 openForm.Top -= Height; 291  
262 } 292 OpenNotifications.Add(this);
Line 263... Line -...
263   -  
264 // Display the form just above the system tray. -  
265 Location = new Point(Screen.PrimaryScreen.WorkingArea.Width - Width, -  
266 Screen.PrimaryScreen.WorkingArea.Height - Height); -  
267   -  
268 OpenNotifications.TryAdd(Handle, this); -  
269   -  
270 // Only start the timer if it has been enabled in the constructor. 293  
271 if (_toastTimer.Enabled) 294 // Only start the timer if it has been enabled in the constructor.
272 { 295 if (_toastTimer.Enabled)
273 _toastTimer.Start(); -  
274 } 296 {
275 } -  
276   -  
277 private void Notification_Shown(object sender, EventArgs e) -  
278 { 297 _toastTimer.Start();
279 // Close the form by sliding down. 298 }
280 _animator.Duration = 0; -  
281 _animator.Direction = FormAnimator.AnimationDirection.Down; -  
282 } -  
283   -  
284 private void Notification_FormClosed(object sender, FormClosedEventArgs e) -  
285 { 299 }
286 // Move down any open forms above this one -  
287 foreach (var openForm in OpenNotifications.Values) -  
288 { 300 }
289 if (openForm.Handle == Handle) -  
290 continue; -  
291   301 catch
-   302 {
-   303 Debug.WriteLine("Error on form load event.");
-   304 }
-   305 }
-   306  
Line 292... Line 307...
292 if (openForm.InvokeRequired) 307 private void Notification_FormClosed(object sender, FormClosedEventArgs e)
-   308 {
-   309 try
-   310 {
-   311 lock (OpenNotificationsLock)
-   312 {
-   313 OpenNotifications.Remove(this);
-   314 }
-   315 }
-   316 catch
-   317 {
-   318 Debug.WriteLine("Error in form closed event.");
-   319 }
-   320 }
-   321  
-   322 private void Notification_Shown(object sender, EventArgs e)
-   323 {
-   324 // Reverse animation direction for hiding.
293 { 325 switch (_formAnimator.Direction)
Line 294... Line 326...
294 void Move() 326 {
295 { 327 case FormAnimator.AnimationDirection.Up:
296 openForm.Top += Height; 328 _formAnimator.Direction = FormAnimator.AnimationDirection.Down;
297 } 329 break;
298   -  
299 openForm.Invoke((Action)Move); -  
300   330 case FormAnimator.AnimationDirection.Down:
301 continue; 331 _formAnimator.Direction = FormAnimator.AnimationDirection.Up;
Line -... Line 332...
-   332 break;
-   333 case FormAnimator.AnimationDirection.Left:
-   334 _formAnimator.Direction = FormAnimator.AnimationDirection.Right;
-   335 break;
-   336 case FormAnimator.AnimationDirection.Right:
-   337 _formAnimator.Direction = FormAnimator.AnimationDirection.Left;
-   338 break;
-   339 }
-   340 }
302 } 341  
-   342 private void ToastTimer_Elapsed(object sender, EventArgs e)
-   343 {
-   344 if (IsDisposed)
-   345 {
-   346 return;
303   347 }
Line 304... Line 348...
304 openForm.Top += Height; 348  
305 } 349 try
-   350 {
-   351 _toastTimer.Stop();
-   352 BeginInvoke(new MethodInvoker(() =>
-   353 {
306   354 lock (OpenNotificationsLock)
-   355 {
-   356 Close();
-   357 }
-   358 }));
-   359 }
-   360 catch
307 OpenNotifications.TryRemove(Handle, out _); 361 {
Line 308... Line 362...
308 } 362 Debug.WriteLine("Error in timer elapsed event.");
309   363 }
310 private void ToastTimer_Elapsed(object sender, EventArgs e) 364 }
311 { 365