mirror of
https://github.com/Hofknecht/SystemTrayMenu.git
synced 2024-10-03 10:36:30 +13:00
Housekeeping, refine IconReader and fix ShellContextMenu
This commit is contained in:
parent
175c93e511
commit
ab9b0ea0b0
5 changed files with 68 additions and 109 deletions
|
@ -209,7 +209,6 @@ namespace SystemTrayMenu.Business
|
|||
timerShowProcessStartedAsLoadingIcon.Stop();
|
||||
timerStillActiveCheck.Stop();
|
||||
waitLeave.Stop();
|
||||
IconReader.Dispose();
|
||||
MainMenu?.Close();
|
||||
|
||||
foreach (FileSystemWatcher watcher in watchers)
|
||||
|
@ -634,10 +633,7 @@ namespace SystemTrayMenu.Business
|
|||
|
||||
if (!AsEnumerable.Any(m => m.Visibility == Visibility.Visible))
|
||||
{
|
||||
if (IconReader.ClearIfCacheTooBig())
|
||||
{
|
||||
GC.Collect();
|
||||
}
|
||||
IconReader.ClearCacheWhenLimitReached();
|
||||
|
||||
openCloseState = OpenCloseState.Default;
|
||||
}
|
||||
|
@ -1088,7 +1084,7 @@ namespace SystemTrayMenu.Business
|
|||
}
|
||||
}
|
||||
|
||||
RowData rowDataRenamed = new(isFolder, rowData.IsAdditionalItem, false, 0, path);
|
||||
RowData rowDataRenamed = new(isFolder, rowData.IsAdditionalItem, 0, path);
|
||||
FolderOptions.ReadHiddenAttributes(rowDataRenamed.Path, out bool hasHiddenFlag, out bool isDirectoryToHide);
|
||||
if (isDirectoryToHide)
|
||||
{
|
||||
|
@ -1160,7 +1156,7 @@ namespace SystemTrayMenu.Business
|
|||
FileAttributes attr = File.GetAttributes(e.FullPath);
|
||||
bool isFolder = (attr & FileAttributes.Directory) == FileAttributes.Directory;
|
||||
bool isAddionalItem = Path.GetDirectoryName(e.FullPath) != Config.Path;
|
||||
RowData rowData = new(isFolder, isAddionalItem, false, 0, e.FullPath);
|
||||
RowData rowData = new(isFolder, isAddionalItem, 0, e.FullPath);
|
||||
FolderOptions.ReadHiddenAttributes(rowData.Path, out bool hasHiddenFlag, out bool isDirectoryToHide);
|
||||
if (isDirectoryToHide)
|
||||
{
|
||||
|
|
|
@ -24,14 +24,12 @@ namespace SystemTrayMenu.DataClasses
|
|||
/// </summary>
|
||||
/// <param name="isFolder">Flag if file or folder.</param>
|
||||
/// <param name="isAdditionalItem">Flag if additional item, from other folder than root folder.</param>
|
||||
/// <param name="isNetworkRoot">Flag if resolved from network root folder.</param>
|
||||
/// <param name="level">The number of the menu level.</param>
|
||||
/// <param name="path">Path to item.</param>
|
||||
internal RowData(bool isFolder, bool isAdditionalItem, bool isNetworkRoot, int level, string path)
|
||||
internal RowData(bool isFolder, bool isAdditionalItem, int level, string path)
|
||||
{
|
||||
IsFolder = isFolder;
|
||||
IsAdditionalItem = isAdditionalItem;
|
||||
IsNetworkRoot = isNetworkRoot;
|
||||
Level = level;
|
||||
|
||||
try
|
||||
|
@ -81,8 +79,6 @@ namespace SystemTrayMenu.DataClasses
|
|||
{
|
||||
ContainsMenu |= IsLinkToFolder;
|
||||
}
|
||||
|
||||
IsMainMenu = Level == 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -100,8 +96,6 @@ namespace SystemTrayMenu.DataClasses
|
|||
|
||||
internal bool IsAdditionalItem { get; }
|
||||
|
||||
internal bool IsNetworkRoot { get; }
|
||||
|
||||
internal int Level { get; set; }
|
||||
|
||||
internal string? FileExtension { get; }
|
||||
|
@ -118,8 +112,6 @@ namespace SystemTrayMenu.DataClasses
|
|||
|
||||
internal bool ContainsMenu { get; }
|
||||
|
||||
internal bool IsMainMenu { get; }
|
||||
|
||||
internal Menu? SubMenu { get; set; }
|
||||
|
||||
internal bool IsMenuOpen { get; set; }
|
||||
|
@ -140,12 +132,12 @@ namespace SystemTrayMenu.DataClasses
|
|||
{
|
||||
if (IsFolder || IsLinkToFolder)
|
||||
{
|
||||
Icon = GetFolderIconWithCache(Path, ShowOverlay, updateIconInBackground, IsMainMenu, out bool loading);
|
||||
Icon = GetFolderIconWithCache(Path, ShowOverlay, updateIconInBackground, Level == 0, out bool loading);
|
||||
IconLoading = loading;
|
||||
}
|
||||
else
|
||||
{
|
||||
Icon = GetFileIconWithCache(Path, ResolvedPath, ShowOverlay, updateIconInBackground, IsMainMenu, out bool loading);
|
||||
Icon = GetFileIconWithCache(Path, ResolvedPath, ShowOverlay, updateIconInBackground, Level == 0, out bool loading);
|
||||
IconLoading = loading;
|
||||
}
|
||||
|
||||
|
@ -168,16 +160,15 @@ namespace SystemTrayMenu.DataClasses
|
|||
{
|
||||
IsClicking = true;
|
||||
}
|
||||
|
||||
if (e != null &&
|
||||
e.RightButton == MouseButtonState.Pressed &&
|
||||
FileInfo != null &&
|
||||
Path != null &&
|
||||
dgv != null &&
|
||||
dgv.Items.Count > RowIndex &&
|
||||
else if (e.RightButton == MouseButtonState.Pressed &&
|
||||
FileInfo != null && Path != null &&
|
||||
dgv != null && dgv.Items.Count > RowIndex &&
|
||||
(DateTime.Now - contextMenuClosed).TotalMilliseconds > 200)
|
||||
{
|
||||
IsContextMenuOpen = true;
|
||||
CreateAndShowShellContextMenu();
|
||||
void CreateAndShowShellContextMenu()
|
||||
{
|
||||
ShellContextMenu ctxMnu = new();
|
||||
Window window = dgv.GetParentWindow();
|
||||
var position = Mouse.GetPosition(window);
|
||||
|
@ -187,20 +178,16 @@ namespace SystemTrayMenu.DataClasses
|
|||
DirectoryInfo[] dir = new DirectoryInfo[1];
|
||||
dir[0] = new DirectoryInfo(Path);
|
||||
ctxMnu.ShowContextMenu(dir, position);
|
||||
TriggerFileWatcherChangeWorkaround();
|
||||
}
|
||||
else
|
||||
{
|
||||
FileInfo[] arrFI = new FileInfo[1];
|
||||
arrFI[0] = FileInfo;
|
||||
ctxMnu.ShowContextMenu(arrFI, position);
|
||||
}
|
||||
}
|
||||
|
||||
TriggerFileWatcherChangeWorkaround();
|
||||
}
|
||||
|
||||
IsContextMenuOpen = false;
|
||||
contextMenuClosed = DateTime.Now;
|
||||
}
|
||||
|
||||
void TriggerFileWatcherChangeWorkaround()
|
||||
{
|
||||
try
|
||||
|
@ -215,6 +202,10 @@ namespace SystemTrayMenu.DataClasses
|
|||
Log.Warn($"{nameof(TriggerFileWatcherChangeWorkaround)} '{Path}'", ex);
|
||||
}
|
||||
}
|
||||
|
||||
IsContextMenuOpen = false;
|
||||
contextMenuClosed = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
internal void OpenItem(out bool doCloseAfterOpen, int clickCount = -1)
|
||||
|
|
|
@ -173,7 +173,7 @@ namespace SystemTrayMenu.Helpers
|
|||
if (indexOfFirstSpace > 0)
|
||||
{
|
||||
string directory = Path.Combine(path, line[..indexOfFirstSpace]);
|
||||
menuData.RowDatas.Add(new RowData(true, false, true, menuData.Level, directory));
|
||||
menuData.RowDatas.Add(new RowData(true, false, menuData.Level, directory));
|
||||
resolvedSomething = true;
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ namespace SystemTrayMenu.Helpers
|
|||
return;
|
||||
}
|
||||
|
||||
menuData.RowDatas.Add(new RowData(true, false, false, menuData.Level, directory));
|
||||
menuData.RowDatas.Add(new RowData(true, false, menuData.Level, directory));
|
||||
}
|
||||
|
||||
foreach (string file in DirectoryBySearchPattern.GetFiles(path, Config.SearchPattern))
|
||||
|
@ -211,7 +211,7 @@ namespace SystemTrayMenu.Helpers
|
|||
return;
|
||||
}
|
||||
|
||||
menuData.RowDatas.Add(new RowData(false, false, false, menuData.Level, file));
|
||||
menuData.RowDatas.Add(new RowData(false, false, menuData.Level, file));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,14 +225,14 @@ namespace SystemTrayMenu.Helpers
|
|||
{
|
||||
foreach (string file in DirectoryBySearchPattern.GetFiles(path, Config.SearchPattern))
|
||||
{
|
||||
menuData.RowDatas.Add(new RowData(false, true, false, menuData.Level, file));
|
||||
menuData.RowDatas.Add(new RowData(false, true, menuData.Level, file));
|
||||
}
|
||||
|
||||
foreach (string directory in Directory.GetDirectories(path))
|
||||
{
|
||||
if (!onlyFiles)
|
||||
{
|
||||
menuData.RowDatas.Add(new RowData(true, true, false, menuData.Level, directory));
|
||||
menuData.RowDatas.Add(new RowData(true, true, menuData.Level, directory));
|
||||
}
|
||||
|
||||
if (recursiv)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
namespace SystemTrayMenu.Utilities
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
@ -735,7 +736,7 @@ namespace SystemTrayMenu.Utilities
|
|||
|
||||
try
|
||||
{
|
||||
if (arrPIDLs == null || oParentFolder == null || oContextMenu == null)
|
||||
if (arrPIDLs == null || oParentFolder == null)
|
||||
{
|
||||
ReleaseAll();
|
||||
return;
|
||||
|
@ -972,6 +973,7 @@ namespace SystemTrayMenu.Utilities
|
|||
/// <param name="oParentFolder">Parent folder.</param>
|
||||
/// <param name="arrPIDLs">PIDLs.</param>
|
||||
/// <returns>true if it got the interfaces, otherwise false.</returns>
|
||||
[MemberNotNullWhen(true, nameof(oContextMenu))]
|
||||
private bool GetContextMenuInterfaces(IShellFolder oParentFolder, IntPtr[] arrPIDLs, out IntPtr ctxMenuPtr)
|
||||
{
|
||||
int nResult = oParentFolder.GetUIObjectOf(
|
||||
|
|
|
@ -20,8 +20,8 @@ namespace SystemTrayMenu.Utilities
|
|||
/// </summary>
|
||||
public static class IconReader
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, Icon?> DictIconCacheMainMenu = new();
|
||||
private static readonly ConcurrentDictionary<string, Icon?> DictIconCacheSubMenus = new();
|
||||
private static readonly ConcurrentDictionary<string, Icon?> IconDictPersistent = new();
|
||||
private static readonly ConcurrentDictionary<string, Icon?> IconDictCache = new();
|
||||
|
||||
public enum IconSize
|
||||
{
|
||||
|
@ -29,47 +29,26 @@ namespace SystemTrayMenu.Utilities
|
|||
Small = 1, // 16x16 pixels
|
||||
}
|
||||
|
||||
public enum FolderType
|
||||
{
|
||||
Open = 0,
|
||||
Closed = 1,
|
||||
}
|
||||
|
||||
// see https://github.com/Hofknecht/SystemTrayMenu/issues/209.
|
||||
public static bool IsPreloading { get; set; } = true;
|
||||
|
||||
public static void Dispose(bool includingMainMenu = true)
|
||||
public static void ClearCacheWhenLimitReached()
|
||||
{
|
||||
if (includingMainMenu)
|
||||
if (IconDictCache.Count > Properties.Settings.Default.ClearCacheIfMoreThanThisNumberOfItems)
|
||||
{
|
||||
foreach (Icon? icon in DictIconCacheMainMenu.Values)
|
||||
foreach (Icon? icon in IconDictCache.Values)
|
||||
{
|
||||
icon?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Icon? icon in DictIconCacheSubMenus.Values)
|
||||
{
|
||||
icon?.Dispose();
|
||||
IconDictCache.Clear();
|
||||
GC.Collect();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ClearIfCacheTooBig()
|
||||
{
|
||||
bool cleared = false;
|
||||
if (DictIconCacheSubMenus.Count > Properties.Settings.Default.ClearCacheIfMoreThanThisNumberOfItems)
|
||||
{
|
||||
Dispose(false);
|
||||
DictIconCacheSubMenus.Clear();
|
||||
cleared = true;
|
||||
}
|
||||
|
||||
return cleared;
|
||||
}
|
||||
|
||||
public static void RemoveIconFromCache(string path)
|
||||
{
|
||||
if (DictIconCacheMainMenu.Remove(path, out Icon? iconToRemove))
|
||||
if (IconDictPersistent.Remove(path, out Icon? iconToRemove))
|
||||
{
|
||||
iconToRemove?.Dispose();
|
||||
}
|
||||
|
@ -80,7 +59,7 @@ namespace SystemTrayMenu.Utilities
|
|||
string? resolvedPath,
|
||||
bool linkOverlay,
|
||||
bool updateIconInBackground,
|
||||
bool isMainMenu,
|
||||
bool checkPersistentFirst,
|
||||
out bool loading,
|
||||
string keyPath = "")
|
||||
{
|
||||
|
@ -109,8 +88,8 @@ namespace SystemTrayMenu.Utilities
|
|||
key = extension + linkOverlay;
|
||||
}
|
||||
|
||||
if (!DictIconCache(isMainMenu).TryGetValue(key, out icon) &&
|
||||
!DictIconCache(!isMainMenu).TryGetValue(key, out icon))
|
||||
if (!DictIconCache(checkPersistentFirst).TryGetValue(key, out icon) &&
|
||||
!DictIconCache(!checkPersistentFirst).TryGetValue(key, out icon))
|
||||
{
|
||||
icon = Resources.StaticResources.LoadingIcon;
|
||||
loading = true;
|
||||
|
@ -119,7 +98,7 @@ namespace SystemTrayMenu.Utilities
|
|||
new Thread(UpdateIconInBackground).Start();
|
||||
void UpdateIconInBackground()
|
||||
{
|
||||
DictIconCache(isMainMenu).GetOrAdd(key, GetIconSTA(path, resolvedPath, linkOverlay, size, false));
|
||||
DictIconCache(checkPersistentFirst).GetOrAdd(key, GetIconSTA(path, resolvedPath, linkOverlay, size, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +111,7 @@ namespace SystemTrayMenu.Utilities
|
|||
string? path,
|
||||
bool linkOverlay,
|
||||
bool updateIconInBackground,
|
||||
bool isMainMenu,
|
||||
bool checkPersistentFirst,
|
||||
out bool loading)
|
||||
{
|
||||
loading = false;
|
||||
|
@ -150,8 +129,8 @@ namespace SystemTrayMenu.Utilities
|
|||
}
|
||||
|
||||
string key = path;
|
||||
if (!DictIconCache(isMainMenu).TryGetValue(key, out icon) &&
|
||||
!DictIconCache(!isMainMenu).TryGetValue(key, out icon))
|
||||
if (!DictIconCache(checkPersistentFirst).TryGetValue(key, out icon) &&
|
||||
!DictIconCache(!checkPersistentFirst).TryGetValue(key, out icon))
|
||||
{
|
||||
icon = Resources.StaticResources.LoadingIcon;
|
||||
loading = true;
|
||||
|
@ -160,14 +139,14 @@ namespace SystemTrayMenu.Utilities
|
|||
{
|
||||
if (IsPreloading)
|
||||
{
|
||||
DictIconCache(isMainMenu).GetOrAdd(key, GetFolder);
|
||||
DictIconCache(checkPersistentFirst).GetOrAdd(key, GetFolder);
|
||||
}
|
||||
else
|
||||
{
|
||||
new Thread(UpdateIconInBackground).Start();
|
||||
void UpdateIconInBackground()
|
||||
{
|
||||
DictIconCache(isMainMenu).GetOrAdd(key, GetFolder);
|
||||
DictIconCache(checkPersistentFirst).GetOrAdd(key, GetFolder);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,17 +202,8 @@ namespace SystemTrayMenu.Utilities
|
|||
return icon;
|
||||
}
|
||||
|
||||
private static ConcurrentDictionary<string, Icon?> DictIconCache(bool isMainMenu)
|
||||
{
|
||||
if (isMainMenu)
|
||||
{
|
||||
return DictIconCacheMainMenu;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DictIconCacheSubMenus;
|
||||
}
|
||||
}
|
||||
private static ConcurrentDictionary<string, Icon?> DictIconCache(bool checkPersistentFirst)
|
||||
=> checkPersistentFirst ? IconDictPersistent : IconDictCache;
|
||||
|
||||
private static bool IsExtensionWithSameIcon(string fileExtension)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue