using System.Drawing.Imaging; using System.Reflection; using System.Runtime.InteropServices; namespace WirelessTextSyncer.Windows.Tray; internal static class TrayIconFactory { private const string ConnectedResourceName = "WirelessTextSyncer.TrayConnected.png"; private const string WaitResourceName = "WirelessTextSyncer.TrayWait.png"; public static Icon CreateConnectedIcon() { return CreateIconFromResource(ConnectedResourceName); } public static Icon CreateWaitIcon() { return CreateIconFromResource(WaitResourceName); } private static Icon CreateIconFromResource(string resourceName) { var assembly = Assembly.GetExecutingAssembly(); using var stream = assembly.GetManifestResourceStream(resourceName) ?? throw new InvalidOperationException($"Tray icon resource not found: {resourceName}"); using var source = new Bitmap(stream); using var bitmap = new Bitmap(source.Width, source.Height, PixelFormat.Format32bppArgb); using (var graphics = Graphics.FromImage(bitmap)) { graphics.Clear(Color.Transparent); graphics.DrawImage(source, 0, 0, source.Width, source.Height); } var handle = bitmap.GetHicon(); try { using var icon = Icon.FromHandle(handle); return (Icon)icon.Clone(); } finally { DestroyIcon(handle); } } [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool DestroyIcon(IntPtr handle); }