Adding the ability to have a tray icon

This commit is contained in:
Den Delimarsky 2021-05-05 07:52:08 -07:00
parent 077f3b79c1
commit 3f5f83ae1c
No known key found for this signature in database
GPG key ID: E1BE1355085F0BCF
3 changed files with 56 additions and 10 deletions

View file

@ -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);
/// <summary>
/// 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;
}
}
}
}

View file

@ -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.
}
}
}

View file

@ -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();
}