This commit is contained in:
Stephan Maier
2024-08-27 08:10:27 +02:00
parent eb5c2fa502
commit 647f938eee
617 changed files with 73086 additions and 7137 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,631 @@
/*
* Created/modified in 2011 by Simon Baer
*
* Based on the Code Project article by Nicolas Wälti:
* http://www.codeproject.com/KB/cpp/PopupNotifier.aspx
*
* Licensed under the Code Project Open License (CPOL).
*/
using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Tulpep.NotificationWindow
{
/// <summary>
/// Non-visual component to show a notification window in the right lower
/// corner of the screen.
/// </summary>
[ToolboxBitmapAttribute(typeof(PopupNotifier), "Icon.ico")]
[DefaultEvent("Click")]
public class PopupNotifier : Component
{
#region Windows API
private const int SW_SHOWNOACTIVATE = 4;
private const int HWND_TOPMOST = -1;
private const uint SWP_NOACTIVATE = 0x0010;
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
static extern bool SetWindowPos(
int hWnd, // Window handle
int hWndInsertAfter, // Placement-order handle
int X, // Horizontal position
int Y, // Vertical position
int cx, // Width
int cy, // Height
uint uFlags); // Window positioning flags
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
static void ShowInactiveTopmost(Form frm)
{
ShowWindow(frm.Handle, SW_SHOWNOACTIVATE);
SetWindowPos(frm.Handle.ToInt32(), HWND_TOPMOST,
frm.Left, frm.Top, frm.Width, frm.Height,
SWP_NOACTIVATE);
}
#endregion
/// <summary>
/// Event that is raised when the text in the notification window is clicked.
/// </summary>
public event EventHandler Click;
/// <summary>
/// Event that is raised when the notification window is manually closed.
/// </summary>
public event EventHandler Close;
/// <summary>
/// Event that is raised when the notification Appears.
/// </summary>
public event EventHandler Appear;
/// <summary>
/// Event that is raised when the notification Dissapers
/// </summary>
public event EventHandler Disappear;
private bool disposed = false;
private PopupNotifierForm frmPopup;
private Timer tmrAnimation;
private Timer tmrWait;
private bool isAppearing = true;
private bool markedForDisposed = false;
private bool mouseIsOn = false;
private int maxPosition;
private double maxOpacity;
private int posStart;
private int posStop;
private double opacityStart;
private double opacityStop;
private int realAnimationDuration;
private System.Diagnostics.Stopwatch sw;
#region Properties
[Category("Header"), DefaultValue(typeof(Color), "ControlDark")]
[Description("Color of the window header.")]
public Color HeaderColor { get; set; }
[Category("Appearance"), DefaultValue(typeof(Color), "Control")]
[Description("Color of the window background.")]
public Color BodyColor { get; set; }
[Category("Title"), DefaultValue(typeof(Color), "Gray")]
[Description("Color of the title text.")]
public Color TitleColor { get; set; }
[Category("Content"), DefaultValue(typeof(Color), "ControlText")]
[Description("Color of the content text.")]
public Color ContentColor { get; set; }
[Category("Appearance"), DefaultValue(typeof(Color), "WindowFrame")]
[Description("Color of the window border.")]
public Color BorderColor { get; set; }
[Category("Buttons"), DefaultValue(typeof(Color), "WindowFrame")]
[Description("Border color of the close and options buttons when the mouse is over them.")]
public Color ButtonBorderColor { get; set; }
[Category("Buttons"), DefaultValue(typeof(Color), "Highlight")]
[Description("Background color of the close and options buttons when the mouse is over them.")]
public Color ButtonHoverColor { get; set; }
[Category("Content"), DefaultValue(typeof(Color), "HotTrack")]
[Description("Color of the content text when the mouse is hovering over it.")]
public Color ContentHoverColor { get; set; }
[Category("Appearance"), DefaultValue(50)]
[Description("Gradient of window background color.")]
public int GradientPower { get; set; }
[Category("Content")]
[Description("Font of the content text.")]
public Font ContentFont { get; set; }
[Category("Title")]
[Description("Font of the title.")]
public Font TitleFont { get; set; }
[Category("Image")]
[Description("Size of the icon image.")]
public Size ImageSize
{
get
{
if (imageSize.Width == 0)
{
if (Image != null)
{
return Image.Size;
}
else
{
return new Size(0, 0);
}
}
else
{
return imageSize;
}
}
set { imageSize = value; }
}
public void ResetImageSize()
{
imageSize = Size.Empty;
}
private bool ShouldSerializeImageSize()
{
return (!imageSize.Equals(Size.Empty));
}
private Size imageSize = new Size(0, 0);
[Category("Image")]
[Description("Icon image to display.")]
public Image Image { get; set; }
[Category("Header"), DefaultValue(true)]
[Description("Whether to show a 'grip' image within the window header.")]
public bool ShowGrip { get; set; }
[Category("Behavior"), DefaultValue(true)]
[Description("Whether to scroll the window or only fade it.")]
public bool Scroll { get; set; }
[Category("Content")]
[Description("Content text to display.")]
public string ContentText { get; set; }
[Category("Title")]
[Description("Title text to display.")]
public string TitleText { get; set; }
[Category("Title")]
[Description("Padding of title text.")]
public Padding TitlePadding { get; set; }
private void ResetTitlePadding()
{
TitlePadding = Padding.Empty;
}
private bool ShouldSerializeTitlePadding()
{
return (!TitlePadding.Equals(Padding.Empty));
}
[Category("Content")]
[Description("Padding of content text.")]
public Padding ContentPadding { get; set; }
private void ResetContentPadding()
{
ContentPadding = Padding.Empty;
}
private bool ShouldSerializeContentPadding()
{
return (!ContentPadding.Equals(Padding.Empty));
}
[Category("Image")]
[Description("Padding of icon image.")]
public Padding ImagePadding { get; set; }
private void ResetImagePadding()
{
ImagePadding = Padding.Empty;
}
private bool ShouldSerializeImagePadding()
{
return (!ImagePadding.Equals(Padding.Empty));
}
[Category("Header"), DefaultValue(9)]
[Description("Height of window header.")]
public int HeaderHeight { get; set; }
[Category("Buttons"), DefaultValue(true)]
[Description("Whether to show the close button.")]
public bool ShowCloseButton { get; set; }
[Category("Buttons"), DefaultValue(false)]
[Description("Whether to show the options button.")]
public bool ShowOptionsButton { get; set; }
[Category("Behavior")]
[Description("Context menu to open when clicking on the options button.")]
public ContextMenuStrip OptionsMenu { get; set; }
[Category("Behavior"), DefaultValue(3000)]
[Description("Time in milliseconds the window is displayed.")]
public int Delay { get; set; }
[Category("Behavior"), DefaultValue(1000)]
[Description("Time in milliseconds needed to make the window appear or disappear.")]
public int AnimationDuration { get; set; }
[Category("Behavior"), DefaultValue(10)]
[Description("Interval in milliseconds used to draw the animation.")]
public int AnimationInterval { get; set; }
[Category("Appearance")]
[Description("Size of the window.")]
public Size Size { get; set; }
[Category("Content")]
[Description("Show Content Right To Left,نمایش پیغام چپ به راست فعال شود")]
public bool IsRightToLeft { get; set; }
#endregion
/// <summary>
/// Create a new instance of the popup component.
/// </summary>
public PopupNotifier()
{
// set default values
HeaderColor = SystemColors.ControlDark;
BodyColor = SystemColors.Control;
TitleColor = System.Drawing.Color.Gray;
ContentColor = SystemColors.ControlText;
BorderColor = SystemColors.WindowFrame;
ButtonBorderColor = SystemColors.WindowFrame;
ButtonHoverColor = SystemColors.Highlight;
ContentHoverColor = SystemColors.HotTrack;
GradientPower = 50;
ContentFont = SystemFonts.DialogFont;
TitleFont = SystemFonts.CaptionFont;
ShowGrip = true;
Scroll = true;
TitlePadding = new Padding(0);
ContentPadding = new Padding(0);
ImagePadding = new Padding(0);
HeaderHeight = 9;
ShowCloseButton = true;
ShowOptionsButton = false;
Delay = 3000;
AnimationInterval = 10;
AnimationDuration = 1000;
Size = new Size(400, 100);
frmPopup = new PopupNotifierForm(this);
frmPopup.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
frmPopup.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
frmPopup.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
frmPopup.MouseEnter += new EventHandler(frmPopup_MouseEnter);
frmPopup.MouseLeave += new EventHandler(frmPopup_MouseLeave);
frmPopup.CloseClick += new EventHandler(frmPopup_CloseClick);
frmPopup.LinkClick += new EventHandler(frmPopup_LinkClick);
frmPopup.ContextMenuOpened += new EventHandler(frmPopup_ContextMenuOpened);
frmPopup.ContextMenuClosed += new EventHandler(frmPopup_ContextMenuClosed);
frmPopup.VisibleChanged += new EventHandler(frmPopup_VisibleChanged);
tmrAnimation = new Timer();
tmrAnimation.Tick += new EventHandler(tmAnimation_Tick);
tmrWait = new Timer();
tmrWait.Tick += new EventHandler(tmWait_Tick);
}
/// <summary>
/// Show the notification window if it is not already visible.
/// If the window is currently disappearing, it is shown again.
/// </summary>
public void Popup()
{
if (!disposed)
{
if (!frmPopup.Visible)
{
frmPopup.Size = Size;
if (Scroll)
{
posStart = Screen.PrimaryScreen.WorkingArea.Bottom;
posStop = Screen.PrimaryScreen.WorkingArea.Bottom - frmPopup.Height;
}
else
{
posStart = Screen.PrimaryScreen.WorkingArea.Bottom - frmPopup.Height;
posStop = Screen.PrimaryScreen.WorkingArea.Bottom - frmPopup.Height;
}
opacityStart = 0;
opacityStop = 1;
frmPopup.Opacity = opacityStart;
frmPopup.Location = new Point(Screen.PrimaryScreen.WorkingArea.Right - frmPopup.Size.Width - 1, posStart);
ShowInactiveTopmost(frmPopup);
isAppearing = true;
tmrWait.Interval = Delay;
tmrAnimation.Interval = AnimationInterval;
realAnimationDuration = AnimationDuration;
tmrAnimation.Start();
sw = System.Diagnostics.Stopwatch.StartNew();
System.Diagnostics.Debug.WriteLine("Animation started.");
}
else
{
if (!isAppearing)
{
frmPopup.Size = Size;
if (Scroll)
{
posStart = frmPopup.Top;
posStop = Screen.PrimaryScreen.WorkingArea.Bottom - frmPopup.Height;
}
else
{
posStart = Screen.PrimaryScreen.WorkingArea.Bottom - frmPopup.Height;
posStop = Screen.PrimaryScreen.WorkingArea.Bottom - frmPopup.Height;
}
opacityStart = frmPopup.Opacity;
opacityStop = 1;
isAppearing = true;
realAnimationDuration = Math.Max((int)sw.ElapsedMilliseconds, 1);
sw.Restart();
System.Diagnostics.Debug.WriteLine("Animation direction changed.");
}
frmPopup.Invalidate();
}
}
}
/// <summary>
/// Hide the notification window.
/// </summary>
public void Hide()
{
System.Diagnostics.Debug.WriteLine("Animation stopped.");
System.Diagnostics.Debug.WriteLine("Wait timer stopped.");
tmrAnimation.Stop();
tmrWait.Stop();
frmPopup.Hide();
if (markedForDisposed)
{
Dispose();
}
}
/// <summary>
/// The custom options menu has been closed. Restart the timer for
/// closing the notification window.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmPopup_ContextMenuClosed(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Menu closed.");
if (!mouseIsOn)
{
tmrWait.Interval = Delay;
tmrWait.Start();
System.Diagnostics.Debug.WriteLine("Wait timer started.");
}
}
/// <summary>
/// The custom options menu has been opened. The window must not be closed
/// as long as the menu is open.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmPopup_ContextMenuOpened(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Menu opened.");
tmrWait.Stop();
System.Diagnostics.Debug.WriteLine("Wait timer stopped.");
}
/// <summary>
/// The text has been clicked. Raise the 'Click' event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmPopup_LinkClick(object sender, EventArgs e)
{
if (Click != null)
{
Click(this, EventArgs.Empty);
}
}
/// <summary>
/// The close button has been clicked. Hide the notification window
/// and raise the 'Close' event.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmPopup_CloseClick(object sender, EventArgs e)
{
Hide();
if (Close != null)
{
Close(this, EventArgs.Empty);
}
}
/// <summary>
/// Visibility has changed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmPopup_VisibleChanged(object sender, EventArgs e)
{
if (frmPopup.Visible)
{
if (Appear != null) Appear(this, EventArgs.Empty);
}
else
{
if (Disappear != null) Disappear(this, EventArgs.Empty);
}
}
/// <summary>
/// Update form position and opacity to show/hide the window.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tmAnimation_Tick(object sender, EventArgs e)
{
long elapsed = sw.ElapsedMilliseconds;
int posCurrent = (int)(posStart + ((posStop - posStart) * elapsed / realAnimationDuration));
bool neg = (posStop - posStart) < 0;
if ((neg && posCurrent < posStop) ||
(!neg && posCurrent > posStop))
{
posCurrent = posStop;
}
double opacityCurrent = opacityStart + ((opacityStop - opacityStart) * elapsed / realAnimationDuration);
neg = (opacityStop - opacityStart) < 0;
if ((neg && opacityCurrent < opacityStop) ||
(!neg && opacityCurrent > opacityStop))
{
opacityCurrent = opacityStop;
}
frmPopup.Top = posCurrent;
frmPopup.Opacity = opacityCurrent;
// animation has ended
if (elapsed > realAnimationDuration)
{
sw.Reset();
tmrAnimation.Stop();
System.Diagnostics.Debug.WriteLine("Animation stopped.");
if (isAppearing)
{
if (Scroll)
{
posStart = Screen.PrimaryScreen.WorkingArea.Bottom - frmPopup.Height;
posStop = Screen.PrimaryScreen.WorkingArea.Bottom;
}
else
{
posStart = Screen.PrimaryScreen.WorkingArea.Bottom - frmPopup.Height;
posStop = Screen.PrimaryScreen.WorkingArea.Bottom - frmPopup.Height;
}
opacityStart = 1;
opacityStop = 0;
realAnimationDuration = AnimationDuration;
isAppearing = false;
maxPosition = frmPopup.Top;
maxOpacity = frmPopup.Opacity;
if (!mouseIsOn)
{
tmrWait.Stop();
tmrWait.Start();
System.Diagnostics.Debug.WriteLine("Wait timer started.");
}
}
else
{
frmPopup.Hide();
if (markedForDisposed)
Dispose();
}
}
}
/// <summary>
/// The wait timer has elapsed, start the animation to hide the window.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tmWait_Tick(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Wait timer elapsed.");
tmrWait.Stop();
tmrAnimation.Interval = AnimationInterval;
tmrAnimation.Start();
sw.Restart();
System.Diagnostics.Debug.WriteLine("Animation started.");
}
/// <summary>
/// Start wait timer if the mouse leaves the form.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmPopup_MouseLeave(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("MouseLeave");
if (frmPopup.Visible && (OptionsMenu == null || !OptionsMenu.Visible))
{
tmrWait.Interval = Delay;
tmrWait.Start();
System.Diagnostics.Debug.WriteLine("Wait timer started.");
}
mouseIsOn = false;
}
/// <summary>
/// Stop wait timer if the mouse enters the form.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmPopup_MouseEnter(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("MouseEnter");
if (!isAppearing)
{
frmPopup.Top = maxPosition;
frmPopup.Opacity = maxOpacity;
tmrAnimation.Stop();
System.Diagnostics.Debug.WriteLine("Animation stopped.");
}
tmrWait.Stop();
System.Diagnostics.Debug.WriteLine("Wait timer stopped.");
mouseIsOn = true;
}
/// <summary>
/// Dispose the notification form.
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
if (!disposed)
{
if (isAppearing)
{
markedForDisposed = true;
return;
}
if (disposing)
{
if (frmPopup != null)
frmPopup.Dispose();
tmrAnimation.Tick -= tmAnimation_Tick;
tmrWait.Tick -= tmWait_Tick;
tmrAnimation.Dispose();
tmrWait.Dispose();
}
disposed = true;
}
base.Dispose(disposing);
}
}
}

View File

@@ -0,0 +1,398 @@
/*
* Created/modified in 2011 by Simon Baer
*
* Based on the Code Project article by Nicolas Wälti:
* http://www.codeproject.com/KB/cpp/PopupNotifier.aspx
*
* Licensed under the Code Project Open License (CPOL).
*/
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Tulpep.NotificationWindow
{
/// <summary>
/// This is the form of the actual notification window.
/// </summary>
internal class PopupNotifierForm : System.Windows.Forms.Form
{
/// <summary>
/// Event that is raised when the text is clicked.
/// </summary>
public event EventHandler LinkClick;
/// <summary>
/// Event that is raised when the notification window is manually closed.
/// </summary>
public event EventHandler CloseClick;
internal event EventHandler ContextMenuOpened;
internal event EventHandler ContextMenuClosed;
private bool mouseOnClose = false;
private bool mouseOnLink = false;
private bool mouseOnOptions = false;
private int heightOfTitle;
#region GDI objects
private bool gdiInitialized = false;
private Rectangle rcBody;
private Rectangle rcHeader;
private Rectangle rcForm;
private LinearGradientBrush brushBody;
private LinearGradientBrush brushHeader;
private Brush brushButtonHover;
private Pen penButtonBorder;
private Pen penContent;
private Pen penBorder;
private Brush brushForeColor;
private Brush brushLinkHover;
private Brush brushContent;
private Brush brushTitle;
#endregion
/// <summary>
/// Create a new instance.
/// </summary>
/// <param name="parent">PopupNotifier</param>
public PopupNotifierForm(PopupNotifier parent)
{
Parent = parent;
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.ShowInTaskbar = false;
this.VisibleChanged += new EventHandler(PopupNotifierForm_VisibleChanged);
this.MouseMove += new MouseEventHandler(PopupNotifierForm_MouseMove);
this.MouseUp += new MouseEventHandler(PopupNotifierForm_MouseUp);
this.Paint += new PaintEventHandler(PopupNotifierForm_Paint);
}
/// <summary>
/// The form is shown/hidden.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PopupNotifierForm_VisibleChanged(object sender, EventArgs e)
{
if (this.Visible)
{
mouseOnClose = false;
mouseOnLink = false;
mouseOnOptions = false;
}
}
/// <summary>
/// Used in design mode.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// PopupNotifierForm
//
this.ClientSize = new System.Drawing.Size(392, 66);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "PopupNotifierForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
this.ResumeLayout(false);
}
/// <summary>
/// Gets or sets the parent control.
/// </summary>
public new PopupNotifier Parent { get; set; }
/// <summary>
/// Add two values but do not return a value greater than 255.
/// </summary>
/// <param name="input">first value</param>
/// <param name="add">value to add</param>
/// <returns>sum of both values</returns>
private int AddValueMax255(int input, int add)
{
return (input + add < 256) ? input + add : 255;
}
/// <summary>
/// Subtract two values but do not returns a value below 0.
/// </summary>
/// <param name="input">first value</param>
/// <param name="ded">value to subtract</param>
/// <returns>first value minus second value</returns>
private int DedValueMin0(int input, int ded)
{
return (input - ded > 0) ? input - ded : 0;
}
/// <summary>
/// Returns a color which is darker than the given color.
/// </summary>
/// <param name="color">Color</param>
/// <returns>darker color</returns>
private Color GetDarkerColor(Color color)
{
return System.Drawing.Color.FromArgb(255, DedValueMin0((int)color.R, Parent.GradientPower), DedValueMin0((int)color.G, Parent.GradientPower), DedValueMin0((int)color.B, Parent.GradientPower));
}
/// <summary>
/// Returns a color which is lighter than the given color.
/// </summary>
/// <param name="color">Color</param>
/// <returns>lighter color</returns>
private Color GetLighterColor(Color color)
{
return System.Drawing.Color.FromArgb(255, AddValueMax255((int)color.R, Parent.GradientPower), AddValueMax255((int)color.G, Parent.GradientPower), AddValueMax255((int)color.B, Parent.GradientPower));
}
/// <summary>
/// Gets the rectangle of the content text.
/// </summary>
private RectangleF RectContentText
{
get
{
if (Parent.Image != null)
{
return new RectangleF(
Parent.ImagePadding.Left + Parent.ImageSize.Width + Parent.ImagePadding.Right + Parent.ContentPadding.Left,
Parent.HeaderHeight + Parent.TitlePadding.Top + heightOfTitle + Parent.TitlePadding.Bottom + Parent.ContentPadding.Top,
this.Width - Parent.ImagePadding.Left - Parent.ImageSize.Width - Parent.ImagePadding.Right - Parent.ContentPadding.Left - Parent.ContentPadding.Right - 16 - 5,
this.Height - Parent.HeaderHeight - Parent.TitlePadding.Top - heightOfTitle - Parent.TitlePadding.Bottom - Parent.ContentPadding.Top - Parent.ContentPadding.Bottom - 1);
}
else
{
return new RectangleF(
Parent.ContentPadding.Left,
Parent.HeaderHeight + Parent.TitlePadding.Top + heightOfTitle + Parent.TitlePadding.Bottom + Parent.ContentPadding.Top,
this.Width - Parent.ContentPadding.Left - Parent.ContentPadding.Right - 16 - 5,
this.Height - Parent.HeaderHeight - Parent.TitlePadding.Top - heightOfTitle - Parent.TitlePadding.Bottom - Parent.ContentPadding.Top - Parent.ContentPadding.Bottom - 1);
}
}
}
/// <summary>
/// gets the rectangle of the close button.
/// </summary>
private Rectangle RectClose
{
get { return new Rectangle(this.Width - 5 - 16, Parent.HeaderHeight + 3, 16, 16); }
}
/// <summary>
/// Gets the rectangle of the options button.
/// </summary>
private Rectangle RectOptions
{
get { return new Rectangle(this.Width - 5 - 16, Parent.HeaderHeight + 3 + 16 + 5, 16, 16); }
}
/// <summary>
/// Update form to display hover styles when the mouse moves over the notification form.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PopupNotifierForm_MouseMove(object sender, MouseEventArgs e)
{
if (Parent.ShowCloseButton)
{
mouseOnClose = RectClose.Contains(e.X, e.Y);
}
if (Parent.ShowOptionsButton)
{
mouseOnOptions = RectOptions.Contains(e.X, e.Y);
}
mouseOnLink = RectContentText.Contains(e.X, e.Y);
Invalidate();
}
/// <summary>
/// A mouse button has been released, check if something has been clicked.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PopupNotifierForm_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
if (RectClose.Contains(e.X, e.Y) && (CloseClick != null))
{
CloseClick(this, EventArgs.Empty);
}
if (RectContentText.Contains(e.X, e.Y) && (LinkClick != null))
{
LinkClick(this, EventArgs.Empty);
}
if (RectOptions.Contains(e.X, e.Y) && (Parent.OptionsMenu != null))
{
if (ContextMenuOpened != null)
{
ContextMenuOpened(this, EventArgs.Empty);
}
Parent.OptionsMenu.Show(this, new Point(RectOptions.Right - Parent.OptionsMenu.Width, RectOptions.Bottom));
Parent.OptionsMenu.Closed += new ToolStripDropDownClosedEventHandler(OptionsMenu_Closed);
}
}
}
/// <summary>
/// The options popup menu has been closed.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OptionsMenu_Closed(object sender, ToolStripDropDownClosedEventArgs e)
{
Parent.OptionsMenu.Closed -= new ToolStripDropDownClosedEventHandler(OptionsMenu_Closed);
if (ContextMenuClosed != null)
{
ContextMenuClosed(this, EventArgs.Empty);
}
}
/// <summary>
/// Create all GDI objects used to paint the form.
/// </summary>
private void AllocateGDIObjects()
{
rcBody = new Rectangle(0, 0, this.Width, this.Height);
rcHeader = new Rectangle(0, 0, this.Width, Parent.HeaderHeight);
rcForm = new Rectangle(0, 0, this.Width - 1, this.Height - 1);
brushBody = new LinearGradientBrush(rcBody, Parent.BodyColor, GetLighterColor(Parent.BodyColor), LinearGradientMode.Vertical);
brushHeader = new LinearGradientBrush(rcHeader, Parent.HeaderColor, GetDarkerColor(Parent.HeaderColor), LinearGradientMode.Vertical);
brushButtonHover = new SolidBrush(Parent.ButtonHoverColor);
penButtonBorder = new Pen(Parent.ButtonBorderColor);
penContent = new Pen(Parent.ContentColor, 2);
penBorder = new Pen(Parent.BorderColor);
brushForeColor = new SolidBrush(ForeColor);
brushLinkHover = new SolidBrush(Parent.ContentHoverColor);
brushContent = new SolidBrush(Parent.ContentColor);
brushTitle = new SolidBrush(Parent.TitleColor);
gdiInitialized = true;
}
/// <summary>
/// Free all GDI objects.
/// </summary>
private void DisposeGDIObjects()
{
if (gdiInitialized)
{
brushBody.Dispose();
brushHeader.Dispose();
brushButtonHover.Dispose();
penButtonBorder.Dispose();
penContent.Dispose();
penBorder.Dispose();
brushForeColor.Dispose();
brushLinkHover.Dispose();
brushContent.Dispose();
brushTitle.Dispose();
}
}
/// <summary>
/// Draw the notification form.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PopupNotifierForm_Paint(object sender, PaintEventArgs e)
{
if (!gdiInitialized)
{
AllocateGDIObjects();
}
// draw window
e.Graphics.FillRectangle(brushBody, rcBody);
e.Graphics.FillRectangle(brushHeader, rcHeader);
e.Graphics.DrawRectangle(penBorder, rcForm);
if (Parent.ShowGrip)
{
e.Graphics.DrawImage(Properties.Resources.Grip, (int)((this.Width - Properties.Resources.Grip.Width) / 2), (int)((Parent.HeaderHeight - 3) / 2));
}
if (Parent.ShowCloseButton)
{
if (mouseOnClose)
{
e.Graphics.FillRectangle(brushButtonHover, RectClose);
e.Graphics.DrawRectangle(penButtonBorder, RectClose);
}
e.Graphics.DrawLine(penContent, RectClose.Left + 4, RectClose.Top + 4, RectClose.Right - 4, RectClose.Bottom - 4);
e.Graphics.DrawLine(penContent, RectClose.Left + 4, RectClose.Bottom - 4, RectClose.Right - 4, RectClose.Top + 4);
}
if (Parent.ShowOptionsButton)
{
if (mouseOnOptions)
{
e.Graphics.FillRectangle(brushButtonHover, RectOptions);
e.Graphics.DrawRectangle(penButtonBorder, RectOptions);
}
e.Graphics.FillPolygon(brushForeColor, new Point[] { new Point(RectOptions.Left + 4, RectOptions.Top + 6), new Point(RectOptions.Left + 12, RectOptions.Top + 6), new Point(RectOptions.Left + 8, RectOptions.Top + 4 + 6) });
}
// draw icon
if (Parent.Image != null)
{
e.Graphics.DrawImage(Parent.Image, Parent.ImagePadding.Left, Parent.HeaderHeight + Parent.ImagePadding.Top, Parent.ImageSize.Width, Parent.ImageSize.Height);
}
if (Parent.IsRightToLeft)
{
heightOfTitle = (int)e.Graphics.MeasureString("A", Parent.TitleFont).Height;
// the value 30 is because of x close icon
int titleX2 = this.Width - 30;// Parent.TitlePadding.Right;
// draw title right to left
StringFormat headerFormat = new StringFormat(StringFormatFlags.DirectionRightToLeft);
e.Graphics.DrawString(Parent.TitleText, Parent.TitleFont, brushTitle, titleX2, Parent.HeaderHeight + Parent.TitlePadding.Top, headerFormat);
// draw content text, optionally with a bold part
this.Cursor = mouseOnLink ? Cursors.Hand : Cursors.Default;
Brush brushText = mouseOnLink ? brushLinkHover : brushContent;
// draw content right to left
StringFormat contentFormat = new StringFormat(StringFormatFlags.DirectionRightToLeft);
e.Graphics.DrawString(Parent.ContentText, Parent.ContentFont, brushText, RectContentText, contentFormat);
}
else
{
// calculate height of title
heightOfTitle = (int)e.Graphics.MeasureString("A", Parent.TitleFont).Height;
int titleX = Parent.TitlePadding.Left;
if (Parent.Image != null)
titleX += Parent.ImagePadding.Left + Parent.ImageSize.Width + Parent.ImagePadding.Right;
e.Graphics.DrawString(Parent.TitleText, Parent.TitleFont, brushTitle, titleX, Parent.HeaderHeight + Parent.TitlePadding.Top);
// draw content text, optionally with a bold part
this.Cursor = mouseOnLink ? Cursors.Hand : Cursors.Default;
Brush brushText = mouseOnLink ? brushLinkHover : brushContent;
e.Graphics.DrawString(Parent.ContentText, Parent.ContentFont, brushText, RectContentText);
}
}
/// <summary>
/// Dispose GDI objects.
/// </summary>
/// <param name="disposing"></param>
protected override void Dispose(bool disposing)
{
if (disposing)
{
DisposeGDIObjects();
}
base.Dispose(disposing);
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Tulpep.NotificationWindow")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Tulpep.NotificationWindow")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("718bace5-a97f-4a78-ad50-5730eba79995")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,73 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Tulpep.NotificationWindow.Properties {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Tulpep.NotificationWindow.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap Grip {
get {
object obj = ResourceManager.GetObject("Grip", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Grip" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Grip.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View File

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{605006EB-D4E6-4312-A293-3A43FAC43240}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Tulpep.NotificationWindow</RootNamespace>
<AssemblyName>Tulpep.NotificationWindow</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="PopupNotifier.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="PopupNotifierForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="Grip.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Icon.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>