diff --git a/SoundSwitch/Framework/NotificationManager/Notification/NotificationBanner.cs b/SoundSwitch/Framework/NotificationManager/Notification/NotificationBanner.cs index 42b6e5bf7e..4dc160c029 100644 --- a/SoundSwitch/Framework/NotificationManager/Notification/NotificationBanner.cs +++ b/SoundSwitch/Framework/NotificationManager/Notification/NotificationBanner.cs @@ -32,11 +32,13 @@ public class NotificationBanner : INotification public void NotifyDefaultChanged(MMDevice audioDevice) { + var Icon = AudioDeviceIconExtractor.ExtractIconFromAudioDevice(audioDevice, true); var toastData = new BannerData { - Image = AudioDeviceIconExtractor.ExtractIconFromAudioDevice(audioDevice, true).ToBitmap(), + Image = Icon.ToBitmap(), Text = audioDevice.FriendlyName }; + Icon.Dispose(); if (Configuration.CustomSound != null && File.Exists(Configuration.CustomSound.FilePath)) { toastData.SoundFile = Configuration.CustomSound; diff --git a/SoundSwitch/UI/Forms/About.cs b/SoundSwitch/UI/Forms/About.cs index 4b8be8faf4..28c33a5559 100644 --- a/SoundSwitch/UI/Forms/About.cs +++ b/SoundSwitch/UI/Forms/About.cs @@ -22,11 +22,12 @@ namespace SoundSwitch.UI.Forms { public partial class About : Form { + private static readonly System.Drawing.Icon helpIcon = Resources.HelpIcon; public About() { InitializeComponent(); - Icon = Resources.HelpIcon; + Icon = helpIcon; } private void About_Load(object sender, System.EventArgs e) diff --git a/SoundSwitch/UI/Forms/Settings.cs b/SoundSwitch/UI/Forms/Settings.cs index e338a8cdea..5c74dd3c21 100644 --- a/SoundSwitch/UI/Forms/Settings.cs +++ b/SoundSwitch/UI/Forms/Settings.cs @@ -38,13 +38,15 @@ namespace SoundSwitch.UI.Forms { public sealed partial class SettingsForm : Form { + private static readonly Icon settingsIcon = Resources.SettingsIcon; + private readonly bool _loaded; public SettingsForm() { // Form itself InitializeComponent(); - Icon = Resources.SettingsIcon; + Icon = settingsIcon; Text = AssemblyUtils.GetReleaseState() == AssemblyUtils.ReleaseState.Beta ? $"{SettingsStrings.settings} {AssemblyUtils.GetReleaseState()}" : SettingsStrings.settings; @@ -234,6 +236,25 @@ private void closeButton_Click(object sender, EventArgs e) Close(); } + protected override void OnClosed(EventArgs e) + { + base.OnClosed(e); + foreach (var i in playbackListView.SmallImageList.Images) + { + if (i is IDisposable) + { + ((IDisposable)i).Dispose(); + } + } + foreach (var i in recordingListView.SmallImageList.Images) + { + if (i is IDisposable) + { + ((IDisposable)i).Dispose(); + } + } + } + private void tabControl_SelectedIndexChanged(object sender, EventArgs e) { var tabControlSender = (TabControl)sender; diff --git a/SoundSwitch/UI/Forms/UpdateDownloadForm.cs b/SoundSwitch/UI/Forms/UpdateDownloadForm.cs index 580a0e750a..e13a4cfb9f 100644 --- a/SoundSwitch/UI/Forms/UpdateDownloadForm.cs +++ b/SoundSwitch/UI/Forms/UpdateDownloadForm.cs @@ -26,13 +26,15 @@ namespace SoundSwitch.UI.Forms { public sealed partial class UpdateDownloadForm : Form { + private static readonly System.Drawing.Icon updateIcon = Resources.UpdateIcon; + private readonly bool _redirectLinks = false; private readonly WebFile _releaseFile; public UpdateDownloadForm(Release release) { InitializeComponent(); - Icon = Resources.UpdateIcon; + Icon = updateIcon; Text = release.Name; LocalizeForm(); Focus(); diff --git a/SoundSwitch/Util/AudioDeviceIconExtractor.cs b/SoundSwitch/Util/AudioDeviceIconExtractor.cs index d5a83a1509..19bfa51589 100644 --- a/SoundSwitch/Util/AudioDeviceIconExtractor.cs +++ b/SoundSwitch/Util/AudioDeviceIconExtractor.cs @@ -24,51 +24,8 @@ namespace SoundSwitch.Util { internal class AudioDeviceIconExtractor { - private class IconKey : IEquatable - { - private string FilePath { get; } - private bool Large { get; } - - public IconKey(string filePath, bool large) - { - FilePath = filePath; - Large = large; - } - - public override int GetHashCode() - { - unchecked - { - return (FilePath.GetHashCode()*397) ^ Large.GetHashCode(); - } - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((IconKey) obj); - } - - public static bool operator ==(IconKey left, IconKey right) - { - return Equals(left, right); - } - - public static bool operator !=(IconKey left, IconKey right) - { - return !Equals(left, right); - } - - public bool Equals(IconKey other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return string.Equals(FilePath, other.FilePath) && Large == other.Large; - } - } - private static readonly Dictionary IconCache = new Dictionary(); + private static readonly Icon defaultSpeakers = Resources.defaultSpeakers; + private static readonly Icon defaultMicrophone = Resources.defaultMicrophone; /// /// Extract the Icon out of an AudioDevice @@ -78,24 +35,18 @@ public bool Equals(IconKey other) /// public static Icon ExtractIconFromAudioDevice(MMDevice audioDevice, bool largeIcon) { - Icon ico; - var iconKey = new IconKey(audioDevice.IconPath, largeIcon); - if (IconCache.TryGetValue(iconKey, out ico)) - { - return ico; - } try { if (audioDevice.IconPath.EndsWith(".ico")) { - ico = Icon.ExtractAssociatedIcon(audioDevice.IconPath); + return Icon.ExtractAssociatedIcon(audioDevice.IconPath); } else { var iconInfo = audioDevice.IconPath.Split(','); var dllPath = iconInfo[0]; var iconIndex = int.Parse(iconInfo[1]); - ico = IconExtractor.Extract(dllPath, iconIndex, largeIcon); + return IconExtractor.Extract(dllPath, iconIndex, largeIcon); } } catch (Exception e) @@ -104,18 +55,13 @@ public static Icon ExtractIconFromAudioDevice(MMDevice audioDevice, bool largeIc switch (audioDevice.DataFlow) { case DataFlow.Capture: - ico = Resources.defaultSpeakers; - break; + return defaultSpeakers; case DataFlow.Render: - ico = Resources.defaultMicrophone; - break; + return defaultMicrophone; default: throw new ArgumentOutOfRangeException(); } } - - IconCache.Add(iconKey, ico); - return ico; } } } \ No newline at end of file diff --git a/SoundSwitch/Util/ToolStripDeviceItem.cs b/SoundSwitch/Util/ToolStripDeviceItem.cs index 6940ee9e47..c574d8e309 100644 --- a/SoundSwitch/Util/ToolStripDeviceItem.cs +++ b/SoundSwitch/Util/ToolStripDeviceItem.cs @@ -24,6 +24,8 @@ namespace SoundSwitch.Util { internal class ToolStripDeviceItem : ToolStripMenuItem { + private static readonly Bitmap check = Resources.Check; + public ToolStripDeviceItem(EventHandler onClick, MMDevice audioDevice) : base(audioDevice.FriendlyName, null, onClick) { @@ -35,7 +37,7 @@ public override Image Image get { if (AudioDevice !=null && AudioController.IsDefault(AudioDevice.ID, (DeviceType) AudioDevice.DataFlow, DeviceRole.Console)) - return Resources.Check; + return check; return null; } diff --git a/SoundSwitch/Util/TrayIcon.cs b/SoundSwitch/Util/TrayIcon.cs index 6a2d75e0d6..440f2d52da 100644 --- a/SoundSwitch/Util/TrayIcon.cs +++ b/SoundSwitch/Util/TrayIcon.cs @@ -37,6 +37,17 @@ namespace SoundSwitch.Util { public sealed class TrayIcon : IDisposable { + private static readonly Bitmap updateBitmap = Resources.Update; + private static readonly Bitmap settingsSmall = Resources.SettingsSmall; + private static readonly Bitmap soundSwitch16 = Resources.SoundSwitch16; + private static readonly Bitmap playbackDevices = Resources.PlaybackDevices; + private static readonly Bitmap mixer = Resources.Mixer; + private static readonly Bitmap infoHelp = Resources.InfoHelp; + private static readonly Bitmap donate = Resources.donate; + private static readonly Bitmap helpSmall = Resources.HelpSmall; + private static readonly Bitmap exit = Resources.exit; + private static readonly Icon updateIcon = Resources.UpdateIcon; + private readonly ContextMenuStrip _selectionMenu = new ContextMenuStrip(); private readonly ContextMenuStrip _settingsMenu = new ContextMenuStrip(); private readonly SynchronizationContext _context = SynchronizationContext.Current ?? new SynchronizationContext(); @@ -55,7 +66,7 @@ public TrayIcon() { UpdateIcon(); _tooltipInfoManager = new TooltipInfoManager(NotifyIcon); - _updateMenuItem = new ToolStripMenuItem(TrayIconStrings.noUpdate, Resources.Update, OnUpdateClick) + _updateMenuItem = new ToolStripMenuItem(TrayIconStrings.noUpdate, updateBitmap, OnUpdateClick) { Enabled = false }; @@ -63,7 +74,7 @@ public TrayIcon() PopulateSettingsMenu(); - _selectionMenu.Items.Add(TrayIconStrings.noDevicesSelected, Resources.SettingsSmall, (sender, e) => ShowSettings()); + _selectionMenu.Items.Add(TrayIconStrings.noDevicesSelected, settingsSmall, (sender, e) => ShowSettings()); NotifyIcon.MouseDoubleClick += (sender, args) => { @@ -104,15 +115,29 @@ public void Dispose() { _selectionMenu.Dispose(); _settingsMenu.Dispose(); + if (NotifyIcon.Icon != null) + { + NotifyIcon.Icon.Dispose(); + } NotifyIcon.Dispose(); _updateMenuItem.Dispose(); } + private void ReplaceIcon(Icon newIcon) + { + var oldIcon = NotifyIcon.Icon; + NotifyIcon.Icon = newIcon; + if (oldIcon != null) + { + oldIcon.Dispose(); + } + } + public void UpdateIcon() { if (AppConfigs.Configuration.KeepSystrayIcon) { - NotifyIcon.Icon = Icon.FromHandle(Resources.SoundSwitch16.GetHicon()); + ReplaceIcon(Icon.FromHandle(soundSwitch16.GetHicon())); return; } @@ -120,7 +145,7 @@ public void UpdateIcon() { var defaultDevice = AppModel.Instance.ActiveAudioDeviceLister.GetPlaybackDevices() .First(device => AudioController.IsDefault(device.ID, (DeviceType)device.DataFlow, DeviceRole.Console)); - NotifyIcon.Icon = AudioDeviceIconExtractor.ExtractIconFromAudioDevice(defaultDevice, false); + ReplaceIcon(AudioDeviceIconExtractor.ExtractIconFromAudioDevice(defaultDevice, false)); } catch (InvalidOperationException) { @@ -134,17 +159,17 @@ private void PopulateSettingsMenu() var readmeHtml = Path.Combine(applicationDirectory, "Readme.html"); _settingsMenu.Items.Add( Application.ProductName + ' ' + AssemblyUtils.GetReleaseState() + " (" + Application.ProductVersion + - ")", Resources.SoundSwitch16); + ")", soundSwitch16); _settingsMenu.Items.Add("-"); - _settingsMenu.Items.Add(TrayIconStrings.playbackDevices, Resources.PlaybackDevices, + _settingsMenu.Items.Add(TrayIconStrings.playbackDevices, playbackDevices, (sender, e) => { Process.Start(new ProcessStartInfo("control", "mmsys.cpl sounds")); }); - _settingsMenu.Items.Add(TrayIconStrings.mixer, Resources.Mixer, + _settingsMenu.Items.Add(TrayIconStrings.mixer, mixer, (sender, e) => { Process.Start(new ProcessStartInfo("sndvol.exe")); }); _settingsMenu.Items.Add("-"); _settingsMenu.Items.Add(_updateMenuItem); - _settingsMenu.Items.Add(TrayIconStrings.settings, Resources.SettingsSmall, (sender, e) => ShowSettings()); + _settingsMenu.Items.Add(TrayIconStrings.settings, settingsSmall, (sender, e) => ShowSettings()); _settingsMenu.Items.Add("-"); - _settingsMenu.Items.Add(TrayIconStrings.help, Resources.InfoHelp, (sender, e) => + _settingsMenu.Items.Add(TrayIconStrings.help, infoHelp, (sender, e) => { if (!File.Exists(readmeHtml)) { @@ -153,10 +178,10 @@ private void PopulateSettingsMenu() } Process.Start(readmeHtml); }); - _settingsMenu.Items.Add(TrayIconStrings.donate, Resources.donate, (sender, e) => Process.Start("https://soundswitch.aaflalo.me/?utm_source=application")); - _settingsMenu.Items.Add(TrayIconStrings.about, Resources.HelpSmall, (sender, e) => new About().Show()); + _settingsMenu.Items.Add(TrayIconStrings.donate, donate, (sender, e) => Process.Start("https://soundswitch.aaflalo.me/?utm_source=application")); + _settingsMenu.Items.Add(TrayIconStrings.about, helpSmall, (sender, e) => new About().Show()); _settingsMenu.Items.Add("-"); - _settingsMenu.Items.Add(TrayIconStrings.exit, Resources.exit, (sender, e) => Application.Exit()); + _settingsMenu.Items.Add(TrayIconStrings.exit, exit, (sender, e) => Application.Exit()); } private void OnUpdateClick(object sender, EventArgs eventArgs) @@ -190,7 +215,7 @@ private void SetEventHandlers() { return; } - NotifyIcon.Icon = AudioDeviceIconExtractor.ExtractIconFromAudioDevice(audioChangeEvent.Device, false); + ReplaceIcon(AudioDeviceIconExtractor.ExtractIconFromAudioDevice(audioChangeEvent.Device, false)); }; AppModel.Instance.NewVersionReleased += (sender, @event) => { @@ -224,9 +249,9 @@ private void StartAnimationIconUpdate() var tick = 0; _animationTimer.Tick += (sender, args) => { - NotifyIcon.Icon = tick == 0 - ? Icon.FromHandle(Resources.SoundSwitch16.GetHicon()) - : Resources.UpdateIcon; + ReplaceIcon(tick == 0 + ? Icon.FromHandle(soundSwitch16.GetHicon()) + : (Icon)updateIcon.Clone()); tick = ++tick % 2; }; }