using System; namespace WeatherAlert ...{ /**////<summary> /// This class describes the arguments used for /// the event arguments when the user opens the window /// via the Toast Window. ///</summary> publicclass ToastSelectEventArgs : System.EventArgs ...{ /**////<summary> /// The object passed back when the user opens his toast. ///</summary> privatereadonlyobject _toastArgs; /**////<summary> /// Retrieve the toast open arguments. ///</summary> publicobject ToastArgs ...{ get ...{ return _toastArgs; } } /**////<summary> /// Single constructor. ///</summary> ///<param name="ToastArgs">The toast arguments.</param> public ToastSelectEventArgs( object ToastArgs ) ...{ _toastArgs = ToastArgs; } } /**////<summary> /// Toast open delegate description. ///</summary> publicdelegatevoid ToastTargetClickHandler( object sender, ToastSelectEventArgs args ); }
Utils.cs
using System; using System.Drawing; using System.Drawing.Drawing2D; namespace WeatherAlert ...{ /**////<summary> /// Utility methods of general use. ///</summary> publicsealedclass Utils ...{ /**////<summary> /// Hidden constructor. ///</summary> private Utils() ...{ } /**////<summary> /// For some reason, GDI+ dropped support for the /// rounded rectangle. Add it back in. ///</summary> ///<param name="rect">The rectangle</param> ///<param name="radius">The radius of the circle that /// inscribes the rounded rect corners.</param> ///<returns>A graphics path surrounding the rounded rect. ///</returns> ///<remarks> /// This method creates a graphics path that can be used to /// draw a rounded rectangle. It is a great way to smooth /// out the rough edges on your windows. ///</remarks> publicstatic GraphicsPath CreateRoundedRectPath( Rectangle rect, int radius ) ...{ GraphicsPath rectPath =new GraphicsPath(); // Add the line on the top: rectPath.AddLine( rect.Left + radius, rect.Top, rect.Right - radius, rect.Top ); // Add the arc at the top right corner: rectPath.AddArc( rect.Right -2* radius, rect.Top, radius *2, radius *2 , 270, 90 ); // Line down the right: rectPath.AddLine( rect.Right, rect.Top + radius, rect.Right, rect.Bottom -10 ); // Bottom Right quarter circle: rectPath.AddArc( rect.Right - radius *2, rect.Bottom - radius *2, radius *2, radius *2, 0, 90 ); // bottom line: rectPath.AddLine( rect.Right -2* radius, rect.Bottom , rect.Left + radius, rect.Bottom ); // Bottom left quarter circle: rectPath.AddArc( rect.Left, rect.Bottom -2* radius, 2* radius, 2* radius, 90, 90 ); // Up the left side: rectPath.AddLine( rect.Left, rect.Bottom - radius, rect.Left, rect.Top + radius ); // Upper left arc: rectPath.AddArc( rect.Left, rect.Top, 2* radius, 2* radius, 180, 90 ); return rectPath; } } }
ToastWindow.cs form
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; namespace WeatherAlert ...{ /**////<summary> /// This is a resuable Toast notification window. ///</summary> ///<remarks> /// The behavior is to fade in a toast window containing the /// message you entered. If the user clicks on the link, an event /// is raised. This is typically used to show the main window, /// or some other more prominent notification. If the user ignores the /// Toast Window, it fades down. /// If a new toast window should be displayed while an existing toast /// is up, the second request is ignored. ///</remarks> publicclass ToastWindow : System.Windows.Forms.Form ...{ /**////<summary> /// The event generated when the user clicks his toast. ///</summary> publicevent ToastTargetClickHandler ToastClick; /**////<summary> /// This enumeration keeps track of what the toast window /// is doing. ///</summary> privateenum ToastState ...{ Nothing, FadeUp, Visible, FadeDown } /**////<summary> /// Is there a toast window up and running? ///</summary> privatestaticbool _toastUp =false; /**////<summary> /// Timer to manage the fade in / fade out. ///</summary> private System.Windows.Forms.Timer timerFadeIn; /**////<summary> /// What is the current Toast Window state? ///</summary> private ToastState toastWindowState; /**////<summary> /// The parameter to send along when the user clicks his toast. ///</summary> privateobject _toastTargetArgs; /**////<summary> /// The message for the toast window. ///</summary> privatestring _message; /**////<summary> /// Close button ///</summary> private System.Windows.Forms.Button buttonClose; /**////<summary> /// Standard included component. ///</summary> private System.ComponentModel.IContainer components; /**////<summary> /// Default constructor ///</summary> public ToastWindow() ...{ // // Required for Windows Form Designer support // InitializeComponent(); } /**////<summary> /// Clean up any resources being used. ///</summary> protectedoverridevoid Dispose( bool disposing ) ...{ if( disposing ) ...{ if(components !=null) ...{ components.Dispose(); } } base.Dispose( disposing ); } Windows Form Designer generated code#region Windows Form Designer generated code /**////<summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. ///</summary> privatevoid InitializeComponent() ...{ this.components =new System.ComponentModel.Container(); System.Resources.ResourceManager resources =new System.Resources.ResourceManager(typeof(ToastWindow)); this.timerFadeIn =new System.Windows.Forms.Timer(this.components); this.buttonClose =new System.Windows.Forms.Button(); this.SuspendLayout(); // // timerFadeIn // this.timerFadeIn.Tick +=new System.EventHandler(this.FadeTick); // // buttonClose // this.buttonClose.Image = ((System.Drawing.Image)(resources.GetObject("buttonClose.Image"))); this.buttonClose.Location =new System.Drawing.Point(256, 8); this.buttonClose.Name ="buttonClose"; this.buttonClose.Size =new System.Drawing.Size(24, 23); this.buttonClose.TabIndex =50; this.buttonClose.Text ="X"; this.buttonClose.Click +=new System.EventHandler(this.buttonClose_Click); this.buttonClose.MouseEnter +=new System.EventHandler(this.EnterCloseBox); this.buttonClose.MouseLeave +=new System.EventHandler(this.LeaveCloseBox); // // ToastWindow // this.AutoScaleBaseSize =new System.Drawing.Size(5, 13); this.ClientSize =new System.Drawing.Size(288, 96); this.Controls.Add(this.buttonClose); this.Cursor = System.Windows.Forms.Cursors.Hand; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Name ="ToastWindow"; this.Opacity =0; this.ShowInTaskbar =false; this.Text ="Weather Alert"; this.TopMost =true; this.TransparencyKey = System.Drawing.Color.Lime; this.Load +=new System.EventHandler(this.OnLoad); this.ResumeLayout(false); } #endregion /**////<summary> /// Paint the window. ///</summary> ///<param name="e">unused</param> ///<remarks> /// Draw the text. ///</remarks> protectedoverridevoid OnPaint(PaintEventArgs e) ...{ RectangleF boundingRect =new RectangleF( ( float ) ClientRectangle.Left, ( float ) ClientRectangle.Top, ( float ) ClientRectangle.Width, ( float ) ClientRectangle.Height ); StringFormat f =new StringFormat(); f.Alignment = StringAlignment.Center; f.LineAlignment = StringAlignment.Center; e.Graphics.DrawString( this._message, this.Font, Brushes.Blue, boundingRect, f ); } /**////<summary> /// Paint the background. ///</summary> ///<param name="pevent">unused</param> ///<remarks> /// Draw the rounded rect using the gradient brushes. ///</remarks> protectedoverridevoid OnPaintBackground(PaintEventArgs pevent) ...{ Graphics g = pevent.Graphics; g.FillRectangle( Brushes.Lime, 0,0,this.ClientSize.Width, this.ClientSize.Height ); System.Drawing.Drawing2D.GraphicsPath path = Utils.CreateRoundedRectPath(this.ClientRectangle, 15 ); using ( System.Drawing.Drawing2D.LinearGradientBrush b = new System.Drawing.Drawing2D.LinearGradientBrush( this.ClientRectangle, Color.SteelBlue, Color.LightBlue, System.Drawing.Drawing2D.LinearGradientMode.Vertical ) ) ...{ g.FillPath( b, path ); } } /**////<summary> /// Load handler. ///</summary> ///<param name="sender">unused</param> ///<param name="e">unused</param> ///<remarks> /// Put the toast window in the right spot, /// Start timers. ///</remarks> privatevoid OnLoad(object sender, System.EventArgs e) ...{ lock ( typeof ( ToastWindow ) ) ...{ System.Diagnostics.Debug.Assert( _toastUp ==false ); _toastUp =true; } // Set the position: // Left is the right of the desktop - our width. this.Left = SystemInformation.WorkingArea.Size.Width -this.Size.Width; this.Top = SystemInformation.WorkingArea.Size.Height -this.Size.Height; this.timerFadeIn.Enabled =true; this.toastWindowState = ToastState.FadeUp; } /**////<summary> /// Mouse Enter handler ///</summary> ///<param name="sender">unused</param> ///<param name="e">Unused</param> ///<remarks> /// If the user moves the mouse over the toast window, /// stop the timers. Change the opacity to full, and /// let the user view the toast message. /// And, make the font act like a selected link. ///</remarks> protectedoverridevoid OnMouseEnter(System.EventArgs e) ...{ StopFade(); } /**////<summary> /// Mouse Leave handler. ///</summary> ///<param name="sender">unused</param> ///<param name="e">unused</param> protectedoverridevoid OnMouseLeave(System.EventArgs e) ...{ StartFade(); } /**////<summary> /// Event handler for when the mouse enters the close box ///</summary> ///<param name="sender">unused</param> ///<param name="e">unused</param> privatevoid EnterCloseBox(object sender, System.EventArgs e) ...{ StopFade(); } /**////<summary> /// Event handler for when the mouse leaves the close box. ///</summary> ///<param name="sender">uused</param> ///<param name="e">unused</param> privatevoid LeaveCloseBox(object sender, System.EventArgs e) ...{ StartFade(); } /**////<summary> /// Stop the fade. ///</summary> ///<remarks> /// Stop the fade because we've got the mouse in our window. ///</remarks> privatevoid StopFade() ...{ this.Font =new System.Drawing.Font("Microsoft Sans Serif", 8.25F); this.Invalidate(); this.StartFadeOut(); this.timerFadeIn.Enabled =true; } /**////<summary> /// Start the fade. ///</summary> ///<remarks> /// We start the fade because we've got /// the mouse leaving our window. ///</remarks> privatevoid StartFade() ...{ this.Font =new System.Drawing.Font("Microsoft Sans Serif", 8.25F); this.Invalidate(); this.StartFadeOut(); this.timerFadeIn.Enabled =true; } /**////<summary> /// Mouse Up handler. ///</summary> ///<param name="sender">unused</param> ///<param name="e">unused</param> ///<remarks> /// Raise the toast click event. The event sink /// will know what to do. ///</remarks> protectedoverridevoid OnMouseUp(System.Windows.Forms.MouseEventArgs e) ...{ if ( ToastClick !=null ) ToastClick( this, new ToastSelectEventArgs( _toastTargetArgs ) ); this.Close(); } /**////<summary> /// Tick handler. Fade in. Fade out. ///</summary> ///<param name="sender">unused</param> ///<param name="e">unused</param> privatevoid FadeTick(object sender, System.EventArgs e) ...{ switch ( this.toastWindowState ) ...{ case ToastState.FadeUp: DoFadeIn(); break; case ToastState.Visible: StartFadeOut(); break; case ToastState.FadeDown: DoFadeDown(); break; } } /**////<summary> /// Increase the opacity of the toast window. ///</summary> ///<remarks> /// Once totally faded in, stay visible for /// 3 full seconds. ///</remarks> privatevoid DoFadeIn() ...{ if ( this.Opacity <0.99 ) ...{ this.Opacity +=0.05; this.Update(); } else// Stop this timer and start a new one: ...{ this.toastWindowState = ToastState.Visible; this.timerFadeIn.Interval =3000; } } /**////<summary> /// Fade out. ///</summary> ///<remarks> /// Lower the opacity until the window is gone. /// Then close. ///</remarks> privatevoid DoFadeDown() ...{ if ( this.Opacity >0.01 ) ...{ this.Opacity -=0.05; this.Update(); } else ...{ this.Close(); lock ( typeof ( ToastWindow ) ) _toastUp =false; } } /**////<summary> /// Transition from up to fade out. ///</summary> privatevoid StartFadeOut() ...{ this.timerFadeIn.Interval =100; this.toastWindowState = ToastState.FadeDown; } /**////<summary> /// Close handler. ///</summary> ///<param name="sender">unused</param> ///<param name="e">unused</param> privatevoid buttonClose_Click(object sender, System.EventArgs e) ...{ this.Close(); lock ( typeof ( ToastWindow ) ) _toastUp =false; } /**////<summary> /// Public entry point. ///</summary> ///<param name="msg">the message.</param> ///<param name="callbackArgs">the arggs to the callback.</param> ///<param name="ToastLauncher">The optional event handler.</param> ///<remarks> /// If there is no toast window up, make the window and show it. /// If a window is already displayed, ignore this message. ///</remarks> publicstaticvoid ShowToast( string msg, object callbackArgs, ToastTargetClickHandler ToastLauncher ) ...{ lock ( typeof (ToastWindow ) ) ...{ if ( _toastUp ==false ) ...{ ToastWindow w =new ToastWindow(); w._message = msg; w._toastTargetArgs = callbackArgs; if ( ToastLauncher !=null ) w.ToastClick += ToastLauncher; w.Show(); } } } } }