# HG changeset patch
# User sl
# Date 1421601092 -3600
# Node ID fe939a729030c3b0dfd2da85c1edfa159cbb65ae
# Parent f0015e909f41183cdbe3ffc5059638ed8b32dadb
Adding tray icon support and minimize to tray option.
diff -r f0015e909f41 -r fe939a729030 Server/App.config
--- a/Server/App.config Sun Jan 18 14:18:28 2015 +0100
+++ b/Server/App.config Sun Jan 18 18:11:32 2015 +0100
@@ -19,6 +19,12 @@
False
+
+ False
+
+
+ False
+
diff -r f0015e909f41 -r fe939a729030 Server/MainForm.Designer.cs
--- a/Server/MainForm.Designer.cs Sun Jan 18 14:18:28 2015 +0100
+++ b/Server/MainForm.Designer.cs Sun Jan 18 18:11:32 2015 +0100
@@ -77,6 +77,8 @@
this.buttonRemoveRow = new System.Windows.Forms.Button();
this.buttonAddRow = new System.Windows.Forms.Button();
this.tabPageApp = new System.Windows.Forms.TabPage();
+ this.checkBoxStartMinimized = new System.Windows.Forms.CheckBox();
+ this.checkBoxMinimizeToTray = new System.Windows.Forms.CheckBox();
this.checkBoxAutoStart = new System.Windows.Forms.CheckBox();
this.buttonUpdate = new System.Windows.Forms.Button();
this.labelFontWidth = new System.Windows.Forms.Label();
@@ -614,6 +616,8 @@
//
// tabPageApp
//
+ this.tabPageApp.Controls.Add(this.checkBoxStartMinimized);
+ this.tabPageApp.Controls.Add(this.checkBoxMinimizeToTray);
this.tabPageApp.Controls.Add(this.checkBoxAutoStart);
this.tabPageApp.Controls.Add(this.buttonUpdate);
this.tabPageApp.Location = new System.Drawing.Point(4, 22);
@@ -624,15 +628,39 @@
this.tabPageApp.Text = "Application";
this.tabPageApp.UseVisualStyleBackColor = true;
//
+ // checkBoxStartMinimized
+ //
+ this.checkBoxStartMinimized.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.checkBoxStartMinimized.AutoSize = true;
+ this.checkBoxStartMinimized.Location = new System.Drawing.Point(8, 144);
+ this.checkBoxStartMinimized.Name = "checkBoxStartMinimized";
+ this.checkBoxStartMinimized.Size = new System.Drawing.Size(96, 17);
+ this.checkBoxStartMinimized.TabIndex = 16;
+ this.checkBoxStartMinimized.Text = "Start minimized";
+ this.checkBoxStartMinimized.UseVisualStyleBackColor = true;
+ this.checkBoxStartMinimized.CheckedChanged += new System.EventHandler(this.checkBoxStartMinimized_CheckedChanged);
+ //
+ // checkBoxMinimizeToTray
+ //
+ this.checkBoxMinimizeToTray.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.checkBoxMinimizeToTray.AutoSize = true;
+ this.checkBoxMinimizeToTray.Location = new System.Drawing.Point(8, 167);
+ this.checkBoxMinimizeToTray.Name = "checkBoxMinimizeToTray";
+ this.checkBoxMinimizeToTray.Size = new System.Drawing.Size(133, 17);
+ this.checkBoxMinimizeToTray.TabIndex = 15;
+ this.checkBoxMinimizeToTray.Text = "Minimize to system tray";
+ this.checkBoxMinimizeToTray.UseVisualStyleBackColor = true;
+ this.checkBoxMinimizeToTray.CheckedChanged += new System.EventHandler(this.checkBoxMinimizeToTray_CheckedChanged);
+ //
// checkBoxAutoStart
//
this.checkBoxAutoStart.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.checkBoxAutoStart.AutoSize = true;
this.checkBoxAutoStart.Location = new System.Drawing.Point(8, 190);
this.checkBoxAutoStart.Name = "checkBoxAutoStart";
- this.checkBoxAutoStart.Size = new System.Drawing.Size(73, 17);
+ this.checkBoxAutoStart.Size = new System.Drawing.Size(143, 17);
this.checkBoxAutoStart.TabIndex = 14;
- this.checkBoxAutoStart.Text = "Auto Start";
+ this.checkBoxAutoStart.Text = "Run on Windows startup";
this.checkBoxAutoStart.UseVisualStyleBackColor = true;
this.checkBoxAutoStart.CheckedChanged += new System.EventHandler(this.checkBoxAutoStart_CheckedChanged);
//
@@ -690,6 +718,7 @@
this.Text = "Sharp Display Manager";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
this.Load += new System.EventHandler(this.MainForm_Load);
+ this.SizeChanged += new System.EventHandler(this.MainForm_SizeChanged);
this.Resize += new System.EventHandler(this.MainForm_Resize);
this.panelDisplay.ResumeLayout(false);
this.tableLayoutPanel.ResumeLayout(false);
@@ -765,6 +794,8 @@
private System.Windows.Forms.TabPage tabPageApp;
private System.Windows.Forms.Button buttonUpdate;
private System.Windows.Forms.CheckBox checkBoxAutoStart;
+ private System.Windows.Forms.CheckBox checkBoxStartMinimized;
+ private System.Windows.Forms.CheckBox checkBoxMinimizeToTray;
}
}
diff -r f0015e909f41 -r fe939a729030 Server/MainForm.cs
--- a/Server/MainForm.cs Sun Jan 18 14:18:28 2015 +0100
+++ b/Server/MainForm.cs Sun Jan 18 18:11:32 2015 +0100
@@ -14,6 +14,7 @@
using System.Threading;
using System.Diagnostics;
using System.Deployment.Application;
+using System.Reflection;
//
using SharpDisplayClient;
using SharpDisplay;
@@ -57,9 +58,16 @@
//Function pointer for pixel Y coordinate intercept
CoordinateTranslationDelegate iScreenY;
- //
+ ///
+ /// Manage run when Windows startup option
+ ///
private StartupManager iStartupManager;
+ ///
+ /// System tray icon.
+ ///
+ private NotifyIconAdv iNotifyIcon;
+
public MainForm()
{
iCurrentClientSessionId = "";
@@ -68,14 +76,26 @@
iDisplay = new Display();
iClients = new Dictionary();
iStartupManager = new StartupManager();
+ iNotifyIcon = new NotifyIconAdv();
InitializeComponent();
UpdateStatus();
//We have a bug when drawing minimized and reusing our bitmap
iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
iCreateBitmap = false;
+
+ if (Properties.Settings.Default.StartMinimized)
+ {
+ WindowState = FormWindowState.Minimized;
+ }
+
}
+ ///
+ ///
+ ///
+ ///
+ ///
private void MainForm_Load(object sender, EventArgs e)
{
if (ApplicationDeployment.IsNetworkDeployed)
@@ -94,10 +114,53 @@
OpenDisplayConnection();
}
- //
+ //Check if "run on Windows startup" is enabled
checkBoxAutoStart.Checked=iStartupManager.Startup;
+
+
+ //Setup notification icon
+ iNotifyIcon.Icon = GetIcon("vfd.ico");
+ iNotifyIcon.Text = "Sharp Display Manager";
+ iNotifyIcon.Visible = true;
+ iNotifyIcon.DoubleClick += delegate(object obj, EventArgs args)
+ {
+ SysTrayHideShow();
+ };
+
+ // To make sure start up with minimize to tray works
+ if (WindowState == FormWindowState.Minimized && Properties.Settings.Default.MinimizeToTray)
+ {
+ Visible = false;
+ }
}
+ ///
+ /// Access icons from embedded resources.
+ ///
+ ///
+ ///
+ public static Icon GetIcon(string name)
+ {
+ name = "SharpDisplayManager.Resources." + name;
+
+ string[] names =
+ Assembly.GetExecutingAssembly().GetManifestResourceNames();
+ for (int i = 0; i < names.Length; i++)
+ {
+ if (names[i].Replace('\\', '.') == name)
+ {
+ using (Stream stream = Assembly.GetExecutingAssembly().
+ GetManifestResourceStream(names[i]))
+ {
+ return new Icon(stream);
+ }
+ }
+ }
+
+ return null;
+ }
+
+
///
/// Set our current client.
/// This will take care of applying our client layout and set data fields.
@@ -520,6 +583,8 @@
CheckFontHeight();
checkBoxConnectOnStartup.Checked = Properties.Settings.Default.DisplayConnectOnStartup;
+ checkBoxMinimizeToTray.Checked = Properties.Settings.Default.MinimizeToTray;
+ checkBoxStartMinimized.Checked = Properties.Settings.Default.StartMinimized;
checkBoxReverseScreen.Checked = cds.ReverseScreen;
checkBoxInverseColors.Checked = cds.InverseColors;
comboBoxDisplayType.SelectedIndex = cds.DisplayType;
@@ -602,6 +667,27 @@
Properties.Settings.Default.Save();
}
+ private void checkBoxMinimizeToTray_CheckedChanged(object sender, EventArgs e)
+ {
+ //Save our "Minimize to tray" setting
+ Properties.Settings.Default.MinimizeToTray = checkBoxMinimizeToTray.Checked;
+ Properties.Settings.Default.Save();
+
+ }
+
+ private void checkBoxStartMinimized_CheckedChanged(object sender, EventArgs e)
+ {
+ //Save our "Start minimized" setting
+ Properties.Settings.Default.StartMinimized = checkBoxStartMinimized.Checked;
+ Properties.Settings.Default.Save();
+ }
+
+ private void checkBoxAutoStart_CheckedChanged(object sender, EventArgs e)
+ {
+ iStartupManager.Startup = checkBoxAutoStart.Checked;
+ }
+
+
private void checkBoxReverseScreen_CheckedChanged(object sender, EventArgs e)
{
//Save our reverse screen setting
@@ -1413,10 +1499,37 @@
}
}
- private void checkBoxAutoStart_CheckedChanged(object sender, EventArgs e)
+
+ ///
+ /// Used to
+ ///
+ private void SysTrayHideShow()
{
- iStartupManager.Startup = checkBoxAutoStart.Checked;
+ Visible = !Visible;
+ if (Visible)
+ {
+ Activate();
+ WindowState = FormWindowState.Normal;
+ }
}
+
+ ///
+ /// Use to handle minimize events.
+ ///
+ ///
+ ///
+ private void MainForm_SizeChanged(object sender, EventArgs e)
+ {
+ if (WindowState == FormWindowState.Minimized && Properties.Settings.Default.MinimizeToTray)
+ {
+ if (Visible)
+ {
+ SysTrayHideShow();
+ }
+ }
+
+ }
+
}
///
diff -r f0015e909f41 -r fe939a729030 Server/NotifyIconAdv.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Server/NotifyIconAdv.cs Sun Jan 18 18:11:32 2015 +0100
@@ -0,0 +1,969 @@
+/*
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+ Copyright (C) 2012 Michael Möller
+
+*/
+
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Windows.Forms;
+
+namespace SharpDisplayManager
+{
+ public class NotifyIconAdv : IDisposable
+ {
+ private NotifyIcon genericNotifyIcon;
+ private NotifyIconWindowsImplementation windowsNotifyIcon;
+
+ public NotifyIconAdv()
+ {
+ int p = (int)Environment.OSVersion.Platform;
+ if ((p == 4) || (p == 128))
+ { // Unix
+ genericNotifyIcon = new NotifyIcon();
+ }
+ else
+ { // Windows
+ windowsNotifyIcon = new NotifyIconWindowsImplementation();
+ }
+ }
+
+ public event EventHandler BalloonTipClicked
+ {
+ add
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.BalloonTipClicked += value;
+ else
+ windowsNotifyIcon.BalloonTipClicked += value;
+ }
+ remove
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.BalloonTipClicked -= value;
+ else
+ windowsNotifyIcon.BalloonTipClicked -= value;
+ }
+ }
+
+ public event EventHandler BalloonTipClosed
+ {
+ add
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.BalloonTipClosed += value;
+ else
+ windowsNotifyIcon.BalloonTipClosed += value;
+ }
+ remove
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.BalloonTipClosed -= value;
+ else
+ windowsNotifyIcon.BalloonTipClosed -= value;
+ }
+ }
+
+ public event EventHandler BalloonTipShown
+ {
+ add
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.BalloonTipShown += value;
+ else
+ windowsNotifyIcon.BalloonTipShown += value;
+ }
+ remove
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.BalloonTipShown -= value;
+ else
+ windowsNotifyIcon.BalloonTipShown -= value;
+ }
+ }
+
+ public event EventHandler Click
+ {
+ add
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.Click += value;
+ else
+ windowsNotifyIcon.Click += value;
+ }
+ remove
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.Click -= value;
+ else
+ windowsNotifyIcon.Click -= value;
+ }
+ }
+
+ public event EventHandler DoubleClick
+ {
+ add
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.DoubleClick += value;
+ else
+ windowsNotifyIcon.DoubleClick += value;
+ }
+ remove
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.DoubleClick -= value;
+ else
+ windowsNotifyIcon.DoubleClick -= value;
+ }
+ }
+
+ public event MouseEventHandler MouseClick
+ {
+ add
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.MouseClick += value;
+ else
+ windowsNotifyIcon.MouseClick += value;
+ }
+ remove
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.MouseClick -= value;
+ else
+ windowsNotifyIcon.MouseClick -= value;
+ }
+ }
+
+ public event MouseEventHandler MouseDoubleClick
+ {
+ add
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.MouseDoubleClick += value;
+ else
+ windowsNotifyIcon.MouseDoubleClick += value;
+ }
+ remove
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.MouseDoubleClick -= value;
+ else
+ windowsNotifyIcon.MouseDoubleClick -= value;
+ }
+ }
+
+ public event MouseEventHandler MouseDown
+ {
+ add
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.MouseDown += value;
+ else
+ windowsNotifyIcon.MouseDown += value;
+ }
+ remove
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.MouseDown -= value;
+ else
+ windowsNotifyIcon.MouseDown -= value;
+ }
+ }
+
+ public event MouseEventHandler MouseMove
+ {
+ add
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.MouseMove += value;
+ else
+ windowsNotifyIcon.MouseMove += value;
+ }
+ remove
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.MouseMove -= value;
+ else
+ windowsNotifyIcon.MouseMove -= value;
+ }
+ }
+
+ public event MouseEventHandler MouseUp
+ {
+ add
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.MouseUp += value;
+ else
+ windowsNotifyIcon.MouseUp += value;
+ }
+ remove
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.MouseUp -= value;
+ else
+ windowsNotifyIcon.MouseUp -= value;
+ }
+ }
+
+ public string BalloonTipText
+ {
+ get
+ {
+ if (genericNotifyIcon != null)
+ return genericNotifyIcon.BalloonTipText;
+ else
+ return windowsNotifyIcon.BalloonTipText;
+ }
+ set
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.BalloonTipText = value;
+ else
+ windowsNotifyIcon.BalloonTipText = value;
+ }
+ }
+
+ public ToolTipIcon BalloonTipIcon
+ {
+ get
+ {
+ if (genericNotifyIcon != null)
+ return genericNotifyIcon.BalloonTipIcon;
+ else
+ return windowsNotifyIcon.BalloonTipIcon;
+ }
+ set
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.BalloonTipIcon = value;
+ else
+ windowsNotifyIcon.BalloonTipIcon = value;
+ }
+ }
+
+ public string BalloonTipTitle
+ {
+ get
+ {
+ if (genericNotifyIcon != null)
+ return genericNotifyIcon.BalloonTipTitle;
+ else
+ return windowsNotifyIcon.BalloonTipTitle;
+ }
+ set
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.BalloonTipTitle = value;
+ else
+ windowsNotifyIcon.BalloonTipTitle = value;
+ }
+ }
+
+ public ContextMenu ContextMenu
+ {
+ get
+ {
+ if (genericNotifyIcon != null)
+ return genericNotifyIcon.ContextMenu;
+ else
+ return windowsNotifyIcon.ContextMenu;
+ }
+ set
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.ContextMenu = value;
+ else
+ windowsNotifyIcon.ContextMenu = value;
+ }
+ }
+
+ public ContextMenuStrip ContextMenuStrip
+ {
+ get
+ {
+ if (genericNotifyIcon != null)
+ return genericNotifyIcon.ContextMenuStrip;
+ else
+ return windowsNotifyIcon.ContextMenuStrip;
+ }
+ set
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.ContextMenuStrip = value;
+ else
+ windowsNotifyIcon.ContextMenuStrip = value;
+ }
+ }
+
+ public object Tag { get; set; }
+
+ public Icon Icon
+ {
+ get
+ {
+ if (genericNotifyIcon != null)
+ return genericNotifyIcon.Icon;
+ else
+ return windowsNotifyIcon.Icon;
+ }
+ set
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.Icon = value;
+ else
+ windowsNotifyIcon.Icon = value;
+ }
+ }
+
+ public string Text
+ {
+ get
+ {
+ if (genericNotifyIcon != null)
+ return genericNotifyIcon.Text;
+ else
+ return windowsNotifyIcon.Text;
+ }
+ set
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.Text = value;
+ else
+ windowsNotifyIcon.Text = value;
+ }
+ }
+
+ public bool Visible
+ {
+ get
+ {
+ if (genericNotifyIcon != null)
+ return genericNotifyIcon.Visible;
+ else
+ return windowsNotifyIcon.Visible;
+ }
+ set
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.Visible = value;
+ else
+ windowsNotifyIcon.Visible = value;
+ }
+ }
+
+ public void Dispose()
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.Dispose();
+ else
+ windowsNotifyIcon.Dispose();
+ }
+
+ public void ShowBalloonTip(int timeout)
+ {
+ ShowBalloonTip(timeout, BalloonTipTitle, BalloonTipText, BalloonTipIcon);
+ }
+
+ public void ShowBalloonTip(int timeout, string tipTitle, string tipText,
+ ToolTipIcon tipIcon)
+ {
+ if (genericNotifyIcon != null)
+ genericNotifyIcon.ShowBalloonTip(timeout, tipTitle, tipText, tipIcon);
+ else
+ windowsNotifyIcon.ShowBalloonTip(timeout, tipTitle, tipText, tipIcon);
+ }
+
+ private class NotifyIconWindowsImplementation : Component
+ {
+ private static int nextId = 0;
+
+ private object syncObj = new object();
+ private Icon icon;
+ private string text = "";
+ private int id;
+ private bool created;
+ private NotifyIconNativeWindow window;
+ private bool doubleClickDown;
+ private bool visible;
+ private MethodInfo commandDispatch;
+
+ public event EventHandler BalloonTipClicked;
+
+ public event EventHandler BalloonTipClosed;
+
+ public event EventHandler BalloonTipShown;
+
+ public event EventHandler Click;
+
+ public event EventHandler DoubleClick;
+
+ public event MouseEventHandler MouseClick;
+
+ public event MouseEventHandler MouseDoubleClick;
+
+ public event MouseEventHandler MouseDown;
+
+ public event MouseEventHandler MouseMove;
+
+ public event MouseEventHandler MouseUp;
+
+ public string BalloonTipText { get; set; }
+
+ public ToolTipIcon BalloonTipIcon { get; set; }
+
+ public string BalloonTipTitle { get; set; }
+
+ public ContextMenu ContextMenu { get; set; }
+
+ public ContextMenuStrip ContextMenuStrip { get; set; }
+
+ public object Tag { get; set; }
+
+ public Icon Icon
+ {
+ get
+ {
+ return icon;
+ }
+ set
+ {
+ if (icon != value)
+ {
+ icon = value;
+ UpdateNotifyIcon(visible);
+ }
+ }
+ }
+
+ public string Text
+ {
+ get
+ {
+ return text;
+ }
+ set
+ {
+ if (value == null)
+ value = "";
+
+ if (value.Length > 63)
+ throw new ArgumentOutOfRangeException();
+
+ if (!value.Equals(text))
+ {
+ text = value;
+
+ if (visible)
+ UpdateNotifyIcon(visible);
+ }
+ }
+ }
+
+ public bool Visible
+ {
+ get
+ {
+ return visible;
+ }
+ set
+ {
+ if (visible != value)
+ {
+ visible = value;
+ UpdateNotifyIcon(visible);
+ }
+ }
+ }
+
+ public NotifyIconWindowsImplementation()
+ {
+ BalloonTipText = "";
+ BalloonTipTitle = "";
+
+ commandDispatch = typeof(Form).Assembly.
+ GetType("System.Windows.Forms.Command").GetMethod("DispatchID",
+ BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public,
+ null, new Type[] { typeof(int) }, null);
+
+ id = ++NotifyIconWindowsImplementation.nextId;
+ window = new NotifyIconNativeWindow(this);
+ UpdateNotifyIcon(visible);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (window != null)
+ {
+ icon = null;
+ text = "";
+ UpdateNotifyIcon(false);
+ window.DestroyHandle();
+ window = null;
+ ContextMenu = null;
+ ContextMenuStrip = null;
+ }
+ }
+ else
+ {
+ if (window != null && window.Handle != IntPtr.Zero)
+ {
+ NativeMethods.PostMessage(
+ new HandleRef(window, window.Handle), WM_CLOSE, 0, 0);
+ window.ReleaseHandle();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ public void ShowBalloonTip(int timeout)
+ {
+ ShowBalloonTip(timeout, BalloonTipTitle, BalloonTipText, BalloonTipIcon);
+ }
+
+ public void ShowBalloonTip(int timeout, string tipTitle, string tipText,
+ ToolTipIcon tipIcon)
+ {
+ if (timeout < 0)
+ throw new ArgumentOutOfRangeException("timeout");
+
+ if (string.IsNullOrEmpty(tipText))
+ throw new ArgumentException("tipText");
+
+ if (DesignMode)
+ return;
+
+ if (created)
+ {
+ NativeMethods.NotifyIconData data = new NativeMethods.NotifyIconData();
+ if (window.Handle == IntPtr.Zero)
+ window.CreateHandle(new CreateParams());
+
+ data.Window = window.Handle;
+ data.ID = id;
+ data.Flags = NativeMethods.NotifyIconDataFlags.Info;
+ data.TimeoutOrVersion = timeout;
+ data.InfoTitle = tipTitle;
+ data.Info = tipText;
+ data.InfoFlags = (int)tipIcon;
+
+ NativeMethods.Shell_NotifyIcon(
+ NativeMethods.NotifyIconMessage.Modify, data);
+ }
+ }
+
+ private void ShowContextMenu()
+ {
+ if (ContextMenu == null && ContextMenuStrip == null)
+ return;
+
+ NativeMethods.Point p = new NativeMethods.Point();
+ NativeMethods.GetCursorPos(ref p);
+ NativeMethods.SetForegroundWindow(
+ new HandleRef(window, window.Handle));
+
+ if (ContextMenu != null)
+ {
+ ContextMenu.GetType().InvokeMember("OnPopup",
+ BindingFlags.NonPublic | BindingFlags.InvokeMethod |
+ BindingFlags.Instance, null, ContextMenu,
+ new Object[] { System.EventArgs.Empty });
+
+ NativeMethods.TrackPopupMenuEx(
+ new HandleRef(ContextMenu, ContextMenu.Handle), 72,
+ p.x, p.y, new HandleRef(window, window.Handle),
+ IntPtr.Zero);
+
+ NativeMethods.PostMessage(
+ new HandleRef(window, window.Handle), WM_NULL, 0, 0);
+ return;
+ }
+
+ if (ContextMenuStrip != null)
+ ContextMenuStrip.GetType().InvokeMember("ShowInTaskbar",
+ BindingFlags.NonPublic | BindingFlags.InvokeMethod |
+ BindingFlags.Instance, null, ContextMenuStrip,
+ new Object[] { p.x, p.y });
+ }
+
+ private void UpdateNotifyIcon(bool showNotifyIcon)
+ {
+ if (DesignMode)
+ return;
+
+ lock (syncObj)
+ {
+ window.LockReference(showNotifyIcon);
+
+ NativeMethods.NotifyIconData data = new NativeMethods.NotifyIconData();
+ data.CallbackMessage = WM_TRAYMOUSEMESSAGE;
+ data.Flags = NativeMethods.NotifyIconDataFlags.Message;
+
+ if (showNotifyIcon && window.Handle == IntPtr.Zero)
+ window.CreateHandle(new CreateParams());
+
+ data.Window = window.Handle;
+ data.ID = id;
+
+ if (icon != null)
+ {
+ data.Flags |= NativeMethods.NotifyIconDataFlags.Icon;
+ data.Icon = icon.Handle;
+ }
+
+ data.Flags |= NativeMethods.NotifyIconDataFlags.Tip;
+ data.Tip = text;
+
+ if (showNotifyIcon && icon != null)
+ {
+ if (!created)
+ {
+ int i = 0;
+ do
+ {
+ created = NativeMethods.Shell_NotifyIcon(
+ NativeMethods.NotifyIconMessage.Add, data);
+ if (!created)
+ {
+ System.Threading.Thread.Sleep(200);
+ i++;
+ }
+ } while (!created && i < 40);
+ }
+ else
+ {
+ NativeMethods.Shell_NotifyIcon(
+ NativeMethods.NotifyIconMessage.Modify, data);
+ }
+ }
+ else
+ {
+ if (created)
+ {
+ int i = 0;
+ bool deleted = false;
+ do
+ {
+ deleted = NativeMethods.Shell_NotifyIcon(
+ NativeMethods.NotifyIconMessage.Delete, data);
+ if (!deleted)
+ {
+ System.Threading.Thread.Sleep(200);
+ i++;
+ }
+ } while (!deleted && i < 40);
+ created = false;
+ }
+ }
+ }
+ }
+
+ private void ProcessMouseDown(ref Message message, MouseButtons button,
+ bool doubleClick)
+ {
+ if (doubleClick)
+ {
+ if (DoubleClick != null)
+ DoubleClick(this, new MouseEventArgs(button, 2, 0, 0, 0));
+
+ if (MouseDoubleClick != null)
+ MouseDoubleClick(this, new MouseEventArgs(button, 2, 0, 0, 0));
+
+ doubleClickDown = true;
+ }
+
+ if (MouseDown != null)
+ MouseDown(this,
+ new MouseEventArgs(button, doubleClick ? 2 : 1, 0, 0, 0));
+ }
+
+ private void ProcessMouseUp(ref Message message, MouseButtons button)
+ {
+ if (MouseUp != null)
+ MouseUp(this, new MouseEventArgs(button, 0, 0, 0, 0));
+
+ if (!doubleClickDown)
+ {
+ if (Click != null)
+ Click(this, new MouseEventArgs(button, 0, 0, 0, 0));
+
+ if (MouseClick != null)
+ MouseClick(this, new MouseEventArgs(button, 0, 0, 0, 0));
+ }
+ doubleClickDown = false;
+ }
+
+ private void ProcessInitMenuPopup(ref Message message)
+ {
+ if (ContextMenu != null &&
+ (bool)ContextMenu.GetType().InvokeMember("ProcessInitMenuPopup",
+ BindingFlags.NonPublic | BindingFlags.InvokeMethod |
+ BindingFlags.Instance, null, ContextMenu,
+ new Object[] { message.WParam }))
+ {
+ return;
+ }
+ window.DefWndProc(ref message);
+ }
+
+ private void WndProc(ref Message message)
+ {
+ switch (message.Msg)
+ {
+ case WM_DESTROY:
+ UpdateNotifyIcon(false);
+ return;
+
+ case WM_COMMAND:
+ if (message.LParam != IntPtr.Zero)
+ {
+ window.DefWndProc(ref message);
+ return;
+ }
+ commandDispatch.Invoke(null, new object[] {
+ message.WParam.ToInt32() & 0xFFFF });
+ return;
+
+ case WM_INITMENUPOPUP:
+ ProcessInitMenuPopup(ref message);
+ return;
+
+ case WM_TRAYMOUSEMESSAGE:
+ switch ((int)message.LParam)
+ {
+ case WM_MOUSEMOVE:
+ if (MouseMove != null)
+ MouseMove(this,
+ new MouseEventArgs(Control.MouseButtons, 0, 0, 0, 0));
+ return;
+
+ case WM_LBUTTONDOWN:
+ ProcessMouseDown(ref message, MouseButtons.Left, false);
+ return;
+
+ case WM_LBUTTONUP:
+ ProcessMouseUp(ref message, MouseButtons.Left);
+ return;
+
+ case WM_LBUTTONDBLCLK:
+ ProcessMouseDown(ref message, MouseButtons.Left, true);
+ return;
+
+ case WM_RBUTTONDOWN:
+ ProcessMouseDown(ref message, MouseButtons.Right, false);
+ return;
+
+ case WM_RBUTTONUP:
+ if (ContextMenu != null || ContextMenuStrip != null)
+ ShowContextMenu();
+ ProcessMouseUp(ref message, MouseButtons.Right);
+ return;
+
+ case WM_RBUTTONDBLCLK:
+ ProcessMouseDown(ref message, MouseButtons.Right, true);
+ return;
+
+ case WM_MBUTTONDOWN:
+ ProcessMouseDown(ref message, MouseButtons.Middle, false);
+ return;
+
+ case WM_MBUTTONUP:
+ ProcessMouseUp(ref message, MouseButtons.Middle);
+ return;
+
+ case WM_MBUTTONDBLCLK:
+ ProcessMouseDown(ref message, MouseButtons.Middle, true);
+ return;
+
+ case NIN_BALLOONSHOW:
+ if (BalloonTipShown != null)
+ BalloonTipShown(this, EventArgs.Empty);
+ return;
+
+ case NIN_BALLOONHIDE:
+ case NIN_BALLOONTIMEOUT:
+ if (BalloonTipClosed != null)
+ BalloonTipClosed(this, EventArgs.Empty);
+ return;
+
+ case NIN_BALLOONUSERCLICK:
+ if (BalloonTipClicked != null)
+ BalloonTipClicked(this, EventArgs.Empty);
+ return;
+
+ default:
+ return;
+ }
+ }
+
+ if (message.Msg == NotifyIconWindowsImplementation.WM_TASKBARCREATED)
+ {
+ lock (syncObj)
+ {
+ created = false;
+ }
+ UpdateNotifyIcon(visible);
+ }
+
+ window.DefWndProc(ref message);
+ }
+
+ private class NotifyIconNativeWindow : NativeWindow
+ {
+ private NotifyIconWindowsImplementation reference;
+ private GCHandle referenceHandle;
+
+ internal NotifyIconNativeWindow(NotifyIconWindowsImplementation component)
+ {
+ this.reference = component;
+ }
+
+ ~NotifyIconNativeWindow()
+ {
+ if (base.Handle != IntPtr.Zero)
+ NativeMethods.PostMessage(
+ new HandleRef(this, base.Handle), WM_CLOSE, 0, 0);
+ }
+
+ public void LockReference(bool locked)
+ {
+ if (locked)
+ {
+ if (!referenceHandle.IsAllocated)
+ {
+ referenceHandle = GCHandle.Alloc(reference, GCHandleType.Normal);
+ return;
+ }
+ }
+ else
+ {
+ if (referenceHandle.IsAllocated)
+ referenceHandle.Free();
+ }
+ }
+
+ protected override void OnThreadException(Exception e)
+ {
+ Application.OnThreadException(e);
+ }
+
+ protected override void WndProc(ref Message m)
+ {
+ reference.WndProc(ref m);
+ }
+ }
+
+ private const int WM_NULL = 0x00;
+ private const int WM_DESTROY = 0x02;
+ private const int WM_CLOSE = 0x10;
+ private const int WM_COMMAND = 0x111;
+ private const int WM_INITMENUPOPUP = 0x117;
+ private const int WM_MOUSEMOVE = 0x200;
+ private const int WM_LBUTTONDOWN = 0x201;
+ private const int WM_LBUTTONUP = 0x202;
+ private const int WM_LBUTTONDBLCLK = 0x203;
+ private const int WM_RBUTTONDOWN = 0x204;
+ private const int WM_RBUTTONUP = 0x205;
+ private const int WM_RBUTTONDBLCLK = 0x206;
+ private const int WM_MBUTTONDOWN = 0x207;
+ private const int WM_MBUTTONUP = 0x208;
+ private const int WM_MBUTTONDBLCLK = 0x209;
+ private const int WM_TRAYMOUSEMESSAGE = 0x800;
+
+ private const int NIN_BALLOONSHOW = 0x402;
+ private const int NIN_BALLOONHIDE = 0x403;
+ private const int NIN_BALLOONTIMEOUT = 0x404;
+ private const int NIN_BALLOONUSERCLICK = 0x405;
+
+ private static int WM_TASKBARCREATED =
+ NativeMethods.RegisterWindowMessage("TaskbarCreated");
+
+ private static class NativeMethods
+ {
+ [DllImport("user32.dll", CharSet = CharSet.Auto)]
+ public static extern IntPtr PostMessage(HandleRef hwnd, int msg,
+ int wparam, int lparam);
+
+ [DllImport("user32.dll", CharSet = CharSet.Auto)]
+ public static extern int RegisterWindowMessage(string msg);
+
+ [Flags]
+ public enum NotifyIconDataFlags : int
+ {
+ Message = 0x1,
+ Icon = 0x2,
+ Tip = 0x4,
+ State = 0x8,
+ Info = 0x10
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ public class NotifyIconData
+ {
+ private int Size = Marshal.SizeOf(typeof(NotifyIconData));
+ public IntPtr Window;
+ public int ID;
+ public NotifyIconDataFlags Flags;
+ public int CallbackMessage;
+ public IntPtr Icon;
+
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
+ public string Tip;
+
+ public int State;
+ public int StateMask;
+
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
+ public string Info;
+
+ public int TimeoutOrVersion;
+
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
+ public string InfoTitle;
+
+ public int InfoFlags;
+ }
+
+ public enum NotifyIconMessage : int
+ {
+ Add = 0x0,
+ Modify = 0x1,
+ Delete = 0x2
+ }
+
+ [DllImport("shell32.dll", CharSet = CharSet.Auto)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool Shell_NotifyIcon(NotifyIconMessage message,
+ NotifyIconData pnid);
+
+ [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
+ public static extern bool TrackPopupMenuEx(HandleRef hmenu, int fuFlags,
+ int x, int y, HandleRef hwnd, IntPtr tpm);
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Point
+ {
+ public int x;
+ public int y;
+ }
+
+ [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
+ public static extern bool GetCursorPos(ref Point point);
+
+ [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
+ public static extern bool SetForegroundWindow(HandleRef hWnd);
+ }
+ }
+ }
+}
\ No newline at end of file
diff -r f0015e909f41 -r fe939a729030 Server/Properties/Resources.resx
--- a/Server/Properties/Resources.resx Sun Jan 18 14:18:28 2015 +0100
+++ b/Server/Properties/Resources.resx Sun Jan 18 18:11:32 2015 +0100
@@ -46,7 +46,7 @@
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
- : System.Serialization.Formatters.Binary.BinaryFormatter
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
@@ -60,6 +60,7 @@
: and then encoded with base64 encoding.
-->
+
@@ -68,9 +69,10 @@
-
+
+
@@ -85,9 +87,10 @@
-
+
+
@@ -109,9 +112,10 @@
2.0
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
\ No newline at end of file
diff -r f0015e909f41 -r fe939a729030 Server/Properties/Settings.Designer.cs
--- a/Server/Properties/Settings.Designer.cs Sun Jan 18 14:18:28 2015 +0100
+++ b/Server/Properties/Settings.Designer.cs Sun Jan 18 18:11:32 2015 +0100
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.34014
+// Runtime Version:4.0.30319.18444
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -69,5 +69,29 @@
this["CycleClients"] = value;
}
}
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool MinimizeToTray {
+ get {
+ return ((bool)(this["MinimizeToTray"]));
+ }
+ set {
+ this["MinimizeToTray"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool StartMinimized {
+ get {
+ return ((bool)(this["StartMinimized"]));
+ }
+ set {
+ this["StartMinimized"] = value;
+ }
+ }
}
}
diff -r f0015e909f41 -r fe939a729030 Server/Properties/Settings.settings
--- a/Server/Properties/Settings.settings Sun Jan 18 14:18:28 2015 +0100
+++ b/Server/Properties/Settings.settings Sun Jan 18 18:11:32 2015 +0100
@@ -14,5 +14,11 @@
False
+
+ False
+
+
+ False
+
\ No newline at end of file
diff -r f0015e909f41 -r fe939a729030 Server/Resources/vfd.ico
Binary file Server/Resources/vfd.ico has changed
diff -r f0015e909f41 -r fe939a729030 Server/SharpDisplayManager.csproj
--- a/Server/SharpDisplayManager.csproj Sun Jan 18 14:18:28 2015 +0100
+++ b/Server/SharpDisplayManager.csproj Sun Jan 18 18:11:32 2015 +0100
@@ -92,7 +92,7 @@
true
- vfd.ico
+ Resources\vfd.ico
SharpDisplayManager.Program
@@ -134,6 +134,7 @@
MainForm.cs
+
Form
@@ -214,7 +215,7 @@
-
+