// C# TaskbarNotifier Class v1.0 // by John O'Byrne - 02 december 2002 // 01 april 2003 : Small fix in the OnMouseUp handler // 11 january 2003 : Patrick Vanden Driesscheadded a few enhancements // Small Enhancements/Bugfix // Small bugfix: When Content text measures larger than the corresponding ContentRectangle // the focus rectangle was not correctly drawn. This has been solved. // Added KeepVisibleOnMouseOver // Added ReShowOnMouseOver // Added If the Title or Content are too long to fit in the corresponding Rectangles, // the text is truncateed and the ellipses are appended (StringTrimming). using System; using System.Drawing; using System.Drawing.Imaging; using System.Drawing.Drawing2D; using System.Windows.Forms; using System.Runtime.InteropServices; namespace GoogleReaderNotifier.WinUI { /// /// TaskbarNotifier allows to display MSN style/Skinned instant messaging popups /// public class TaskbarNotifier : System.Windows.Forms.Form { #region TaskbarNotifier Protected Members protected Bitmap BackgroundBitmap = null; protected Bitmap CloseBitmap = null; protected Point CloseBitmapLocation; protected Size CloseBitmapSize; protected Rectangle RealTitleRectangle; protected Rectangle RealContentRectangle; protected Rectangle WorkAreaRectangle; protected Timer timer = new Timer(); protected TaskbarStates taskbarState = TaskbarStates.hidden; protected string titleText; protected string contentText; protected Color normalTitleColor = Color.FromArgb(255, 0, 0); protected Color hoverTitleColor = Color.FromArgb(255, 0, 0); protected Color normalContentColor = Color.FromArgb(0, 0, 0); protected Color hoverContentColor = Color.FromArgb(0, 0, 0x66); protected Font normalTitleFont = new Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Pixel); protected Font hoverTitleFont = new Font("Arial", 12, FontStyle.Bold, GraphicsUnit.Pixel); protected Font normalContentFont = new Font("Arial", 11, FontStyle.Regular, GraphicsUnit.Pixel); protected Font hoverContentFont = new Font("Arial", 11, FontStyle.Regular, GraphicsUnit.Pixel); protected int nShowEvents; protected int nHideEvents; protected int nVisibleEvents; protected int nIncrementShow; protected int nIncrementHide; protected bool bIsMouseOverPopup = false; protected bool bIsMouseOverClose = false; protected bool bIsMouseOverContent = false; protected bool bIsMouseOverTitle = false; protected bool bIsMouseDown = false; protected bool bKeepVisibleOnMouseOver = true; // Added Rev 002 protected bool bReShowOnMouseOver = false; // Added Rev 002 #endregion #region TaskbarNotifier Public Members public Rectangle TitleRectangle; public Rectangle ContentRectangle; public bool TitleClickable = false; public bool ContentClickable = true; public bool CloseClickable = true; public bool EnableSelectionRectangle = true; public event EventHandler CloseClick = null; public event EventHandler TitleClick = null; public event EventHandler ContentClick = null; #endregion #region TaskbarNotifier Enums ////// List of the different popup animation status /// public enum TaskbarStates { hidden = 0, appearing = 1, visible = 2, disappearing = 3 } #endregion #region TaskbarNotifier Constructor ////// The Constructor for TaskbarNotifier /// public TaskbarNotifier() { // Window Style FormBorderStyle = FormBorderStyle.None; WindowState = FormWindowState.Minimized; base.Show(); base.Hide(); WindowState = FormWindowState.Normal; ShowInTaskbar = false; TopMost = true; MaximizeBox = false; MinimizeBox = false; ControlBox = false; timer.Enabled = true; timer.Tick += new EventHandler(OnTimer); //CloseBitmap CloseBitmap = global::TyroDeveloperDLL.Properties.Resources.close; CloseBitmapSize = new System.Drawing.Size(16, 16); CloseBitmapLocation = new Point(325, 8); //BackgroundBitmap BackgroundBitmap = global::TyroDeveloperDLL.Properties.Resources.bak; //configuration TitleRectangle = new Rectangle(8, 9, 300, 25); ContentRectangle = new Rectangle(8, 41, 300, 100); } #endregion #region TaskbarNotifier Properties ////// Get the current TaskbarState (hidden, showing, visible, hiding) /// public TaskbarStates TaskbarState { get { return taskbarState; } } ////// Get/Set the popup Title Text /// public string TitleText { get { return titleText; } set { titleText = value; Refresh(); } } ////// Get/Set the popup Content Text /// public string ContentText { get { return contentText; } set { contentText = value; Refresh(); } } ////// Get/Set the Normal Title Color /// public Color NormalTitleColor { get { return normalTitleColor; } set { normalTitleColor = value; Refresh(); } } ////// Get/Set the Hover Title Color /// public Color HoverTitleColor { get { return hoverTitleColor; } set { hoverTitleColor = value; Refresh(); } } ////// Get/Set the Normal Content Color /// public Color NormalContentColor { get { return normalContentColor; } set { normalContentColor = value; Refresh(); } } ////// Get/Set the Hover Content Color /// public Color HoverContentColor { get { return hoverContentColor; } set { hoverContentColor = value; Refresh(); } } ////// Get/Set the Normal Title Font /// public Font NormalTitleFont { get { return normalTitleFont; } set { normalTitleFont = value; Refresh(); } } ////// Get/Set the Hover Title Font /// public Font HoverTitleFont { get { return hoverTitleFont; } set { hoverTitleFont = value; Refresh(); } } ////// Get/Set the Normal Content Font /// public Font NormalContentFont { get { return normalContentFont; } set { normalContentFont = value; Refresh(); } } ////// Get/Set the Hover Content Font /// public Font HoverContentFont { get { return hoverContentFont; } set { hoverContentFont = value; Refresh(); } } ////// Indicates if the popup should remain visible when the mouse pointer is over it. /// Added Rev 002 /// public bool KeepVisibleOnMousOver { get { return bKeepVisibleOnMouseOver; } set { bKeepVisibleOnMouseOver = value; } } ////// Indicates if the popup should appear again when mouse moves over it while it's disappearing. /// Added Rev 002 /// public bool ReShowOnMouseOver { get { return bReShowOnMouseOver; } set { bReShowOnMouseOver = value; } } protected override bool ShowWithoutActivation { get { return true; } } #endregion #region TaskbarNotifier Public Methods [DllImport("user32.dll")] private static extern Boolean ShowWindow(IntPtr hWnd, Int32 nCmdShow); ////// Displays the popup for a certain amount of time /// /// The string which will be shown as the title of the popup /// The string which will be shown as the content of the popup /// Duration of the showing animation (in milliseconds) /// Duration of the visible state before collapsing (in milliseconds) /// Duration of the hiding animation (in milliseconds) ///Nothing public void Show(string strTitle, string strContent, int nTimeToShow, int nTimeToStay, int nTimeToHide) { WorkAreaRectangle = Screen.GetWorkingArea(WorkAreaRectangle); titleText = strTitle; contentText = strContent; nVisibleEvents = nTimeToStay; CalculateMouseRectangles(); // We calculate the pixel increment and the timer value for the showing animation int nEvents; if (nTimeToShow > 10) { nEvents = Math.Min((nTimeToShow / 10), BackgroundBitmap.Height); nShowEvents = nTimeToShow / nEvents; nIncrementShow = BackgroundBitmap.Height / nEvents; } else { nShowEvents = 10; nIncrementShow = BackgroundBitmap.Height; } // We calculate the pixel increment and the timer value for the hiding animation if (nTimeToHide > 10) { nEvents = Math.Min((nTimeToHide / 10), BackgroundBitmap.Height); nHideEvents = nTimeToHide / nEvents; nIncrementHide = BackgroundBitmap.Height / nEvents; } else { nHideEvents = 10; nIncrementHide = BackgroundBitmap.Height; } switch (taskbarState) { case TaskbarStates.hidden: taskbarState = TaskbarStates.appearing; SetBounds(WorkAreaRectangle.Right - BackgroundBitmap.Width - 17, WorkAreaRectangle.Bottom - 1, BackgroundBitmap.Width, 0); timer.Interval = nShowEvents; timer.Start(); // We Show the popup without stealing focus // Although ShowWithoutActivation is overridden, using just Show() will still steal focus // This focus stealing problem may be related to the fact that .TopMost is also used. ShowWindow(this.Handle, 4); break; case TaskbarStates.appearing: Refresh(); break; case TaskbarStates.visible: timer.Stop(); timer.Interval = nVisibleEvents; timer.Start(); Refresh(); break; case TaskbarStates.disappearing: timer.Stop(); taskbarState = TaskbarStates.visible; SetBounds(WorkAreaRectangle.Right - BackgroundBitmap.Width - 17, WorkAreaRectangle.Bottom - BackgroundBitmap.Height - 1, BackgroundBitmap.Width, BackgroundBitmap.Height); timer.Interval = nVisibleEvents; timer.Start(); Refresh(); break; } } ////// Hides the popup /// ///Nothing public new void Hide() { if (taskbarState != TaskbarStates.hidden) { timer.Stop(); taskbarState = TaskbarStates.hidden; base.Hide(); Visible = false; } } ////// Sets the background bitmap and its transparency color /// /// Path of the Background Bitmap on the disk /// Color of the Bitmap which won't be visible ///Nothing public void SetBackgroundBitmap(string strFilename, Color transparencyColor) { BackgroundBitmap = new Bitmap(strFilename); Width = BackgroundBitmap.Width; Height = BackgroundBitmap.Height; Region = BitmapToRegion(BackgroundBitmap, transparencyColor); } ////// Sets the background bitmap and its transparency color /// /// Image/Bitmap object which represents the Background Bitmap /// Color of the Bitmap which won't be visible ///Nothing public void SetBackgroundBitmap(Image image, Color transparencyColor) { BackgroundBitmap = new Bitmap(image); Width = BackgroundBitmap.Width; Height = BackgroundBitmap.Height; Region = BitmapToRegion(BackgroundBitmap, transparencyColor); } ////// Sets the 3-State Close Button bitmap, its transparency color and its coordinates /// /// Path of the 3-state Close button Bitmap on the disk (width must a multiple of 3) /// Color of the Bitmap which won't be visible /// Location of the close button on the popup ///Nothing public void SetCloseBitmap(string strFilename, Color transparencyColor, Point position) { CloseBitmap = new Bitmap(strFilename); CloseBitmap.MakeTransparent(transparencyColor); CloseBitmapSize = new Size(CloseBitmap.Width / 3, CloseBitmap.Height); CloseBitmapLocation = position; } ////// Sets the 3-State Close Button bitmap, its transparency color and its coordinates /// /// Image/Bitmap object which represents the 3-state Close button Bitmap (width must be a multiple of 3) /// Color of the Bitmap which won't be visible /// /// Location of the close button on the popup ///Nothing public void SetCloseBitmap(Image image, Color transparencyColor, Point position) { CloseBitmap = new Bitmap(image); CloseBitmap.MakeTransparent(transparencyColor); CloseBitmapSize = new Size(CloseBitmap.Width / 3, CloseBitmap.Height); CloseBitmapLocation = position; } #endregion #region TaskbarNotifier Protected Methods protected void DrawCloseButton(Graphics grfx) { if (CloseBitmap != null) { Rectangle rectDest = new Rectangle(CloseBitmapLocation, CloseBitmapSize); Rectangle rectSrc; if (bIsMouseOverClose) { if (bIsMouseDown) rectSrc = new Rectangle(new Point(CloseBitmapSize.Width * 2, 0), CloseBitmapSize); else rectSrc = new Rectangle(new Point(CloseBitmapSize.Width, 0), CloseBitmapSize); } else rectSrc = new Rectangle(new Point(0, 0), CloseBitmapSize); grfx.DrawImage(CloseBitmap, rectDest, rectSrc, GraphicsUnit.Pixel); } } protected void DrawText(Graphics grfx) { if (titleText != null && titleText.Length != 0) { StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Near; sf.LineAlignment = StringAlignment.Center; sf.FormatFlags = StringFormatFlags.NoWrap; sf.Trimming = StringTrimming.EllipsisCharacter; // Added Rev 002 if (bIsMouseOverTitle) grfx.DrawString(titleText, hoverTitleFont, new SolidBrush(hoverTitleColor), TitleRectangle, sf); else grfx.DrawString(titleText, normalTitleFont, new SolidBrush(normalTitleColor), TitleRectangle, sf); } if (contentText != null && contentText.Length != 0) { StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; sf.FormatFlags = StringFormatFlags.MeasureTrailingSpaces; sf.Trimming = StringTrimming.Word; // Added Rev 002 if (bIsMouseOverContent) { grfx.DrawString(contentText, hoverContentFont, new SolidBrush(hoverContentColor), ContentRectangle, sf); if (EnableSelectionRectangle) ControlPaint.DrawBorder3D(grfx, RealContentRectangle, Border3DStyle.Etched, Border3DSide.Top | Border3DSide.Bottom | Border3DSide.Left | Border3DSide.Right); } else grfx.DrawString(contentText, normalContentFont, new SolidBrush(normalContentColor), ContentRectangle, sf); } } protected void CalculateMouseRectangles() { Graphics grfx = CreateGraphics(); StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; sf.FormatFlags = StringFormatFlags.MeasureTrailingSpaces; SizeF sizefTitle = grfx.MeasureString(titleText, hoverTitleFont, TitleRectangle.Width, sf); SizeF sizefContent = grfx.MeasureString(contentText, hoverContentFont, ContentRectangle.Width, sf); grfx.Dispose(); // Added Rev 002 //We should check if the title size really fits inside the pre-defined title rectangle if (sizefTitle.Height > TitleRectangle.Height) { RealTitleRectangle = new Rectangle(TitleRectangle.Left, TitleRectangle.Top, TitleRectangle.Width, TitleRectangle.Height); } else { RealTitleRectangle = new Rectangle(TitleRectangle.Left, TitleRectangle.Top, (int)sizefTitle.Width, (int)sizefTitle.Height); } RealTitleRectangle.Inflate(0, 2); // Added Rev 002 //We should check if the Content size really fits inside the pre-defined Content rectangle if (sizefContent.Height > ContentRectangle.Height) { RealContentRectangle = new Rectangle((ContentRectangle.Width - (int)sizefContent.Width) / 2 + ContentRectangle.Left, ContentRectangle.Top, (int)sizefContent.Width, ContentRectangle.Height); } else { RealContentRectangle = new Rectangle((ContentRectangle.Width - (int)sizefContent.Width) / 2 + ContentRectangle.Left, (ContentRectangle.Height - (int)sizefContent.Height) / 2 + ContentRectangle.Top, (int)sizefContent.Width, (int)sizefContent.Height); } RealContentRectangle.Inflate(0, 2); } protected Region BitmapToRegion(Bitmap bitmap, Color transparencyColor) { if (bitmap == null) throw new ArgumentNullException("Bitmap", "Bitmap cannot be null!"); int height = bitmap.Height; int width = bitmap.Width; GraphicsPath path = new GraphicsPath(); for (int j = 0; j < height; j++) for (int i = 0; i < width; i++) { if (bitmap.GetPixel(i, j) == transparencyColor) continue; int x0 = i; while ((i < width) && (bitmap.GetPixel(i, j) != transparencyColor)) i++; path.AddRectangle(new Rectangle(x0, j, i - x0, 1)); } Region region = new Region(path); path.Dispose(); return region; } #endregion #region TaskbarNotifier Events Overrides protected void OnTimer(Object obj, EventArgs ea) { switch (taskbarState) { case TaskbarStates.appearing: if (Height < BackgroundBitmap.Height) { SetBounds(Left, Top - nIncrementShow, Width, Height + nIncrementShow); Opacity = ((Double)Height / BackgroundBitmap.Height); } else { timer.Stop(); Opacity = 1; Height = BackgroundBitmap.Height; timer.Interval = nVisibleEvents; taskbarState = TaskbarStates.visible; timer.Start(); } break; case TaskbarStates.visible: timer.Stop(); Opacity = 1; timer.Interval = nHideEvents; // Added Rev 002 if ((bKeepVisibleOnMouseOver && !bIsMouseOverPopup) || (!bKeepVisibleOnMouseOver)) { taskbarState = TaskbarStates.disappearing; } //taskbarState = TaskbarStates.disappearing; // Rev 002 timer.Start(); break; case TaskbarStates.disappearing: // Added Rev 002 if (bReShowOnMouseOver && bIsMouseOverPopup) { taskbarState = TaskbarStates.appearing; } else { if (Top < WorkAreaRectangle.Bottom) { SetBounds(Left, Top + nIncrementHide, Width, Height - nIncrementHide); Opacity = ((Double)Height / BackgroundBitmap.Height); } else { Hide(); } } break; } } protected override void OnMouseEnter(EventArgs ea) { base.OnMouseEnter(ea); bIsMouseOverPopup = true; Refresh(); } protected override void OnMouseLeave(EventArgs ea) { base.OnMouseLeave(ea); bIsMouseOverPopup = false; bIsMouseOverClose = false; bIsMouseOverTitle = false; bIsMouseOverContent = false; Refresh(); } protected override void OnMouseMove(MouseEventArgs mea) { base.OnMouseMove(mea); bool bContentModified = false; if ((mea.X > CloseBitmapLocation.X) && (mea.X < CloseBitmapLocation.X + CloseBitmapSize.Width) && (mea.Y > CloseBitmapLocation.Y) && (mea.Y < CloseBitmapLocation.Y + CloseBitmapSize.Height) && CloseClickable) { if (!bIsMouseOverClose) { bIsMouseOverClose = true; bIsMouseOverTitle = false; bIsMouseOverContent = false; Cursor = Cursors.Hand; bContentModified = true; } } else if (RealContentRectangle.Contains(new Point(mea.X, mea.Y)) && ContentClickable) { if (!bIsMouseOverContent) { bIsMouseOverClose = false; bIsMouseOverTitle = false; bIsMouseOverContent = true; Cursor = Cursors.Hand; bContentModified = true; } } else if (RealTitleRectangle.Contains(new Point(mea.X, mea.Y)) && TitleClickable) { if (!bIsMouseOverTitle) { bIsMouseOverClose = false; bIsMouseOverTitle = true; bIsMouseOverContent = false; Cursor = Cursors.Hand; bContentModified = true; } } else { if (bIsMouseOverClose || bIsMouseOverTitle || bIsMouseOverContent) bContentModified = true; bIsMouseOverClose = false; bIsMouseOverTitle = false; bIsMouseOverContent = false; Cursor = Cursors.Default; } if (bContentModified) Refresh(); } protected override void OnMouseDown(MouseEventArgs mea) { base.OnMouseDown(mea); bIsMouseDown = true; if (bIsMouseOverClose) Refresh(); } protected override void OnMouseUp(MouseEventArgs mea) { base.OnMouseUp(mea); bIsMouseDown = false; if (bIsMouseOverClose) { Hide(); if (CloseClick != null) CloseClick(this, new EventArgs()); } else if (bIsMouseOverTitle) { if (TitleClick != null) TitleClick(this, new EventArgs()); } else if (bIsMouseOverContent) { if (ContentClick != null) ContentClick(this, new EventArgs()); } } protected override void OnPaintBackground(PaintEventArgs pea) { Graphics grfx = pea.Graphics; grfx.PageUnit = GraphicsUnit.Pixel; Graphics offScreenGraphics; Bitmap offscreenBitmap; offscreenBitmap = new Bitmap(BackgroundBitmap.Width, BackgroundBitmap.Height); offScreenGraphics = Graphics.FromImage(offscreenBitmap); if (BackgroundBitmap != null) { offScreenGraphics.DrawImage(BackgroundBitmap, 0, 0, BackgroundBitmap.Width, BackgroundBitmap.Height); } DrawCloseButton(offScreenGraphics); DrawText(offScreenGraphics); grfx.DrawImage(offscreenBitmap, 0, 0); } #endregion } }
Please visit: www.TyroDeveloper.com
Please Click on +1
No comments:
Post a Comment