From 2fba44a56f35f0ee69772554dd4431d977175038 Mon Sep 17 00:00:00 2001 From: Jay Otterbein Date: Tue, 12 Sep 2017 13:19:49 -0500 Subject: [PATCH 1/3] Fixed issue where tray icon showed even after exiting the application --- percentage/percentage/TrayIcon.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/percentage/percentage/TrayIcon.cs b/percentage/percentage/TrayIcon.cs index f23d772..adedd8d 100644 --- a/percentage/percentage/TrayIcon.cs +++ b/percentage/percentage/TrayIcon.cs @@ -55,6 +55,8 @@ private void timer_Tick(object sender, EventArgs e) private void menuItem_Click(object sender, EventArgs e) { + notifyIcon.Visible = false; + notifyIcon.Dispose(); Application.Exit(); } From b1d2cb48f9b674248b36a8bc2cd7671d095b6573 Mon Sep 17 00:00:00 2001 From: Jay Otterbein Date: Tue, 12 Sep 2017 13:20:30 -0500 Subject: [PATCH 2/3] Added using statements to force dispose even if an error happened, and added a dispose for the image returned from DrawText that wasn't happening on timer --- percentage/percentage/TrayIcon.cs | 67 ++++++++++++++----------------- 1 file changed, 30 insertions(+), 37 deletions(-) diff --git a/percentage/percentage/TrayIcon.cs b/percentage/percentage/TrayIcon.cs index adedd8d..03f082e 100644 --- a/percentage/percentage/TrayIcon.cs +++ b/percentage/percentage/TrayIcon.cs @@ -44,13 +44,14 @@ private void timer_Tick(object sender, EventArgs e) PowerStatus powerStatus = SystemInformation.PowerStatus; batteryPercentage = (powerStatus.BatteryLifePercent * 100).ToString(); - Bitmap bitmap = new Bitmap(DrawText(batteryPercentage, new Font(iconFont, iconFontSize), Color.White, Color.Black)); - - System.IntPtr intPtr = bitmap.GetHicon(); - Icon icon = Icon.FromHandle(intPtr); - - notifyIcon.Icon = icon; - notifyIcon.Text = batteryPercentage + "%"; + using (Bitmap bitmap = new Bitmap(DrawText(batteryPercentage, new Font(iconFont, iconFontSize), Color.White, Color.Black))) + { + System.IntPtr intPtr = bitmap.GetHicon(); + Icon icon = Icon.FromHandle(intPtr); + + notifyIcon.Icon = icon; + notifyIcon.Text = batteryPercentage + "%"; + } } private void menuItem_Click(object sender, EventArgs e) @@ -62,38 +63,30 @@ private void menuItem_Click(object sender, EventArgs e) private Image DrawText(String text, Font font, Color textColor, Color backColor) { - // create a dummy bitmap to get a graphics object - Image image = new Bitmap(1, 1); - Graphics graphics = Graphics.FromImage(image); - - // measure the string to see how big the image needs to be - SizeF textSize = graphics.MeasureString(text, font); - - // free up the dummy image and old graphics object - image.Dispose(); - graphics.Dispose(); - - // create a new image of the right size - image = new Bitmap((int) textSize.Width, (int) textSize.Height); - - graphics = Graphics.FromImage(image); - - // paint the background - graphics.Clear(backColor); - - // create a brush for the text - Brush textBrush = new SolidBrush(textColor); - - graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; - - graphics.DrawString(text, font, textBrush, 0, 0); - - graphics.Save(); - - textBrush.Dispose(); - graphics.Dispose(); + var textSize = GetImageSize(text, font); + Image image = new Bitmap((int) textSize.Width, (int) textSize.Height); + using (Graphics graphics = Graphics.FromImage(image)) + { + // paint the background + graphics.Clear(backColor); + + // create a brush for the text + using (Brush textBrush = new SolidBrush(textColor)) + { + graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; + graphics.DrawString(text, font, textBrush, 0, 0); + graphics.Save(); + } + } return image; } + + private static SizeF GetImageSize(string text, Font font) + { + using (Image image = new Bitmap(1, 1)) + using (Graphics graphics = Graphics.FromImage(image)) + return graphics.MeasureString(text, font); + } } } From 8d066f02e1745279270231b1c3a25fcf5fb05d18 Mon Sep 17 00:00:00 2001 From: Jay Otterbein Date: Tue, 12 Sep 2017 13:27:17 -0500 Subject: [PATCH 3/3] Added dispose and custom DestroyIcon call for the items created in the timer_Tick method following the documentation on MSDN: https://msdn.microsoft.com/en-us/library/system.drawing.bitmap.gethicon(v=vs.110).aspx --- percentage/percentage/TrayIcon.cs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/percentage/percentage/TrayIcon.cs b/percentage/percentage/TrayIcon.cs index 03f082e..d3643c6 100644 --- a/percentage/percentage/TrayIcon.cs +++ b/percentage/percentage/TrayIcon.cs @@ -1,11 +1,15 @@ using System; using System.Drawing; +using System.Runtime.InteropServices; using System.Windows.Forms; namespace percentage { class TrayIcon { + [DllImport("user32.dll", CharSet = CharSet.Auto)] + static extern bool DestroyIcon(IntPtr handle); + private const string iconFont = "Segoe UI"; private const int iconFontSize = 14; @@ -47,10 +51,18 @@ private void timer_Tick(object sender, EventArgs e) using (Bitmap bitmap = new Bitmap(DrawText(batteryPercentage, new Font(iconFont, iconFontSize), Color.White, Color.Black))) { System.IntPtr intPtr = bitmap.GetHicon(); - Icon icon = Icon.FromHandle(intPtr); - - notifyIcon.Icon = icon; - notifyIcon.Text = batteryPercentage + "%"; + try + { + using (Icon icon = Icon.FromHandle(intPtr)) + { + notifyIcon.Icon = icon; + notifyIcon.Text = batteryPercentage + "%"; + } + } + finally + { + DestroyIcon(intPtr); + } } }