Adding tray icon support and minimize to tray option.
authorsl
Sun, 18 Jan 2015 18:11:32 +0100
changeset 94fe939a729030
parent 93 f0015e909f41
child 95 a4a02cc952a0
Adding tray icon support and minimize to tray option.
Server/App.config
Server/MainForm.Designer.cs
Server/MainForm.cs
Server/NotifyIconAdv.cs
Server/Properties/Resources.resx
Server/Properties/Settings.Designer.cs
Server/Properties/Settings.settings
Server/Resources/vfd.ico
Server/SharpDisplayManager.csproj
Server/vfd.ico
     1.1 --- a/Server/App.config	Sun Jan 18 14:18:28 2015 +0100
     1.2 +++ b/Server/App.config	Sun Jan 18 18:11:32 2015 +0100
     1.3 @@ -19,6 +19,12 @@
     1.4              <setting name="CycleClients" serializeAs="String">
     1.5                  <value>False</value>
     1.6              </setting>
     1.7 +            <setting name="MinimizeToTray" serializeAs="String">
     1.8 +                <value>False</value>
     1.9 +            </setting>
    1.10 +            <setting name="StartMinimized" serializeAs="String">
    1.11 +                <value>False</value>
    1.12 +            </setting>
    1.13          </SharpDisplayManager.Properties.Settings>
    1.14      </userSettings>
    1.15  </configuration>
     2.1 --- a/Server/MainForm.Designer.cs	Sun Jan 18 14:18:28 2015 +0100
     2.2 +++ b/Server/MainForm.Designer.cs	Sun Jan 18 18:11:32 2015 +0100
     2.3 @@ -77,6 +77,8 @@
     2.4  			this.buttonRemoveRow = new System.Windows.Forms.Button();
     2.5  			this.buttonAddRow = new System.Windows.Forms.Button();
     2.6  			this.tabPageApp = new System.Windows.Forms.TabPage();
     2.7 +			this.checkBoxStartMinimized = new System.Windows.Forms.CheckBox();
     2.8 +			this.checkBoxMinimizeToTray = new System.Windows.Forms.CheckBox();
     2.9  			this.checkBoxAutoStart = new System.Windows.Forms.CheckBox();
    2.10  			this.buttonUpdate = new System.Windows.Forms.Button();
    2.11  			this.labelFontWidth = new System.Windows.Forms.Label();
    2.12 @@ -614,6 +616,8 @@
    2.13  			// 
    2.14  			// tabPageApp
    2.15  			// 
    2.16 +			this.tabPageApp.Controls.Add(this.checkBoxStartMinimized);
    2.17 +			this.tabPageApp.Controls.Add(this.checkBoxMinimizeToTray);
    2.18  			this.tabPageApp.Controls.Add(this.checkBoxAutoStart);
    2.19  			this.tabPageApp.Controls.Add(this.buttonUpdate);
    2.20  			this.tabPageApp.Location = new System.Drawing.Point(4, 22);
    2.21 @@ -624,15 +628,39 @@
    2.22  			this.tabPageApp.Text = "Application";
    2.23  			this.tabPageApp.UseVisualStyleBackColor = true;
    2.24  			// 
    2.25 +			// checkBoxStartMinimized
    2.26 +			// 
    2.27 +			this.checkBoxStartMinimized.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
    2.28 +			this.checkBoxStartMinimized.AutoSize = true;
    2.29 +			this.checkBoxStartMinimized.Location = new System.Drawing.Point(8, 144);
    2.30 +			this.checkBoxStartMinimized.Name = "checkBoxStartMinimized";
    2.31 +			this.checkBoxStartMinimized.Size = new System.Drawing.Size(96, 17);
    2.32 +			this.checkBoxStartMinimized.TabIndex = 16;
    2.33 +			this.checkBoxStartMinimized.Text = "Start minimized";
    2.34 +			this.checkBoxStartMinimized.UseVisualStyleBackColor = true;
    2.35 +			this.checkBoxStartMinimized.CheckedChanged += new System.EventHandler(this.checkBoxStartMinimized_CheckedChanged);
    2.36 +			// 
    2.37 +			// checkBoxMinimizeToTray
    2.38 +			// 
    2.39 +			this.checkBoxMinimizeToTray.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
    2.40 +			this.checkBoxMinimizeToTray.AutoSize = true;
    2.41 +			this.checkBoxMinimizeToTray.Location = new System.Drawing.Point(8, 167);
    2.42 +			this.checkBoxMinimizeToTray.Name = "checkBoxMinimizeToTray";
    2.43 +			this.checkBoxMinimizeToTray.Size = new System.Drawing.Size(133, 17);
    2.44 +			this.checkBoxMinimizeToTray.TabIndex = 15;
    2.45 +			this.checkBoxMinimizeToTray.Text = "Minimize to system tray";
    2.46 +			this.checkBoxMinimizeToTray.UseVisualStyleBackColor = true;
    2.47 +			this.checkBoxMinimizeToTray.CheckedChanged += new System.EventHandler(this.checkBoxMinimizeToTray_CheckedChanged);
    2.48 +			// 
    2.49  			// checkBoxAutoStart
    2.50  			// 
    2.51  			this.checkBoxAutoStart.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
    2.52  			this.checkBoxAutoStart.AutoSize = true;
    2.53  			this.checkBoxAutoStart.Location = new System.Drawing.Point(8, 190);
    2.54  			this.checkBoxAutoStart.Name = "checkBoxAutoStart";
    2.55 -			this.checkBoxAutoStart.Size = new System.Drawing.Size(73, 17);
    2.56 +			this.checkBoxAutoStart.Size = new System.Drawing.Size(143, 17);
    2.57  			this.checkBoxAutoStart.TabIndex = 14;
    2.58 -			this.checkBoxAutoStart.Text = "Auto Start";
    2.59 +			this.checkBoxAutoStart.Text = "Run on Windows startup";
    2.60  			this.checkBoxAutoStart.UseVisualStyleBackColor = true;
    2.61  			this.checkBoxAutoStart.CheckedChanged += new System.EventHandler(this.checkBoxAutoStart_CheckedChanged);
    2.62  			// 
    2.63 @@ -690,6 +718,7 @@
    2.64  			this.Text = "Sharp Display Manager";
    2.65  			this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
    2.66  			this.Load += new System.EventHandler(this.MainForm_Load);
    2.67 +			this.SizeChanged += new System.EventHandler(this.MainForm_SizeChanged);
    2.68  			this.Resize += new System.EventHandler(this.MainForm_Resize);
    2.69  			this.panelDisplay.ResumeLayout(false);
    2.70  			this.tableLayoutPanel.ResumeLayout(false);
    2.71 @@ -765,6 +794,8 @@
    2.72          private System.Windows.Forms.TabPage tabPageApp;
    2.73          private System.Windows.Forms.Button buttonUpdate;
    2.74  		private System.Windows.Forms.CheckBox checkBoxAutoStart;
    2.75 +		private System.Windows.Forms.CheckBox checkBoxStartMinimized;
    2.76 +		private System.Windows.Forms.CheckBox checkBoxMinimizeToTray;
    2.77      }
    2.78  }
    2.79  
     3.1 --- a/Server/MainForm.cs	Sun Jan 18 14:18:28 2015 +0100
     3.2 +++ b/Server/MainForm.cs	Sun Jan 18 18:11:32 2015 +0100
     3.3 @@ -14,6 +14,7 @@
     3.4  using System.Threading;
     3.5  using System.Diagnostics;
     3.6  using System.Deployment.Application;
     3.7 +using System.Reflection;
     3.8  //
     3.9  using SharpDisplayClient;
    3.10  using SharpDisplay;
    3.11 @@ -57,9 +58,16 @@
    3.12          //Function pointer for pixel Y coordinate intercept
    3.13          CoordinateTranslationDelegate iScreenY;
    3.14  
    3.15 -		//
    3.16 +		/// <summary>
    3.17 +		/// Manage run when Windows startup option
    3.18 +		/// </summary>
    3.19  		private StartupManager iStartupManager;
    3.20  
    3.21 +		/// <summary>
    3.22 +		/// System tray icon.
    3.23 +		/// </summary>
    3.24 +		private NotifyIconAdv iNotifyIcon;
    3.25 +
    3.26          public MainForm()
    3.27          {
    3.28              iCurrentClientSessionId = "";
    3.29 @@ -68,14 +76,26 @@
    3.30              iDisplay = new Display();
    3.31              iClients = new Dictionary<string, ClientData>();
    3.32  			iStartupManager = new StartupManager();
    3.33 +			iNotifyIcon = new NotifyIconAdv();
    3.34  
    3.35              InitializeComponent();
    3.36              UpdateStatus();
    3.37              //We have a bug when drawing minimized and reusing our bitmap
    3.38              iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
    3.39              iCreateBitmap = false;
    3.40 +
    3.41 +			if (Properties.Settings.Default.StartMinimized)
    3.42 +			{
    3.43 +				WindowState = FormWindowState.Minimized;
    3.44 +			}
    3.45 +
    3.46          }
    3.47  
    3.48 +		/// <summary>
    3.49 +		/// 
    3.50 +		/// </summary>
    3.51 +		/// <param name="sender"></param>
    3.52 +		/// <param name="e"></param>
    3.53          private void MainForm_Load(object sender, EventArgs e)
    3.54          {
    3.55  			if (ApplicationDeployment.IsNetworkDeployed)
    3.56 @@ -94,10 +114,53 @@
    3.57                  OpenDisplayConnection();
    3.58              }
    3.59  
    3.60 -			//
    3.61 +			//Check if "run on Windows startup" is enabled
    3.62  			checkBoxAutoStart.Checked=iStartupManager.Startup;
    3.63 +
    3.64 +
    3.65 +			//Setup notification icon
    3.66 +			iNotifyIcon.Icon = GetIcon("vfd.ico");
    3.67 +			iNotifyIcon.Text = "Sharp Display Manager";
    3.68 +			iNotifyIcon.Visible = true;
    3.69 +			iNotifyIcon.DoubleClick += delegate(object obj, EventArgs args)
    3.70 +			{
    3.71 +				SysTrayHideShow();
    3.72 +			};
    3.73 +
    3.74 +			// To make sure start up with minimize to tray works
    3.75 +			if (WindowState == FormWindowState.Minimized && Properties.Settings.Default.MinimizeToTray)
    3.76 +			{
    3.77 +				Visible = false;
    3.78 +			}
    3.79          }
    3.80  
    3.81 +		/// <summary>
    3.82 +		/// Access icons from embedded resources.
    3.83 +		/// </summary>
    3.84 +		/// <param name="name"></param>
    3.85 +		/// <returns></returns>
    3.86 +		public static Icon GetIcon(string name)
    3.87 +		{
    3.88 +			name = "SharpDisplayManager.Resources." + name;
    3.89 +
    3.90 +			string[] names =
    3.91 +			  Assembly.GetExecutingAssembly().GetManifestResourceNames();
    3.92 +			for (int i = 0; i < names.Length; i++)
    3.93 +			{
    3.94 +				if (names[i].Replace('\\', '.') == name)
    3.95 +				{
    3.96 +					using (Stream stream = Assembly.GetExecutingAssembly().
    3.97 +					  GetManifestResourceStream(names[i]))
    3.98 +					{
    3.99 +						return new Icon(stream);
   3.100 +					}
   3.101 +				}
   3.102 +			}
   3.103 +
   3.104 +			return null;
   3.105 +		}
   3.106 +
   3.107 +
   3.108          /// <summary>
   3.109          /// Set our current client.
   3.110          /// This will take care of applying our client layout and set data fields.
   3.111 @@ -520,6 +583,8 @@
   3.112  
   3.113              CheckFontHeight();
   3.114              checkBoxConnectOnStartup.Checked = Properties.Settings.Default.DisplayConnectOnStartup;
   3.115 +			checkBoxMinimizeToTray.Checked = Properties.Settings.Default.MinimizeToTray;
   3.116 +			checkBoxStartMinimized.Checked = Properties.Settings.Default.StartMinimized;
   3.117              checkBoxReverseScreen.Checked = cds.ReverseScreen;
   3.118              checkBoxInverseColors.Checked = cds.InverseColors;
   3.119              comboBoxDisplayType.SelectedIndex = cds.DisplayType;
   3.120 @@ -602,6 +667,27 @@
   3.121              Properties.Settings.Default.Save();
   3.122          }
   3.123  
   3.124 +		private void checkBoxMinimizeToTray_CheckedChanged(object sender, EventArgs e)
   3.125 +		{
   3.126 +			//Save our "Minimize to tray" setting
   3.127 +			Properties.Settings.Default.MinimizeToTray = checkBoxMinimizeToTray.Checked;
   3.128 +			Properties.Settings.Default.Save();
   3.129 +
   3.130 +		}
   3.131 +
   3.132 +		private void checkBoxStartMinimized_CheckedChanged(object sender, EventArgs e)
   3.133 +		{
   3.134 +			//Save our "Start minimized" setting
   3.135 +			Properties.Settings.Default.StartMinimized = checkBoxStartMinimized.Checked;
   3.136 +			Properties.Settings.Default.Save();
   3.137 +		}
   3.138 +
   3.139 +		private void checkBoxAutoStart_CheckedChanged(object sender, EventArgs e)
   3.140 +		{
   3.141 +			iStartupManager.Startup = checkBoxAutoStart.Checked;
   3.142 +		}
   3.143 +
   3.144 +
   3.145          private void checkBoxReverseScreen_CheckedChanged(object sender, EventArgs e)
   3.146          {
   3.147              //Save our reverse screen setting
   3.148 @@ -1413,10 +1499,37 @@
   3.149              }
   3.150          }
   3.151  
   3.152 -		private void checkBoxAutoStart_CheckedChanged(object sender, EventArgs e)
   3.153 +
   3.154 +		/// <summary>
   3.155 +		/// Used to 
   3.156 +		/// </summary>
   3.157 +		private void SysTrayHideShow()
   3.158  		{
   3.159 -			iStartupManager.Startup = checkBoxAutoStart.Checked;
   3.160 +			Visible = !Visible;
   3.161 +			if (Visible)
   3.162 +			{
   3.163 +				Activate();
   3.164 +				WindowState = FormWindowState.Normal;
   3.165 +			}
   3.166  		}
   3.167 +
   3.168 +		/// <summary>
   3.169 +		/// Use to handle minimize events.
   3.170 +		/// </summary>
   3.171 +		/// <param name="sender"></param>
   3.172 +		/// <param name="e"></param>
   3.173 +		private void MainForm_SizeChanged(object sender, EventArgs e)
   3.174 +		{
   3.175 +			if (WindowState == FormWindowState.Minimized && Properties.Settings.Default.MinimizeToTray)
   3.176 +			{
   3.177 +				if (Visible)
   3.178 +				{
   3.179 +					SysTrayHideShow();
   3.180 +				}
   3.181 +			}
   3.182 +			
   3.183 +		}
   3.184 +
   3.185      }
   3.186  
   3.187      /// <summary>
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/Server/NotifyIconAdv.cs	Sun Jan 18 18:11:32 2015 +0100
     4.3 @@ -0,0 +1,969 @@
     4.4 +/*
     4.5 +
     4.6 +  This Source Code Form is subject to the terms of the Mozilla Public
     4.7 +  License, v. 2.0. If a copy of the MPL was not distributed with this
     4.8 +  file, You can obtain one at http://mozilla.org/MPL/2.0/.
     4.9 +
    4.10 +  Copyright (C) 2012 Michael Möller <mmoeller@openhardwaremonitor.org>
    4.11 +
    4.12 +*/
    4.13 +
    4.14 +using System;
    4.15 +using System.ComponentModel;
    4.16 +using System.Drawing;
    4.17 +using System.Reflection;
    4.18 +using System.Runtime.InteropServices;
    4.19 +using System.Windows.Forms;
    4.20 +
    4.21 +namespace SharpDisplayManager
    4.22 +{
    4.23 +	public class NotifyIconAdv : IDisposable
    4.24 +	{
    4.25 +		private NotifyIcon genericNotifyIcon;
    4.26 +		private NotifyIconWindowsImplementation windowsNotifyIcon;
    4.27 +
    4.28 +		public NotifyIconAdv()
    4.29 +		{
    4.30 +			int p = (int)Environment.OSVersion.Platform;
    4.31 +			if ((p == 4) || (p == 128))
    4.32 +			{ // Unix
    4.33 +				genericNotifyIcon = new NotifyIcon();
    4.34 +			}
    4.35 +			else
    4.36 +			{ // Windows
    4.37 +				windowsNotifyIcon = new NotifyIconWindowsImplementation();
    4.38 +			}
    4.39 +		}
    4.40 +
    4.41 +		public event EventHandler BalloonTipClicked
    4.42 +		{
    4.43 +			add
    4.44 +			{
    4.45 +				if (genericNotifyIcon != null)
    4.46 +					genericNotifyIcon.BalloonTipClicked += value;
    4.47 +				else
    4.48 +					windowsNotifyIcon.BalloonTipClicked += value;
    4.49 +			}
    4.50 +			remove
    4.51 +			{
    4.52 +				if (genericNotifyIcon != null)
    4.53 +					genericNotifyIcon.BalloonTipClicked -= value;
    4.54 +				else
    4.55 +					windowsNotifyIcon.BalloonTipClicked -= value;
    4.56 +			}
    4.57 +		}
    4.58 +
    4.59 +		public event EventHandler BalloonTipClosed
    4.60 +		{
    4.61 +			add
    4.62 +			{
    4.63 +				if (genericNotifyIcon != null)
    4.64 +					genericNotifyIcon.BalloonTipClosed += value;
    4.65 +				else
    4.66 +					windowsNotifyIcon.BalloonTipClosed += value;
    4.67 +			}
    4.68 +			remove
    4.69 +			{
    4.70 +				if (genericNotifyIcon != null)
    4.71 +					genericNotifyIcon.BalloonTipClosed -= value;
    4.72 +				else
    4.73 +					windowsNotifyIcon.BalloonTipClosed -= value;
    4.74 +			}
    4.75 +		}
    4.76 +
    4.77 +		public event EventHandler BalloonTipShown
    4.78 +		{
    4.79 +			add
    4.80 +			{
    4.81 +				if (genericNotifyIcon != null)
    4.82 +					genericNotifyIcon.BalloonTipShown += value;
    4.83 +				else
    4.84 +					windowsNotifyIcon.BalloonTipShown += value;
    4.85 +			}
    4.86 +			remove
    4.87 +			{
    4.88 +				if (genericNotifyIcon != null)
    4.89 +					genericNotifyIcon.BalloonTipShown -= value;
    4.90 +				else
    4.91 +					windowsNotifyIcon.BalloonTipShown -= value;
    4.92 +			}
    4.93 +		}
    4.94 +
    4.95 +		public event EventHandler Click
    4.96 +		{
    4.97 +			add
    4.98 +			{
    4.99 +				if (genericNotifyIcon != null)
   4.100 +					genericNotifyIcon.Click += value;
   4.101 +				else
   4.102 +					windowsNotifyIcon.Click += value;
   4.103 +			}
   4.104 +			remove
   4.105 +			{
   4.106 +				if (genericNotifyIcon != null)
   4.107 +					genericNotifyIcon.Click -= value;
   4.108 +				else
   4.109 +					windowsNotifyIcon.Click -= value;
   4.110 +			}
   4.111 +		}
   4.112 +
   4.113 +		public event EventHandler DoubleClick
   4.114 +		{
   4.115 +			add
   4.116 +			{
   4.117 +				if (genericNotifyIcon != null)
   4.118 +					genericNotifyIcon.DoubleClick += value;
   4.119 +				else
   4.120 +					windowsNotifyIcon.DoubleClick += value;
   4.121 +			}
   4.122 +			remove
   4.123 +			{
   4.124 +				if (genericNotifyIcon != null)
   4.125 +					genericNotifyIcon.DoubleClick -= value;
   4.126 +				else
   4.127 +					windowsNotifyIcon.DoubleClick -= value;
   4.128 +			}
   4.129 +		}
   4.130 +
   4.131 +		public event MouseEventHandler MouseClick
   4.132 +		{
   4.133 +			add
   4.134 +			{
   4.135 +				if (genericNotifyIcon != null)
   4.136 +					genericNotifyIcon.MouseClick += value;
   4.137 +				else
   4.138 +					windowsNotifyIcon.MouseClick += value;
   4.139 +			}
   4.140 +			remove
   4.141 +			{
   4.142 +				if (genericNotifyIcon != null)
   4.143 +					genericNotifyIcon.MouseClick -= value;
   4.144 +				else
   4.145 +					windowsNotifyIcon.MouseClick -= value;
   4.146 +			}
   4.147 +		}
   4.148 +
   4.149 +		public event MouseEventHandler MouseDoubleClick
   4.150 +		{
   4.151 +			add
   4.152 +			{
   4.153 +				if (genericNotifyIcon != null)
   4.154 +					genericNotifyIcon.MouseDoubleClick += value;
   4.155 +				else
   4.156 +					windowsNotifyIcon.MouseDoubleClick += value;
   4.157 +			}
   4.158 +			remove
   4.159 +			{
   4.160 +				if (genericNotifyIcon != null)
   4.161 +					genericNotifyIcon.MouseDoubleClick -= value;
   4.162 +				else
   4.163 +					windowsNotifyIcon.MouseDoubleClick -= value;
   4.164 +			}
   4.165 +		}
   4.166 +
   4.167 +		public event MouseEventHandler MouseDown
   4.168 +		{
   4.169 +			add
   4.170 +			{
   4.171 +				if (genericNotifyIcon != null)
   4.172 +					genericNotifyIcon.MouseDown += value;
   4.173 +				else
   4.174 +					windowsNotifyIcon.MouseDown += value;
   4.175 +			}
   4.176 +			remove
   4.177 +			{
   4.178 +				if (genericNotifyIcon != null)
   4.179 +					genericNotifyIcon.MouseDown -= value;
   4.180 +				else
   4.181 +					windowsNotifyIcon.MouseDown -= value;
   4.182 +			}
   4.183 +		}
   4.184 +
   4.185 +		public event MouseEventHandler MouseMove
   4.186 +		{
   4.187 +			add
   4.188 +			{
   4.189 +				if (genericNotifyIcon != null)
   4.190 +					genericNotifyIcon.MouseMove += value;
   4.191 +				else
   4.192 +					windowsNotifyIcon.MouseMove += value;
   4.193 +			}
   4.194 +			remove
   4.195 +			{
   4.196 +				if (genericNotifyIcon != null)
   4.197 +					genericNotifyIcon.MouseMove -= value;
   4.198 +				else
   4.199 +					windowsNotifyIcon.MouseMove -= value;
   4.200 +			}
   4.201 +		}
   4.202 +
   4.203 +		public event MouseEventHandler MouseUp
   4.204 +		{
   4.205 +			add
   4.206 +			{
   4.207 +				if (genericNotifyIcon != null)
   4.208 +					genericNotifyIcon.MouseUp += value;
   4.209 +				else
   4.210 +					windowsNotifyIcon.MouseUp += value;
   4.211 +			}
   4.212 +			remove
   4.213 +			{
   4.214 +				if (genericNotifyIcon != null)
   4.215 +					genericNotifyIcon.MouseUp -= value;
   4.216 +				else
   4.217 +					windowsNotifyIcon.MouseUp -= value;
   4.218 +			}
   4.219 +		}
   4.220 +
   4.221 +		public string BalloonTipText
   4.222 +		{
   4.223 +			get
   4.224 +			{
   4.225 +				if (genericNotifyIcon != null)
   4.226 +					return genericNotifyIcon.BalloonTipText;
   4.227 +				else
   4.228 +					return windowsNotifyIcon.BalloonTipText;
   4.229 +			}
   4.230 +			set
   4.231 +			{
   4.232 +				if (genericNotifyIcon != null)
   4.233 +					genericNotifyIcon.BalloonTipText = value;
   4.234 +				else
   4.235 +					windowsNotifyIcon.BalloonTipText = value;
   4.236 +			}
   4.237 +		}
   4.238 +
   4.239 +		public ToolTipIcon BalloonTipIcon
   4.240 +		{
   4.241 +			get
   4.242 +			{
   4.243 +				if (genericNotifyIcon != null)
   4.244 +					return genericNotifyIcon.BalloonTipIcon;
   4.245 +				else
   4.246 +					return windowsNotifyIcon.BalloonTipIcon;
   4.247 +			}
   4.248 +			set
   4.249 +			{
   4.250 +				if (genericNotifyIcon != null)
   4.251 +					genericNotifyIcon.BalloonTipIcon = value;
   4.252 +				else
   4.253 +					windowsNotifyIcon.BalloonTipIcon = value;
   4.254 +			}
   4.255 +		}
   4.256 +
   4.257 +		public string BalloonTipTitle
   4.258 +		{
   4.259 +			get
   4.260 +			{
   4.261 +				if (genericNotifyIcon != null)
   4.262 +					return genericNotifyIcon.BalloonTipTitle;
   4.263 +				else
   4.264 +					return windowsNotifyIcon.BalloonTipTitle;
   4.265 +			}
   4.266 +			set
   4.267 +			{
   4.268 +				if (genericNotifyIcon != null)
   4.269 +					genericNotifyIcon.BalloonTipTitle = value;
   4.270 +				else
   4.271 +					windowsNotifyIcon.BalloonTipTitle = value;
   4.272 +			}
   4.273 +		}
   4.274 +
   4.275 +		public ContextMenu ContextMenu
   4.276 +		{
   4.277 +			get
   4.278 +			{
   4.279 +				if (genericNotifyIcon != null)
   4.280 +					return genericNotifyIcon.ContextMenu;
   4.281 +				else
   4.282 +					return windowsNotifyIcon.ContextMenu;
   4.283 +			}
   4.284 +			set
   4.285 +			{
   4.286 +				if (genericNotifyIcon != null)
   4.287 +					genericNotifyIcon.ContextMenu = value;
   4.288 +				else
   4.289 +					windowsNotifyIcon.ContextMenu = value;
   4.290 +			}
   4.291 +		}
   4.292 +
   4.293 +		public ContextMenuStrip ContextMenuStrip
   4.294 +		{
   4.295 +			get
   4.296 +			{
   4.297 +				if (genericNotifyIcon != null)
   4.298 +					return genericNotifyIcon.ContextMenuStrip;
   4.299 +				else
   4.300 +					return windowsNotifyIcon.ContextMenuStrip;
   4.301 +			}
   4.302 +			set
   4.303 +			{
   4.304 +				if (genericNotifyIcon != null)
   4.305 +					genericNotifyIcon.ContextMenuStrip = value;
   4.306 +				else
   4.307 +					windowsNotifyIcon.ContextMenuStrip = value;
   4.308 +			}
   4.309 +		}
   4.310 +
   4.311 +		public object Tag { get; set; }
   4.312 +
   4.313 +		public Icon Icon
   4.314 +		{
   4.315 +			get
   4.316 +			{
   4.317 +				if (genericNotifyIcon != null)
   4.318 +					return genericNotifyIcon.Icon;
   4.319 +				else
   4.320 +					return windowsNotifyIcon.Icon;
   4.321 +			}
   4.322 +			set
   4.323 +			{
   4.324 +				if (genericNotifyIcon != null)
   4.325 +					genericNotifyIcon.Icon = value;
   4.326 +				else
   4.327 +					windowsNotifyIcon.Icon = value;
   4.328 +			}
   4.329 +		}
   4.330 +
   4.331 +		public string Text
   4.332 +		{
   4.333 +			get
   4.334 +			{
   4.335 +				if (genericNotifyIcon != null)
   4.336 +					return genericNotifyIcon.Text;
   4.337 +				else
   4.338 +					return windowsNotifyIcon.Text;
   4.339 +			}
   4.340 +			set
   4.341 +			{
   4.342 +				if (genericNotifyIcon != null)
   4.343 +					genericNotifyIcon.Text = value;
   4.344 +				else
   4.345 +					windowsNotifyIcon.Text = value;
   4.346 +			}
   4.347 +		}
   4.348 +
   4.349 +		public bool Visible
   4.350 +		{
   4.351 +			get
   4.352 +			{
   4.353 +				if (genericNotifyIcon != null)
   4.354 +					return genericNotifyIcon.Visible;
   4.355 +				else
   4.356 +					return windowsNotifyIcon.Visible;
   4.357 +			}
   4.358 +			set
   4.359 +			{
   4.360 +				if (genericNotifyIcon != null)
   4.361 +					genericNotifyIcon.Visible = value;
   4.362 +				else
   4.363 +					windowsNotifyIcon.Visible = value;
   4.364 +			}
   4.365 +		}
   4.366 +
   4.367 +		public void Dispose()
   4.368 +		{
   4.369 +			if (genericNotifyIcon != null)
   4.370 +				genericNotifyIcon.Dispose();
   4.371 +			else
   4.372 +				windowsNotifyIcon.Dispose();
   4.373 +		}
   4.374 +
   4.375 +		public void ShowBalloonTip(int timeout)
   4.376 +		{
   4.377 +			ShowBalloonTip(timeout, BalloonTipTitle, BalloonTipText, BalloonTipIcon);
   4.378 +		}
   4.379 +
   4.380 +		public void ShowBalloonTip(int timeout, string tipTitle, string tipText,
   4.381 +		  ToolTipIcon tipIcon)
   4.382 +		{
   4.383 +			if (genericNotifyIcon != null)
   4.384 +				genericNotifyIcon.ShowBalloonTip(timeout, tipTitle, tipText, tipIcon);
   4.385 +			else
   4.386 +				windowsNotifyIcon.ShowBalloonTip(timeout, tipTitle, tipText, tipIcon);
   4.387 +		}
   4.388 +
   4.389 +		private class NotifyIconWindowsImplementation : Component
   4.390 +		{
   4.391 +			private static int nextId = 0;
   4.392 +
   4.393 +			private object syncObj = new object();
   4.394 +			private Icon icon;
   4.395 +			private string text = "";
   4.396 +			private int id;
   4.397 +			private bool created;
   4.398 +			private NotifyIconNativeWindow window;
   4.399 +			private bool doubleClickDown;
   4.400 +			private bool visible;
   4.401 +			private MethodInfo commandDispatch;
   4.402 +
   4.403 +			public event EventHandler BalloonTipClicked;
   4.404 +
   4.405 +			public event EventHandler BalloonTipClosed;
   4.406 +
   4.407 +			public event EventHandler BalloonTipShown;
   4.408 +
   4.409 +			public event EventHandler Click;
   4.410 +
   4.411 +			public event EventHandler DoubleClick;
   4.412 +
   4.413 +			public event MouseEventHandler MouseClick;
   4.414 +
   4.415 +			public event MouseEventHandler MouseDoubleClick;
   4.416 +
   4.417 +			public event MouseEventHandler MouseDown;
   4.418 +
   4.419 +			public event MouseEventHandler MouseMove;
   4.420 +
   4.421 +			public event MouseEventHandler MouseUp;
   4.422 +
   4.423 +			public string BalloonTipText { get; set; }
   4.424 +
   4.425 +			public ToolTipIcon BalloonTipIcon { get; set; }
   4.426 +
   4.427 +			public string BalloonTipTitle { get; set; }
   4.428 +
   4.429 +			public ContextMenu ContextMenu { get; set; }
   4.430 +
   4.431 +			public ContextMenuStrip ContextMenuStrip { get; set; }
   4.432 +
   4.433 +			public object Tag { get; set; }
   4.434 +
   4.435 +			public Icon Icon
   4.436 +			{
   4.437 +				get
   4.438 +				{
   4.439 +					return icon;
   4.440 +				}
   4.441 +				set
   4.442 +				{
   4.443 +					if (icon != value)
   4.444 +					{
   4.445 +						icon = value;
   4.446 +						UpdateNotifyIcon(visible);
   4.447 +					}
   4.448 +				}
   4.449 +			}
   4.450 +
   4.451 +			public string Text
   4.452 +			{
   4.453 +				get
   4.454 +				{
   4.455 +					return text;
   4.456 +				}
   4.457 +				set
   4.458 +				{
   4.459 +					if (value == null)
   4.460 +						value = "";
   4.461 +
   4.462 +					if (value.Length > 63)
   4.463 +						throw new ArgumentOutOfRangeException();
   4.464 +
   4.465 +					if (!value.Equals(text))
   4.466 +					{
   4.467 +						text = value;
   4.468 +
   4.469 +						if (visible)
   4.470 +							UpdateNotifyIcon(visible);
   4.471 +					}
   4.472 +				}
   4.473 +			}
   4.474 +
   4.475 +			public bool Visible
   4.476 +			{
   4.477 +				get
   4.478 +				{
   4.479 +					return visible;
   4.480 +				}
   4.481 +				set
   4.482 +				{
   4.483 +					if (visible != value)
   4.484 +					{
   4.485 +						visible = value;
   4.486 +						UpdateNotifyIcon(visible);
   4.487 +					}
   4.488 +				}
   4.489 +			}
   4.490 +
   4.491 +			public NotifyIconWindowsImplementation()
   4.492 +			{
   4.493 +				BalloonTipText = "";
   4.494 +				BalloonTipTitle = "";
   4.495 +
   4.496 +				commandDispatch = typeof(Form).Assembly.
   4.497 +				  GetType("System.Windows.Forms.Command").GetMethod("DispatchID",
   4.498 +				  BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public,
   4.499 +				  null, new Type[] { typeof(int) }, null);
   4.500 +
   4.501 +				id = ++NotifyIconWindowsImplementation.nextId;
   4.502 +				window = new NotifyIconNativeWindow(this);
   4.503 +				UpdateNotifyIcon(visible);
   4.504 +			}
   4.505 +
   4.506 +			protected override void Dispose(bool disposing)
   4.507 +			{
   4.508 +				if (disposing)
   4.509 +				{
   4.510 +					if (window != null)
   4.511 +					{
   4.512 +						icon = null;
   4.513 +						text = "";
   4.514 +						UpdateNotifyIcon(false);
   4.515 +						window.DestroyHandle();
   4.516 +						window = null;
   4.517 +						ContextMenu = null;
   4.518 +						ContextMenuStrip = null;
   4.519 +					}
   4.520 +				}
   4.521 +				else
   4.522 +				{
   4.523 +					if (window != null && window.Handle != IntPtr.Zero)
   4.524 +					{
   4.525 +						NativeMethods.PostMessage(
   4.526 +						  new HandleRef(window, window.Handle), WM_CLOSE, 0, 0);
   4.527 +						window.ReleaseHandle();
   4.528 +					}
   4.529 +				}
   4.530 +				base.Dispose(disposing);
   4.531 +			}
   4.532 +
   4.533 +			public void ShowBalloonTip(int timeout)
   4.534 +			{
   4.535 +				ShowBalloonTip(timeout, BalloonTipTitle, BalloonTipText, BalloonTipIcon);
   4.536 +			}
   4.537 +
   4.538 +			public void ShowBalloonTip(int timeout, string tipTitle, string tipText,
   4.539 +			  ToolTipIcon tipIcon)
   4.540 +			{
   4.541 +				if (timeout < 0)
   4.542 +					throw new ArgumentOutOfRangeException("timeout");
   4.543 +
   4.544 +				if (string.IsNullOrEmpty(tipText))
   4.545 +					throw new ArgumentException("tipText");
   4.546 +
   4.547 +				if (DesignMode)
   4.548 +					return;
   4.549 +
   4.550 +				if (created)
   4.551 +				{
   4.552 +					NativeMethods.NotifyIconData data = new NativeMethods.NotifyIconData();
   4.553 +					if (window.Handle == IntPtr.Zero)
   4.554 +						window.CreateHandle(new CreateParams());
   4.555 +
   4.556 +					data.Window = window.Handle;
   4.557 +					data.ID = id;
   4.558 +					data.Flags = NativeMethods.NotifyIconDataFlags.Info;
   4.559 +					data.TimeoutOrVersion = timeout;
   4.560 +					data.InfoTitle = tipTitle;
   4.561 +					data.Info = tipText;
   4.562 +					data.InfoFlags = (int)tipIcon;
   4.563 +
   4.564 +					NativeMethods.Shell_NotifyIcon(
   4.565 +					  NativeMethods.NotifyIconMessage.Modify, data);
   4.566 +				}
   4.567 +			}
   4.568 +
   4.569 +			private void ShowContextMenu()
   4.570 +			{
   4.571 +				if (ContextMenu == null && ContextMenuStrip == null)
   4.572 +					return;
   4.573 +
   4.574 +				NativeMethods.Point p = new NativeMethods.Point();
   4.575 +				NativeMethods.GetCursorPos(ref p);
   4.576 +				NativeMethods.SetForegroundWindow(
   4.577 +				  new HandleRef(window, window.Handle));
   4.578 +
   4.579 +				if (ContextMenu != null)
   4.580 +				{
   4.581 +					ContextMenu.GetType().InvokeMember("OnPopup",
   4.582 +					  BindingFlags.NonPublic | BindingFlags.InvokeMethod |
   4.583 +					  BindingFlags.Instance, null, ContextMenu,
   4.584 +					  new Object[] { System.EventArgs.Empty });
   4.585 +
   4.586 +					NativeMethods.TrackPopupMenuEx(
   4.587 +					  new HandleRef(ContextMenu, ContextMenu.Handle), 72,
   4.588 +					  p.x, p.y, new HandleRef(window, window.Handle),
   4.589 +					  IntPtr.Zero);
   4.590 +
   4.591 +					NativeMethods.PostMessage(
   4.592 +					  new HandleRef(window, window.Handle), WM_NULL, 0, 0);
   4.593 +					return;
   4.594 +				}
   4.595 +
   4.596 +				if (ContextMenuStrip != null)
   4.597 +					ContextMenuStrip.GetType().InvokeMember("ShowInTaskbar",
   4.598 +					  BindingFlags.NonPublic | BindingFlags.InvokeMethod |
   4.599 +					  BindingFlags.Instance, null, ContextMenuStrip,
   4.600 +					  new Object[] { p.x, p.y });
   4.601 +			}
   4.602 +
   4.603 +			private void UpdateNotifyIcon(bool showNotifyIcon)
   4.604 +			{
   4.605 +				if (DesignMode)
   4.606 +					return;
   4.607 +
   4.608 +				lock (syncObj)
   4.609 +				{
   4.610 +					window.LockReference(showNotifyIcon);
   4.611 +
   4.612 +					NativeMethods.NotifyIconData data = new NativeMethods.NotifyIconData();
   4.613 +					data.CallbackMessage = WM_TRAYMOUSEMESSAGE;
   4.614 +					data.Flags = NativeMethods.NotifyIconDataFlags.Message;
   4.615 +
   4.616 +					if (showNotifyIcon && window.Handle == IntPtr.Zero)
   4.617 +						window.CreateHandle(new CreateParams());
   4.618 +
   4.619 +					data.Window = window.Handle;
   4.620 +					data.ID = id;
   4.621 +
   4.622 +					if (icon != null)
   4.623 +					{
   4.624 +						data.Flags |= NativeMethods.NotifyIconDataFlags.Icon;
   4.625 +						data.Icon = icon.Handle;
   4.626 +					}
   4.627 +
   4.628 +					data.Flags |= NativeMethods.NotifyIconDataFlags.Tip;
   4.629 +					data.Tip = text;
   4.630 +
   4.631 +					if (showNotifyIcon && icon != null)
   4.632 +					{
   4.633 +						if (!created)
   4.634 +						{
   4.635 +							int i = 0;
   4.636 +							do
   4.637 +							{
   4.638 +								created = NativeMethods.Shell_NotifyIcon(
   4.639 +								  NativeMethods.NotifyIconMessage.Add, data);
   4.640 +								if (!created)
   4.641 +								{
   4.642 +									System.Threading.Thread.Sleep(200);
   4.643 +									i++;
   4.644 +								}
   4.645 +							} while (!created && i < 40);
   4.646 +						}
   4.647 +						else
   4.648 +						{
   4.649 +							NativeMethods.Shell_NotifyIcon(
   4.650 +							  NativeMethods.NotifyIconMessage.Modify, data);
   4.651 +						}
   4.652 +					}
   4.653 +					else
   4.654 +					{
   4.655 +						if (created)
   4.656 +						{
   4.657 +							int i = 0;
   4.658 +							bool deleted = false;
   4.659 +							do
   4.660 +							{
   4.661 +								deleted = NativeMethods.Shell_NotifyIcon(
   4.662 +								  NativeMethods.NotifyIconMessage.Delete, data);
   4.663 +								if (!deleted)
   4.664 +								{
   4.665 +									System.Threading.Thread.Sleep(200);
   4.666 +									i++;
   4.667 +								}
   4.668 +							} while (!deleted && i < 40);
   4.669 +							created = false;
   4.670 +						}
   4.671 +					}
   4.672 +				}
   4.673 +			}
   4.674 +
   4.675 +			private void ProcessMouseDown(ref Message message, MouseButtons button,
   4.676 +			  bool doubleClick)
   4.677 +			{
   4.678 +				if (doubleClick)
   4.679 +				{
   4.680 +					if (DoubleClick != null)
   4.681 +						DoubleClick(this, new MouseEventArgs(button, 2, 0, 0, 0));
   4.682 +
   4.683 +					if (MouseDoubleClick != null)
   4.684 +						MouseDoubleClick(this, new MouseEventArgs(button, 2, 0, 0, 0));
   4.685 +
   4.686 +					doubleClickDown = true;
   4.687 +				}
   4.688 +
   4.689 +				if (MouseDown != null)
   4.690 +					MouseDown(this,
   4.691 +					  new MouseEventArgs(button, doubleClick ? 2 : 1, 0, 0, 0));
   4.692 +			}
   4.693 +
   4.694 +			private void ProcessMouseUp(ref Message message, MouseButtons button)
   4.695 +			{
   4.696 +				if (MouseUp != null)
   4.697 +					MouseUp(this, new MouseEventArgs(button, 0, 0, 0, 0));
   4.698 +
   4.699 +				if (!doubleClickDown)
   4.700 +				{
   4.701 +					if (Click != null)
   4.702 +						Click(this, new MouseEventArgs(button, 0, 0, 0, 0));
   4.703 +
   4.704 +					if (MouseClick != null)
   4.705 +						MouseClick(this, new MouseEventArgs(button, 0, 0, 0, 0));
   4.706 +				}
   4.707 +				doubleClickDown = false;
   4.708 +			}
   4.709 +
   4.710 +			private void ProcessInitMenuPopup(ref Message message)
   4.711 +			{
   4.712 +				if (ContextMenu != null &&
   4.713 +				  (bool)ContextMenu.GetType().InvokeMember("ProcessInitMenuPopup",
   4.714 +					BindingFlags.NonPublic | BindingFlags.InvokeMethod |
   4.715 +					BindingFlags.Instance, null, ContextMenu,
   4.716 +					new Object[] { message.WParam }))
   4.717 +				{
   4.718 +					return;
   4.719 +				}
   4.720 +				window.DefWndProc(ref message);
   4.721 +			}
   4.722 +
   4.723 +			private void WndProc(ref Message message)
   4.724 +			{
   4.725 +				switch (message.Msg)
   4.726 +				{
   4.727 +					case WM_DESTROY:
   4.728 +						UpdateNotifyIcon(false);
   4.729 +						return;
   4.730 +
   4.731 +					case WM_COMMAND:
   4.732 +						if (message.LParam != IntPtr.Zero)
   4.733 +						{
   4.734 +							window.DefWndProc(ref message);
   4.735 +							return;
   4.736 +						}
   4.737 +						commandDispatch.Invoke(null, new object[] {
   4.738 +            message.WParam.ToInt32() & 0xFFFF });
   4.739 +						return;
   4.740 +
   4.741 +					case WM_INITMENUPOPUP:
   4.742 +						ProcessInitMenuPopup(ref message);
   4.743 +						return;
   4.744 +
   4.745 +					case WM_TRAYMOUSEMESSAGE:
   4.746 +						switch ((int)message.LParam)
   4.747 +						{
   4.748 +							case WM_MOUSEMOVE:
   4.749 +								if (MouseMove != null)
   4.750 +									MouseMove(this,
   4.751 +									  new MouseEventArgs(Control.MouseButtons, 0, 0, 0, 0));
   4.752 +								return;
   4.753 +
   4.754 +							case WM_LBUTTONDOWN:
   4.755 +								ProcessMouseDown(ref message, MouseButtons.Left, false);
   4.756 +								return;
   4.757 +
   4.758 +							case WM_LBUTTONUP:
   4.759 +								ProcessMouseUp(ref message, MouseButtons.Left);
   4.760 +								return;
   4.761 +
   4.762 +							case WM_LBUTTONDBLCLK:
   4.763 +								ProcessMouseDown(ref message, MouseButtons.Left, true);
   4.764 +								return;
   4.765 +
   4.766 +							case WM_RBUTTONDOWN:
   4.767 +								ProcessMouseDown(ref message, MouseButtons.Right, false);
   4.768 +								return;
   4.769 +
   4.770 +							case WM_RBUTTONUP:
   4.771 +								if (ContextMenu != null || ContextMenuStrip != null)
   4.772 +									ShowContextMenu();
   4.773 +								ProcessMouseUp(ref message, MouseButtons.Right);
   4.774 +								return;
   4.775 +
   4.776 +							case WM_RBUTTONDBLCLK:
   4.777 +								ProcessMouseDown(ref message, MouseButtons.Right, true);
   4.778 +								return;
   4.779 +
   4.780 +							case WM_MBUTTONDOWN:
   4.781 +								ProcessMouseDown(ref message, MouseButtons.Middle, false);
   4.782 +								return;
   4.783 +
   4.784 +							case WM_MBUTTONUP:
   4.785 +								ProcessMouseUp(ref message, MouseButtons.Middle);
   4.786 +								return;
   4.787 +
   4.788 +							case WM_MBUTTONDBLCLK:
   4.789 +								ProcessMouseDown(ref message, MouseButtons.Middle, true);
   4.790 +								return;
   4.791 +
   4.792 +							case NIN_BALLOONSHOW:
   4.793 +								if (BalloonTipShown != null)
   4.794 +									BalloonTipShown(this, EventArgs.Empty);
   4.795 +								return;
   4.796 +
   4.797 +							case NIN_BALLOONHIDE:
   4.798 +							case NIN_BALLOONTIMEOUT:
   4.799 +								if (BalloonTipClosed != null)
   4.800 +									BalloonTipClosed(this, EventArgs.Empty);
   4.801 +								return;
   4.802 +
   4.803 +							case NIN_BALLOONUSERCLICK:
   4.804 +								if (BalloonTipClicked != null)
   4.805 +									BalloonTipClicked(this, EventArgs.Empty);
   4.806 +								return;
   4.807 +
   4.808 +							default:
   4.809 +								return;
   4.810 +						}
   4.811 +				}
   4.812 +
   4.813 +				if (message.Msg == NotifyIconWindowsImplementation.WM_TASKBARCREATED)
   4.814 +				{
   4.815 +					lock (syncObj)
   4.816 +					{
   4.817 +						created = false;
   4.818 +					}
   4.819 +					UpdateNotifyIcon(visible);
   4.820 +				}
   4.821 +
   4.822 +				window.DefWndProc(ref message);
   4.823 +			}
   4.824 +
   4.825 +			private class NotifyIconNativeWindow : NativeWindow
   4.826 +			{
   4.827 +				private NotifyIconWindowsImplementation reference;
   4.828 +				private GCHandle referenceHandle;
   4.829 +
   4.830 +				internal NotifyIconNativeWindow(NotifyIconWindowsImplementation component)
   4.831 +				{
   4.832 +					this.reference = component;
   4.833 +				}
   4.834 +
   4.835 +				~NotifyIconNativeWindow()
   4.836 +				{
   4.837 +					if (base.Handle != IntPtr.Zero)
   4.838 +						NativeMethods.PostMessage(
   4.839 +						  new HandleRef(this, base.Handle), WM_CLOSE, 0, 0);
   4.840 +				}
   4.841 +
   4.842 +				public void LockReference(bool locked)
   4.843 +				{
   4.844 +					if (locked)
   4.845 +					{
   4.846 +						if (!referenceHandle.IsAllocated)
   4.847 +						{
   4.848 +							referenceHandle = GCHandle.Alloc(reference, GCHandleType.Normal);
   4.849 +							return;
   4.850 +						}
   4.851 +					}
   4.852 +					else
   4.853 +					{
   4.854 +						if (referenceHandle.IsAllocated)
   4.855 +							referenceHandle.Free();
   4.856 +					}
   4.857 +				}
   4.858 +
   4.859 +				protected override void OnThreadException(Exception e)
   4.860 +				{
   4.861 +					Application.OnThreadException(e);
   4.862 +				}
   4.863 +
   4.864 +				protected override void WndProc(ref Message m)
   4.865 +				{
   4.866 +					reference.WndProc(ref m);
   4.867 +				}
   4.868 +			}
   4.869 +
   4.870 +			private const int WM_NULL = 0x00;
   4.871 +			private const int WM_DESTROY = 0x02;
   4.872 +			private const int WM_CLOSE = 0x10;
   4.873 +			private const int WM_COMMAND = 0x111;
   4.874 +			private const int WM_INITMENUPOPUP = 0x117;
   4.875 +			private const int WM_MOUSEMOVE = 0x200;
   4.876 +			private const int WM_LBUTTONDOWN = 0x201;
   4.877 +			private const int WM_LBUTTONUP = 0x202;
   4.878 +			private const int WM_LBUTTONDBLCLK = 0x203;
   4.879 +			private const int WM_RBUTTONDOWN = 0x204;
   4.880 +			private const int WM_RBUTTONUP = 0x205;
   4.881 +			private const int WM_RBUTTONDBLCLK = 0x206;
   4.882 +			private const int WM_MBUTTONDOWN = 0x207;
   4.883 +			private const int WM_MBUTTONUP = 0x208;
   4.884 +			private const int WM_MBUTTONDBLCLK = 0x209;
   4.885 +			private const int WM_TRAYMOUSEMESSAGE = 0x800;
   4.886 +
   4.887 +			private const int NIN_BALLOONSHOW = 0x402;
   4.888 +			private const int NIN_BALLOONHIDE = 0x403;
   4.889 +			private const int NIN_BALLOONTIMEOUT = 0x404;
   4.890 +			private const int NIN_BALLOONUSERCLICK = 0x405;
   4.891 +
   4.892 +			private static int WM_TASKBARCREATED =
   4.893 +			  NativeMethods.RegisterWindowMessage("TaskbarCreated");
   4.894 +
   4.895 +			private static class NativeMethods
   4.896 +			{
   4.897 +				[DllImport("user32.dll", CharSet = CharSet.Auto)]
   4.898 +				public static extern IntPtr PostMessage(HandleRef hwnd, int msg,
   4.899 +				  int wparam, int lparam);
   4.900 +
   4.901 +				[DllImport("user32.dll", CharSet = CharSet.Auto)]
   4.902 +				public static extern int RegisterWindowMessage(string msg);
   4.903 +
   4.904 +				[Flags]
   4.905 +				public enum NotifyIconDataFlags : int
   4.906 +				{
   4.907 +					Message = 0x1,
   4.908 +					Icon = 0x2,
   4.909 +					Tip = 0x4,
   4.910 +					State = 0x8,
   4.911 +					Info = 0x10
   4.912 +				}
   4.913 +
   4.914 +				[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
   4.915 +				public class NotifyIconData
   4.916 +				{
   4.917 +					private int Size = Marshal.SizeOf(typeof(NotifyIconData));
   4.918 +					public IntPtr Window;
   4.919 +					public int ID;
   4.920 +					public NotifyIconDataFlags Flags;
   4.921 +					public int CallbackMessage;
   4.922 +					public IntPtr Icon;
   4.923 +
   4.924 +					[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
   4.925 +					public string Tip;
   4.926 +
   4.927 +					public int State;
   4.928 +					public int StateMask;
   4.929 +
   4.930 +					[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
   4.931 +					public string Info;
   4.932 +
   4.933 +					public int TimeoutOrVersion;
   4.934 +
   4.935 +					[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
   4.936 +					public string InfoTitle;
   4.937 +
   4.938 +					public int InfoFlags;
   4.939 +				}
   4.940 +
   4.941 +				public enum NotifyIconMessage : int
   4.942 +				{
   4.943 +					Add = 0x0,
   4.944 +					Modify = 0x1,
   4.945 +					Delete = 0x2
   4.946 +				}
   4.947 +
   4.948 +				[DllImport("shell32.dll", CharSet = CharSet.Auto)]
   4.949 +				[return: MarshalAs(UnmanagedType.Bool)]
   4.950 +				public static extern bool Shell_NotifyIcon(NotifyIconMessage message,
   4.951 +				  NotifyIconData pnid);
   4.952 +
   4.953 +				[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
   4.954 +				public static extern bool TrackPopupMenuEx(HandleRef hmenu, int fuFlags,
   4.955 +				  int x, int y, HandleRef hwnd, IntPtr tpm);
   4.956 +
   4.957 +				[StructLayout(LayoutKind.Sequential)]
   4.958 +				public struct Point
   4.959 +				{
   4.960 +					public int x;
   4.961 +					public int y;
   4.962 +				}
   4.963 +
   4.964 +				[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
   4.965 +				public static extern bool GetCursorPos(ref Point point);
   4.966 +
   4.967 +				[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
   4.968 +				public static extern bool SetForegroundWindow(HandleRef hWnd);
   4.969 +			}
   4.970 +		}
   4.971 +	}
   4.972 +}
   4.973 \ No newline at end of file
     5.1 --- a/Server/Properties/Resources.resx	Sun Jan 18 14:18:28 2015 +0100
     5.2 +++ b/Server/Properties/Resources.resx	Sun Jan 18 18:11:32 2015 +0100
     5.3 @@ -46,7 +46,7 @@
     5.4      
     5.5      mimetype: application/x-microsoft.net.object.binary.base64
     5.6      value   : The object must be serialized with 
     5.7 -            : System.Serialization.Formatters.Binary.BinaryFormatter
     5.8 +            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
     5.9              : and then encoded with base64 encoding.
    5.10      
    5.11      mimetype: application/x-microsoft.net.object.soap.base64
    5.12 @@ -60,6 +60,7 @@
    5.13              : and then encoded with base64 encoding.
    5.14      -->
    5.15    <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    5.16 +    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    5.17      <xsd:element name="root" msdata:IsDataSet="true">
    5.18        <xsd:complexType>
    5.19          <xsd:choice maxOccurs="unbounded">
    5.20 @@ -68,9 +69,10 @@
    5.21                <xsd:sequence>
    5.22                  <xsd:element name="value" type="xsd:string" minOccurs="0" />
    5.23                </xsd:sequence>
    5.24 -              <xsd:attribute name="name" type="xsd:string" />
    5.25 +              <xsd:attribute name="name" use="required" type="xsd:string" />
    5.26                <xsd:attribute name="type" type="xsd:string" />
    5.27                <xsd:attribute name="mimetype" type="xsd:string" />
    5.28 +              <xsd:attribute ref="xml:space" />
    5.29              </xsd:complexType>
    5.30            </xsd:element>
    5.31            <xsd:element name="assembly">
    5.32 @@ -85,9 +87,10 @@
    5.33                  <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
    5.34                  <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
    5.35                </xsd:sequence>
    5.36 -              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
    5.37 +              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
    5.38                <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
    5.39                <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
    5.40 +              <xsd:attribute ref="xml:space" />
    5.41              </xsd:complexType>
    5.42            </xsd:element>
    5.43            <xsd:element name="resheader">
    5.44 @@ -109,9 +112,10 @@
    5.45      <value>2.0</value>
    5.46    </resheader>
    5.47    <resheader name="reader">
    5.48 -    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
    5.49 +    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
    5.50    </resheader>
    5.51    <resheader name="writer">
    5.52 -    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
    5.53 +    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
    5.54    </resheader>
    5.55 +  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    5.56  </root>
    5.57 \ No newline at end of file
     6.1 --- a/Server/Properties/Settings.Designer.cs	Sun Jan 18 14:18:28 2015 +0100
     6.2 +++ b/Server/Properties/Settings.Designer.cs	Sun Jan 18 18:11:32 2015 +0100
     6.3 @@ -1,7 +1,7 @@
     6.4  //------------------------------------------------------------------------------
     6.5  // <auto-generated>
     6.6  //     This code was generated by a tool.
     6.7 -//     Runtime Version:4.0.30319.34014
     6.8 +//     Runtime Version:4.0.30319.18444
     6.9  //
    6.10  //     Changes to this file may cause incorrect behavior and will be lost if
    6.11  //     the code is regenerated.
    6.12 @@ -69,5 +69,29 @@
    6.13                  this["CycleClients"] = value;
    6.14              }
    6.15          }
    6.16 +        
    6.17 +        [global::System.Configuration.UserScopedSettingAttribute()]
    6.18 +        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    6.19 +        [global::System.Configuration.DefaultSettingValueAttribute("False")]
    6.20 +        public bool MinimizeToTray {
    6.21 +            get {
    6.22 +                return ((bool)(this["MinimizeToTray"]));
    6.23 +            }
    6.24 +            set {
    6.25 +                this["MinimizeToTray"] = value;
    6.26 +            }
    6.27 +        }
    6.28 +        
    6.29 +        [global::System.Configuration.UserScopedSettingAttribute()]
    6.30 +        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    6.31 +        [global::System.Configuration.DefaultSettingValueAttribute("False")]
    6.32 +        public bool StartMinimized {
    6.33 +            get {
    6.34 +                return ((bool)(this["StartMinimized"]));
    6.35 +            }
    6.36 +            set {
    6.37 +                this["StartMinimized"] = value;
    6.38 +            }
    6.39 +        }
    6.40      }
    6.41  }
     7.1 --- a/Server/Properties/Settings.settings	Sun Jan 18 14:18:28 2015 +0100
     7.2 +++ b/Server/Properties/Settings.settings	Sun Jan 18 18:11:32 2015 +0100
     7.3 @@ -14,5 +14,11 @@
     7.4      <Setting Name="CycleClients" Type="System.Boolean" Scope="User">
     7.5        <Value Profile="(Default)">False</Value>
     7.6      </Setting>
     7.7 +    <Setting Name="MinimizeToTray" Type="System.Boolean" Scope="User">
     7.8 +      <Value Profile="(Default)">False</Value>
     7.9 +    </Setting>
    7.10 +    <Setting Name="StartMinimized" Type="System.Boolean" Scope="User">
    7.11 +      <Value Profile="(Default)">False</Value>
    7.12 +    </Setting>
    7.13    </Settings>
    7.14  </SettingsFile>
    7.15 \ No newline at end of file
     8.1 Binary file Server/Resources/vfd.ico has changed
     9.1 --- a/Server/SharpDisplayManager.csproj	Sun Jan 18 14:18:28 2015 +0100
     9.2 +++ b/Server/SharpDisplayManager.csproj	Sun Jan 18 18:11:32 2015 +0100
     9.3 @@ -92,7 +92,7 @@
     9.4      <GenerateManifests>true</GenerateManifests>
     9.5    </PropertyGroup>
     9.6    <PropertyGroup>
     9.7 -    <ApplicationIcon>vfd.ico</ApplicationIcon>
     9.8 +    <ApplicationIcon>Resources\vfd.ico</ApplicationIcon>
     9.9    </PropertyGroup>
    9.10    <PropertyGroup>
    9.11      <StartupObject>SharpDisplayManager.Program</StartupObject>
    9.12 @@ -134,6 +134,7 @@
    9.13        <DependentUpon>MainForm.cs</DependentUpon>
    9.14      </Compile>
    9.15      <Compile Include="MarqueeLabel.cs" />
    9.16 +    <Compile Include="NotifyIconAdv.cs" />
    9.17      <Compile Include="Program.cs" />
    9.18      <Compile Include="ProgressForm.cs">
    9.19        <SubType>Form</SubType>
    9.20 @@ -214,7 +215,7 @@
    9.21    </ItemGroup>
    9.22    <ItemGroup>
    9.23      <Content Include="MiniDisplay.dll" />
    9.24 -    <Content Include="vfd.ico" />
    9.25 +    <EmbeddedResource Include="Resources\vfd.ico" />
    9.26    </ItemGroup>
    9.27    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    9.28    <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
    10.1 Binary file Server/vfd.ico has changed