From d21162318eb64041a8a73b3438bb23b582d4cd39 Mon Sep 17 00:00:00 2001 From: Syrone Wong Date: Fri, 23 Dec 2016 21:41:11 +0800 Subject: [PATCH] Workaround NotifyIcon's 63 chars limit(#965) Signed-off-by: Syrone Wong --- shadowsocks-csharp/Util/ViewUtils.cs | 14 ++++++++++++++ shadowsocks-csharp/View/MenuViewController.cs | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/shadowsocks-csharp/Util/ViewUtils.cs b/shadowsocks-csharp/Util/ViewUtils.cs index c9c45b0f..7131d40d 100644 --- a/shadowsocks-csharp/Util/ViewUtils.cs +++ b/shadowsocks-csharp/Util/ViewUtils.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Windows.Forms; namespace Shadowsocks.Util @@ -17,5 +18,18 @@ namespace Shadowsocks.Util var children = control.Controls.OfType().ToList(); return children.SelectMany(GetChildControls).Concat(children); } + + // Workaround NotifyIcon's 63 chars limit + // https://stackoverflow.com/questions/579665/how-can-i-show-a-systray-tooltip-longer-than-63-chars + public static void SetNotifyIconText(NotifyIcon ni, string text) + { + if (text.Length >= 128) + throw new ArgumentOutOfRangeException("Text limited to 127 characters"); + Type t = typeof(NotifyIcon); + BindingFlags hidden = BindingFlags.NonPublic | BindingFlags.Instance; + t.GetField("text", hidden).SetValue(ni, text); + if ((bool)t.GetField("added", hidden).GetValue(ni)) + t.GetMethod("UpdateIcon", hidden).Invoke(ni, new object[] { true }); + } } } diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index d715ab2b..869278de 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -180,13 +180,13 @@ namespace Shadowsocks.View { serverInfo = config.GetCurrentServer().FriendlyName(); } - // we want to show more details but notify icon title is limited to 63 characters + // show more info by hacking the P/Invoke declaration for NOTIFYICONDATA inside Windows Forms string text = I18N.GetString("Shadowsocks") + " " + UpdateChecker.Version + "\n" + (enabled ? I18N.GetString("System Proxy On: ") + (global ? I18N.GetString("Global") : I18N.GetString("PAC")) : String.Format(I18N.GetString("Running: Port {0}"), config.localPort)) // this feedback is very important because they need to know Shadowsocks is running + "\n" + serverInfo; - _notifyIcon.Text = text.Substring(0, Math.Min(63, text.Length)); + ViewUtils.SetNotifyIconText(_notifyIcon, text); } private Bitmap getTrayIconByState(Bitmap originIcon, bool enabled, bool global)