From 3f5f83ae1cd4a2821a787d67b1b7a58e6fd44103 Mon Sep 17 00:00:00 2001 From: Den Delimarsky <1389609+dend@users.noreply.github.com> Date: Wed, 5 May 2021 07:52:08 -0700 Subject: [PATCH] Adding the ability to have a tray icon --- .../espresso/Espresso.Shell/Core/APIHelper.cs | 30 +++++++++++++--- .../Espresso.Shell/Core/TrayHelper.cs | 34 +++++++++++++++---- .../espresso/Espresso.Shell/Program.cs | 2 ++ 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/modules/espresso/Espresso.Shell/Core/APIHelper.cs b/src/modules/espresso/Espresso.Shell/Core/APIHelper.cs index e0c96ad75..befa736a7 100644 --- a/src/modules/espresso/Espresso.Shell/Core/APIHelper.cs +++ b/src/modules/espresso/Espresso.Shell/Core/APIHelper.cs @@ -5,6 +5,7 @@ using Microsoft.Win32; using NLog; using System; +using System.Drawing; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -33,15 +34,18 @@ namespace Espresso.Shell.Core private static Logger log; + // More details about the API used: https://docs.microsoft.com/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags); + + [DllImport("Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] + private static extern int ExtractIconEx(string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons); + static APIHelper() { log = LogManager.GetCurrentClassLogger(); } - // More details about the API used: https://docs.microsoft.com/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate - [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] - static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags); - /// /// Sets the computer awake state using the native Win32 SetThreadExecutionState API. This /// function is just a nice-to-have wrapper that helps avoid tracking the success or failure of @@ -183,5 +187,23 @@ namespace Espresso.Shell.Core return string.Empty; } } + + + public static Icon? Extract(string file, int number, bool largeIcon) + { + IntPtr large; + IntPtr small; + ExtractIconEx(file, number, out large, out small, 1); + try + { + return Icon.FromHandle(largeIcon ? large : small); + } + catch + { + return null; + } + + } + } } diff --git a/src/modules/espresso/Espresso.Shell/Core/TrayHelper.cs b/src/modules/espresso/Espresso.Shell/Core/TrayHelper.cs index 0cd3f4882..73c81e3ec 100644 --- a/src/modules/espresso/Espresso.Shell/Core/TrayHelper.cs +++ b/src/modules/espresso/Espresso.Shell/Core/TrayHelper.cs @@ -5,6 +5,7 @@ using Espresso.Shell.Models; using System; using System.Drawing; +using System.Threading.Tasks; using System.Windows.Forms; namespace Espresso.Shell.Core @@ -23,14 +24,16 @@ namespace Espresso.Shell.Core trayIcon.Icon = icon; trayIcon.ContextMenuStrip = contextMenu; trayIcon.Visible = true; + + Application.Run(); } - internal static void InitializeEspressoTray(EspressoMode mode, bool keepDisplayOn, Action indefiniteSelectionCallback, Action timedSelectionCallback) + internal static void InitializeEspressoTray(string text, EspressoMode mode, bool keepDisplayOn, Action indefiniteSelectionCallback, Action timedSelectionCallback) { var contextMenuStrip = new ContextMenuStrip(); - + // Main toolstrip. - var operationContextMenu = new ToolStrip(); + var operationContextMenu = new ToolStripMenuItem(); operationContextMenu.Text = "Mode"; // Indefinite keep-awake menu item. @@ -40,13 +43,32 @@ namespace Espresso.Shell.Core { indefiniteMenuItem.Checked = true; } - operationContextMenu.Items.Add(indefiniteMenuItem); // Timed keep-awake menu item + var timedMenuItem = new ToolStripMenuItem(); + timedMenuItem.Text = "Timed"; - // Exit menu item + var halfHourMenuItem = new ToolStripMenuItem(); + halfHourMenuItem.Text = "30 minutes"; - // About menu item + var oneHourMenuItem = new ToolStripMenuItem(); + halfHourMenuItem.Text = "1 hour"; + + var twoHousrMenuItem = new ToolStripMenuItem(); + halfHourMenuItem.Text = "2 hours"; + + timedMenuItem.DropDownItems.Add(halfHourMenuItem); + timedMenuItem.DropDownItems.Add(oneHourMenuItem); + timedMenuItem.DropDownItems.Add(twoHousrMenuItem); + + operationContextMenu.DropDownItems.Add(indefiniteMenuItem); + operationContextMenu.DropDownItems.Add(timedMenuItem); + + contextMenuStrip.Items.Add(operationContextMenu); + +#pragma warning disable CS8604 // Possible null reference argument. + Task.Factory.StartNew(() => InitializeTrayIcon(text, APIHelper.Extract("shell32.dll", 42, true), contextMenuStrip)); +#pragma warning restore CS8604 // Possible null reference argument. } } } diff --git a/src/modules/espresso/Espresso.Shell/Program.cs b/src/modules/espresso/Espresso.Shell/Program.cs index 2dbbdce75..acfeb0955 100644 --- a/src/modules/espresso/Espresso.Shell/Program.cs +++ b/src/modules/espresso/Espresso.Shell/Program.cs @@ -199,6 +199,8 @@ namespace Espresso.Shell }); } + TrayHelper.InitializeEspressoTray("Espresso", EspressoMode.INDEFINITE, true, new Action(()=>Console.WriteLine("test")), new Action(() => Console.WriteLine("test"))); + new ManualResetEvent(false).WaitOne(); }