Toasts – Blame information for rev 8

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 // =====COPYRIGHT=====
2 // Code originally retrieved from http://www.vbforums.com/showthread.php?t=547778 - no license information supplied
3 // =====COPYRIGHT=====
4  
5 using System;
6 using System.Collections.Generic;
7 using System.Drawing;
8 office 8 using System.IO;
9 using System.Media;
10 using System.Reflection;
11 using System.Threading.Tasks;
1 office 12 using System.Windows.Forms;
13  
14 namespace Toasts
15 {
2 office 16 public partial class ToastForm : Form
1 office 17 {
18 #region Static Fields and Constants
19  
2 office 20 private static readonly List<ToastForm> OpenNotifications = new List<ToastForm>();
1 office 21  
22 #endregion
23  
2 office 24 #region Public Methods
25  
26 /// <summary>
27 /// Displays the form
28 /// </summary>
29 /// <remarks>
30 /// Required to allow the form to determine the current foreground window before being displayed
31 /// </remarks>
32 public new void Show()
33 {
34 // Determine the current foreground window so it can be reactivated each time this form tries to get the focus
35 _currentForegroundWindow = NativeMethods.GetForegroundWindow();
36  
37 base.Show();
38 }
39  
40 #endregion
41  
8 office 42 #region Private Methods
43  
44 private static async Task<byte[]> LoadResource(string resource)
45 {
46 var assembly = Assembly.GetExecutingAssembly();
47  
48 using (var manifestResourceStream = assembly.GetManifestResourceStream(resource))
49 {
50 if (manifestResourceStream == null)
51 {
52 return null;
53 }
54  
55 var memoryStream = new MemoryStream();
56  
57 await manifestResourceStream.CopyToAsync(memoryStream);
58  
59 memoryStream.Position = 0L;
60  
61 return memoryStream.ToArray();
62 }
63 }
64  
65 #endregion
66  
1 office 67 #region Constructors, Destructors and Finalizers
68  
8 office 69 private ToastForm()
7 office 70 {
71 InitializeComponent();
72 }
8 office 73  
1 office 74 /// <summary>
75 /// </summary>
76 /// <param name="title"></param>
77 /// <param name="body"></param>
78 /// <param name="duration"></param>
79 /// <param name="image"></param>
80 /// <param name="animation"></param>
81 /// <param name="direction"></param>
8 office 82 public ToastForm(string title, string body, int duration, Image logo, Image background, byte[] sound,
7 office 83 FormAnimator.AnimationMethod animation, FormAnimator.AnimationDirection direction) : this()
1 office 84 {
85 lifeTimer.Interval = duration;
86 labelTitle.Text = title;
87 labelBody.Text = body;
88 imageBox.Image = logo;
89 BackgroundImage = background;
90  
8 office 91 _sound = sound;
92  
1 office 93 _animator = new FormAnimator(this, animation, direction, 500);
94  
95 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20));
96 }
97  
8 office 98 public ToastForm(string title, string body, int duration, Image logo, byte[] sound,
7 office 99 FormAnimator.AnimationMethod animation, FormAnimator.AnimationDirection direction) : this()
2 office 100 {
101 lifeTimer.Interval = duration;
102 labelTitle.Text = title;
103 labelBody.Text = body;
104 imageBox.Image = logo;
1 office 105  
8 office 106 _sound = sound;
107  
2 office 108 _animator = new FormAnimator(this, animation, direction, 500);
109  
110 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20));
111 }
112  
8 office 113 public ToastForm(string title, string body, int duration, Image logo, byte[] sound) : this()
1 office 114 {
2 office 115 lifeTimer.Interval = duration;
116 labelTitle.Text = title;
117 labelBody.Text = body;
118 imageBox.Image = logo;
119  
8 office 120 _sound = sound;
121  
2 office 122 _animator = new FormAnimator(this, FormAnimator.AnimationMethod.Slide, FormAnimator.AnimationDirection.Up,
123 500);
124  
125 Region = Region.FromHrgn(NativeMethods.CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 20, 20));
1 office 126 }
127  
7 office 128 /// <summary>
129 /// Clean up any resources being used.
130 /// </summary>
131 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
132 protected override void Dispose(bool disposing)
133 {
134 if (disposing && (components != null))
135 {
136 components.Dispose();
137 }
138 base.Dispose(disposing);
139 }
140  
1 office 141 #endregion
142  
143 #region Private Delegates, Events, Enums, Properties, Indexers and Fields
144  
145 private readonly FormAnimator _animator;
146  
147 private bool _allowFocus;
148  
149 private IntPtr _currentForegroundWindow;
150  
8 office 151 private byte[] _sound;
152  
1 office 153 #endregion
154  
155 #region Event Handlers
156  
8 office 157 private async void Notification_Load(object sender, EventArgs e)
1 office 158 {
8 office 159 // Play the sound.
160 if (_sound == null)
161 {
162 _sound = await LoadResource($"Toasts.Sounds.default.wav");
163 }
164  
165 using (var memoryStream = new MemoryStream(_sound))
166 {
167 using (var player = new SoundPlayer(memoryStream))
168 {
169 player.Play();
170 }
171 }
172  
1 office 173 // Display the form just above the system tray.
174 Location = new Point(Screen.PrimaryScreen.WorkingArea.Width - Width,
175 Screen.PrimaryScreen.WorkingArea.Height - Height);
176  
177 // Move each open form upwards to make room for this one
4 office 178 foreach (var openForm in OpenNotifications)
179 {
180 if (openForm.InvokeRequired)
181 {
182 Action action = delegate { openForm.Top -= Height; };
183 openForm.Invoke(action);
7 office 184  
185 continue;
4 office 186 }
1 office 187  
4 office 188 openForm.Top -= Height;
189 }
190  
1 office 191 OpenNotifications.Add(this);
192 lifeTimer.Start();
193 }
194  
195 private void Notification_Activated(object sender, EventArgs e)
196 {
197 // Prevent the form taking focus when it is initially shown
198 if (!_allowFocus)
7 office 199 {
1 office 200 // Activate the window that previously had focus
201 NativeMethods.SetForegroundWindow(_currentForegroundWindow);
7 office 202 }
1 office 203 }
204  
205 private void Notification_Shown(object sender, EventArgs e)
206 {
207 // Once the animation has completed the form can receive focus
208 _allowFocus = true;
209  
210 // Close the form by sliding down.
211 _animator.Duration = 0;
212 _animator.Direction = FormAnimator.AnimationDirection.Down;
213 }
214  
215 private void Notification_FormClosed(object sender, FormClosedEventArgs e)
216 {
217 // Move down any open forms above this one
218 foreach (var openForm in OpenNotifications)
219 {
220 if (openForm == this)
221 // Remaining forms are below this one
222 break;
223  
7 office 224 if (openForm.InvokeRequired)
225 {
226 Action action = delegate { openForm.Top += Height; };
227 openForm.Invoke(action);
228  
229 continue;
230 }
1 office 231 }
232  
233 OpenNotifications.Remove(this);
234 }
235  
236 private void LifeTimer_Tick(object sender, EventArgs e)
237 {
238 Close();
239 }
240  
241 private void Notification_Click(object sender, EventArgs e)
242 {
243 Close();
244 }
245  
246 private void LabelTitle_Click(object sender, EventArgs e)
247 {
248 Close();
249 }
250  
251 private void LabelRO_Click(object sender, EventArgs e)
252 {
253 Close();
254 }
255  
256 #endregion
257 }
258 }